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 fcd9dd0534043..2caf20ffe8b3a 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 @@ -35,12 +35,14 @@ import org.elasticsearch.rest.RestStatus; import org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase; 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.List; import java.util.Map; +import java.util.stream.Collectors; import static org.elasticsearch.snapshots.SnapshotsService.NO_FEATURE_STATES_VALUE; import static org.elasticsearch.tasks.TaskResultsService.TASKS_FEATURE_NAME; @@ -209,14 +211,17 @@ public void testGetSnapshots() throws IOException { GetSnapshotsResponse response = execute(request, highLevelClient().snapshot()::get, highLevelClient().snapshot()::getAsync); 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)); + assertEquals( + Sets.newSet(repository1, repository2), + response.getSnapshots().stream().map(SnapshotInfo::repository).collect(Collectors.toSet()) + ); - 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)); + assertThat(response.getSnapshots(), hasSize(2)); + assertThat(response.getSnapshots().get(0).snapshotId().getName(), equalTo(snapshot1)); + assertThat(response.getSnapshots().get(0).repository(), equalTo(repository1)); + assertThat(response.getSnapshots().get(1).snapshotId().getName(), equalTo(snapshot2)); + assertThat(response.getSnapshots().get(1).userMetadata(), equalTo(originalMetadata)); + assertThat(response.getSnapshots().get(1).repository(), equalTo(repository2)); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java index 277db4dac1b5d..ae7bd2a09eedb 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ILMDocumentationIT.java @@ -1044,7 +1044,7 @@ private void assertSnapshotExists(final RestHighLevelClient client, final String GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest(new String[]{repo}, new String[]{snapshotName}); try { final GetSnapshotsResponse snaps = client.snapshot().get(getSnapshotsRequest, RequestOptions.DEFAULT); - Optional info = snaps.getSnapshots(repo).stream().findFirst(); + Optional info = snaps.getSnapshots().stream().findFirst(); if (info.isPresent()) { info.ifPresent(si -> { assertThat(si.snapshotId().getName(), equalTo(snapshotName)); 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 d09db5fda0b4e..22fd3a7c0095a 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 @@ -617,7 +617,7 @@ public void testSnapshotGetSnapshots() throws IOException { // end::get-snapshots-execute // tag::get-snapshots-response - List snapshotsInfos = response.getSnapshots(repositoryName); + List snapshotsInfos = response.getSnapshots(); SnapshotInfo snapshotInfo = snapshotsInfos.get(0); RestStatus restStatus = snapshotInfo.status(); // <1> SnapshotId snapshotId = snapshotInfo.snapshotId(); // <2> diff --git a/docs/reference/migration/migrate_8_0/snapshots.asciidoc b/docs/reference/migration/migrate_8_0/snapshots.asciidoc index c4d91aaaafc3b..d421dbb4c3918 100644 --- a/docs/reference/migration/migrate_8_0/snapshots.asciidoc +++ b/docs/reference/migration/migrate_8_0/snapshots.asciidoc @@ -9,64 +9,6 @@ // end::notable-breaking-changes[] -.The get snapshot API's response format has changed. -[%collapsible] -==== -*Details* + -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. - -For example, requesting one snapshot from particular repository - -[source,console] ------------------------------------ -GET _snapshot/repo1/snap1 ------------------------------------ -// TEST[skip:no repo and snapshots are created] - -produces the following response - -[source,console-result] ------------------------------------ -{ - "responses": [ - { - "repository": "repo1", - "snapshots": [ - { - "snapshot": "snap1", - "uuid": "cEzdqUKxQ5G6MyrJAcYwmA", - "version_id": 8000099, - "version": "8.0.0", - "indices": [], - "include_global_state": true, - "state": "SUCCESS", - "start_time": "2019-05-10T17:01:57.868Z", - "start_time_in_millis": 1557507717868, - "end_time": "2019-05-10T17:01:57.909Z", - "end_time_in_millis": 1557507717909, - "duration_in_millis": 41, - "failures": [], - "shards": { - "total": 0, - "failed": 0, - "successful": 0 - } - } - ] - } - ] -} ------------------------------------ -// TESTRESPONSE[skip:no repo and snapshots are created] - -See <> for more information. - -*Impact* + -Update your workflow and applications to use the get snapshot API's new response -format. -==== - .The `repositories.fs.compress` node-level setting has been removed. [%collapsible] ==== diff --git a/docs/reference/snapshot-restore/apis/create-snapshot-api.asciidoc b/docs/reference/snapshot-restore/apis/create-snapshot-api.asciidoc index 9f13c4b25549f..3543c2c5bd643 100644 --- a/docs/reference/snapshot-restore/apis/create-snapshot-api.asciidoc +++ b/docs/reference/snapshot-restore/apis/create-snapshot-api.asciidoc @@ -176,6 +176,7 @@ The API returns the following response: "snapshot": { "snapshot": "snapshot_2", "uuid": "vdRctLCxSketdKb54xw67g", + "repository": "my_repository", "version_id": , "version": , "indices": [], diff --git a/docs/reference/snapshot-restore/apis/get-snapshot-api.asciidoc b/docs/reference/snapshot-restore/apis/get-snapshot-api.asciidoc index b19e922137815..b3bdc6964abeb 100644 --- a/docs/reference/snapshot-restore/apis/get-snapshot-api.asciidoc +++ b/docs/reference/snapshot-restore/apis/get-snapshot-api.asciidoc @@ -284,42 +284,38 @@ The API returns the following response: [source,console-result] ---- { - "responses": [ + "snapshots": [ { + "snapshot": "snapshot_2", + "uuid": "vdRctLCxSketdKb54xw67g", "repository": "my_repository", - "snapshots": [ - { - "snapshot": "snapshot_2", - "uuid": "vdRctLCxSketdKb54xw67g", - "version_id": , - "version": , - "indices": [], - "data_streams": [], - "feature_states": [], - "include_global_state": true, - "state": "SUCCESS", - "start_time": "2020-07-06T21:55:18.129Z", - "start_time_in_millis": 1593093628850, - "end_time": "2020-07-06T21:55:18.129Z", - "end_time_in_millis": 1593094752018, - "duration_in_millis": 0, - "failures": [], - "shards": { - "total": 0, - "failed": 0, - "successful": 0 - } - } - ] + "version_id": , + "version": , + "indices": [], + "data_streams": [], + "feature_states": [], + "include_global_state": true, + "state": "SUCCESS", + "start_time": "2020-07-06T21:55:18.129Z", + "start_time_in_millis": 1593093628850, + "end_time": "2020-07-06T21:55:18.129Z", + "end_time_in_millis": 1593094752018, + "duration_in_millis": 0, + "failures": [], + "shards": { + "total": 0, + "failed": 0, + "successful": 0 + } } ] } ---- -// TESTRESPONSE[s/"uuid": "vdRctLCxSketdKb54xw67g"/"uuid": $body.responses.0.snapshots.0.uuid/] -// TESTRESPONSE[s/"version_id": /"version_id": $body.responses.0.snapshots.0.version_id/] -// TESTRESPONSE[s/"version": /"version": $body.responses.0.snapshots.0.version/] -// TESTRESPONSE[s/"start_time": "2020-07-06T21:55:18.129Z"/"start_time": $body.responses.0.snapshots.0.start_time/] -// TESTRESPONSE[s/"start_time_in_millis": 1593093628850/"start_time_in_millis": $body.responses.0.snapshots.0.start_time_in_millis/] -// TESTRESPONSE[s/"end_time": "2020-07-06T21:55:18.129Z"/"end_time": $body.responses.0.snapshots.0.end_time/] -// TESTRESPONSE[s/"end_time_in_millis": 1593094752018/"end_time_in_millis": $body.responses.0.snapshots.0.end_time_in_millis/] -// TESTRESPONSE[s/"duration_in_millis": 0/"duration_in_millis": $body.responses.0.snapshots.0.duration_in_millis/] +// TESTRESPONSE[s/"uuid": "vdRctLCxSketdKb54xw67g"/"uuid": $body.snapshots.0.uuid/] +// TESTRESPONSE[s/"version_id": /"version_id": $body.snapshots.0.version_id/] +// TESTRESPONSE[s/"version": /"version": $body.snapshots.0.version/] +// TESTRESPONSE[s/"start_time": "2020-07-06T21:55:18.129Z"/"start_time": $body.snapshots.0.start_time/] +// TESTRESPONSE[s/"start_time_in_millis": 1593093628850/"start_time_in_millis": $body.snapshots.0.start_time_in_millis/] +// TESTRESPONSE[s/"end_time": "2020-07-06T21:55:18.129Z"/"end_time": $body.snapshots.0.end_time/] +// TESTRESPONSE[s/"end_time_in_millis": 1593094752018/"end_time_in_millis": $body.snapshots.0.end_time_in_millis/] +// TESTRESPONSE[s/"duration_in_millis": 0/"duration_in_millis": $body.snapshots.0.duration_in_millis/] diff --git a/docs/reference/snapshot-restore/monitor-snapshot-restore.asciidoc b/docs/reference/snapshot-restore/monitor-snapshot-restore.asciidoc index 54ebdd56bd633..3e47082b6115c 100644 --- a/docs/reference/snapshot-restore/monitor-snapshot-restore.asciidoc +++ b/docs/reference/snapshot-restore/monitor-snapshot-restore.asciidoc @@ -31,6 +31,8 @@ PUT /_snapshot/my_fs_backup } PUT /_snapshot/my_backup/snapshot_1?wait_for_completion=true + +PUT /_snapshot/my_backup/some_other_snapshot?wait_for_completion=true ----------------------------------- // TESTSETUP diff --git a/modules/repository-url/src/internalClusterTest/java/org/elasticsearch/repositories/url/URLSnapshotRestoreIT.java b/modules/repository-url/src/internalClusterTest/java/org/elasticsearch/repositories/url/URLSnapshotRestoreIT.java index f39c4ab1ee274..cc130ca913b42 100644 --- a/modules/repository-url/src/internalClusterTest/java/org/elasticsearch/repositories/url/URLSnapshotRestoreIT.java +++ b/modules/repository-url/src/internalClusterTest/java/org/elasticsearch/repositories/url/URLSnapshotRestoreIT.java @@ -28,7 +28,6 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.notNullValue; @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST) public class URLSnapshotRestoreIT extends ESIntegTestCase { @@ -77,7 +76,7 @@ public void testUrlRepository() throws Exception { .prepareGetSnapshots("test-repo") .setSnapshots("test-snap") .get() - .getSnapshots("test-repo") + .getSnapshots() .get(0) .state(); assertThat(state, equalTo(SnapshotState.SUCCESS)); @@ -105,8 +104,7 @@ public void testUrlRepository() throws Exception { logger.info("--> list available shapshots"); GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("url-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots("url-repo"), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); logger.info("--> delete snapshot"); AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get(); @@ -114,7 +112,6 @@ 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("url-repo"), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(0)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(0)); } } diff --git a/modules/repository-url/src/yamlRestTest/resources/rest-api-spec/test/repository_url/10_basic.yml b/modules/repository-url/src/yamlRestTest/resources/rest-api-spec/test/repository_url/10_basic.yml index fb49f3da24af5..b932f0d53caad 100644 --- a/modules/repository-url/src/yamlRestTest/resources/rest-api-spec/test/repository_url/10_basic.yml +++ b/modules/repository-url/src/yamlRestTest/resources/rest-api-spec/test/repository_url/10_basic.yml @@ -112,9 +112,6 @@ teardown: --- "Restore with repository-url using http://": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Ensure that the URL repository is registered - do: @@ -129,9 +126,9 @@ teardown: repository: repository-url snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -177,9 +174,6 @@ teardown: --- "Restore with repository-url using file://": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Ensure that the URL repository is registered - do: @@ -194,9 +188,9 @@ teardown: repository: repository-file snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -242,18 +236,13 @@ teardown: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/src/yamlRestTest/resources/rest-api-spec/test/repository_azure/20_repository.yml b/plugins/repository-azure/src/yamlRestTest/resources/rest-api-spec/test/repository_azure/20_repository.yml index 5ee9446e8501a..beaa95b732d52 100644 --- a/plugins/repository-azure/src/yamlRestTest/resources/rest-api-spec/test/repository_azure/20_repository.yml +++ b/plugins/repository-azure/src/yamlRestTest/resources/rest-api-spec/test/repository_azure/20_repository.yml @@ -28,9 +28,6 @@ setup: --- "Snapshot/Restore with repository-azure": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -130,9 +127,9 @@ setup: repository: repository snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state: SUCCESS } - - match: { responses.0.snapshots.1.state: SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -212,18 +209,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/src/yamlRestTest/resources/rest-api-spec/test/repository_gcs/20_repository.yml b/plugins/repository-gcs/src/yamlRestTest/resources/rest-api-spec/test/repository_gcs/20_repository.yml index 81e50a77d651a..abc7d03c75474 100644 --- a/plugins/repository-gcs/src/yamlRestTest/resources/rest-api-spec/test/repository_gcs/20_repository.yml +++ b/plugins/repository-gcs/src/yamlRestTest/resources/rest-api-spec/test/repository_gcs/20_repository.yml @@ -28,9 +28,6 @@ setup: --- "Snapshot/Restore with repository-gcs": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -130,9 +127,9 @@ setup: repository: repository snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -209,18 +206,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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 01f2f524294ed..60851c270e3fa 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 @@ -83,7 +83,7 @@ public void testSimpleWorkflow() { .prepareGetSnapshots("test-repo") .setSnapshots("test-snap") .get() - .getSnapshots("test-repo") + .getSnapshots() .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 6ed93e07160b2..f38f4783b195b 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: { responses.0.snapshots: 1 } - - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } + - length: { snapshots: 1 } + - match: { snapshots.0.snapshot : test_snapshot_get } # List snapshot info - do: @@ -55,8 +55,8 @@ repository: test_snapshot_get_repository snapshot: "*" - - length: { responses.0.snapshots: 1 } - - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } + - length: { snapshots: 1 } + - match: { 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 dda910ae36c26..c2a37964e70a7 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: { responses.0.snapshots: 1 } + - length: { snapshots: 1 } # Remove our repository - do: diff --git a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_get.yml b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_get.yml index 2c4fcc338ab07..20d988884113f 100644 --- a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_get.yml +++ b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_get.yml @@ -48,8 +48,8 @@ repository: test_snapshot_get_repository snapshot: test_snapshot_get - - length: { responses.0.snapshots: 1 } - - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } + - length: { snapshots: 1 } + - match: { snapshots.0.snapshot : test_snapshot_get } # List snapshot info - do: @@ -57,8 +57,8 @@ repository: test_snapshot_get_repository snapshot: "*" - - length: { responses.0.snapshots: 1 } - - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } + - length: { snapshots: 1 } + - match: { snapshots.0.snapshot : test_snapshot_get } # Remove our snapshot - do: diff --git a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_readonly.yml b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_readonly.yml index c31749072a17b..8c4c0347a156a 100644 --- a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_readonly.yml +++ b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/secure_hdfs_repository/30_snapshot_readonly.yml @@ -23,7 +23,7 @@ repository: test_snapshot_repository_ro snapshot: "_all" - - length: { responses.0.snapshots: 1 } + - length: { snapshots: 1 } # Remove our repository - do: diff --git a/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml index f651cad52e8f2..386b4dcc15b42 100644 --- a/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml +++ b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml @@ -108,9 +108,6 @@ setup: --- "Snapshot and Restore with repository-s3 using permanent credentials": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -215,9 +212,9 @@ setup: repository: repository_permanent snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -322,18 +319,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/yamlRestTest/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml index caca1b959511e..d26a07eec85dc 100644 --- a/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml +++ b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml @@ -19,9 +19,6 @@ setup: --- "Snapshot and Restore with repository-s3 using temporary credentials": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -126,9 +123,9 @@ setup: repository: repository_temporary snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -233,18 +230,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/yamlRestTest/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml index 3573af618febe..6d3b174b99863 100644 --- a/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml +++ b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml @@ -19,9 +19,6 @@ setup: --- "Snapshot and Restore with repository-s3 using ec2 credentials": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -126,9 +123,9 @@ setup: repository: repository_ec2 snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -233,18 +230,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/yamlRestTest/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml index 88c315af4b536..79d1e3d9c3bbe 100644 --- a/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml +++ b/plugins/repository-s3/src/yamlRestTest/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml @@ -19,9 +19,6 @@ setup: --- "Snapshot and Restore with repository-s3 using ecs credentials": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -126,9 +123,9 @@ setup: repository: repository_ecs snapshot: snapshot-one,snapshot-two - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.state : SUCCESS } - - match: { responses.0.snapshots.1.state : SUCCESS } + - is_true: snapshots + - match: { snapshots.0.state : SUCCESS } + - match: { snapshots.1.state : SUCCESS } # Delete the index - do: @@ -233,18 +230,13 @@ setup: --- "Get a non existing snapshot": - - skip: - version: " - 7.99.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/smoke-test-http/src/test/java/org/elasticsearch/http/snapshots/RestGetSnapshotsIT.java b/qa/smoke-test-http/src/test/java/org/elasticsearch/http/snapshots/RestGetSnapshotsIT.java index 72514beed8504..3b4ae8a6707e0 100644 --- a/qa/smoke-test-http/src/test/java/org/elasticsearch/http/snapshots/RestGetSnapshotsIT.java +++ b/qa/smoke-test-http/src/test/java/org/elasticsearch/http/snapshots/RestGetSnapshotsIT.java @@ -65,7 +65,7 @@ public void testSortOrder() throws Exception { private void doTestSortOrder(String repoName, Collection allSnapshotNames, SortOrder order) throws IOException { final List defaultSorting = - clusterAdmin().prepareGetSnapshots(repoName).setOrder(order).get().getSnapshots(repoName); + clusterAdmin().prepareGetSnapshots(repoName).setOrder(order).get().getSnapshots(); assertSnapshotListSorted(defaultSorting, null, order); assertSnapshotListSorted( allSnapshotsSorted(allSnapshotNames, repoName, GetSnapshotsRequest.SortBy.NAME, order), @@ -196,7 +196,7 @@ private static List allSnapshotsSorted(Collection allSnaps request.addParameter("order", order.toString()); } final Response response = getRestClient().performRequest(request); - final List snapshotInfos = readSnapshotInfos(repoName, response); + final List snapshotInfos = readSnapshotInfos(response); assertEquals(snapshotInfos.size(), allSnapshotNames.size()); for (SnapshotInfo snapshotInfo : snapshotInfos) { assertThat(snapshotInfo.snapshotId().getName(), is(in(allSnapshotNames))); @@ -219,15 +219,15 @@ private static List sortedWithLimit(String repoName, } request.addParameter("size", String.valueOf(size)); final Response response = getRestClient().performRequest(request); - return readSnapshotInfos(repoName, response); + return readSnapshotInfos(response); } - private static List readSnapshotInfos(String repoName, Response response) throws IOException { + private static List readSnapshotInfos(Response response) throws IOException { final List snapshotInfos; try (InputStream input = response.getEntity().getContent(); XContentParser parser = JsonXContent.jsonXContent.createParser( NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, input)) { - snapshotInfos = GetSnapshotsResponse.fromXContent(parser).getSnapshots(repoName); + snapshotInfos = GetSnapshotsResponse.fromXContent(parser).getSnapshots(); } return snapshotInfos; } @@ -249,6 +249,6 @@ private static List sortedWithLimit(String repoName, request.addParameter("order", order.toString()); } final Response response = getRestClient().performRequest(request); - return readSnapshotInfos(repoName, response); + return readSnapshotInfos(response); } } diff --git a/rest-api-spec/build.gradle b/rest-api-spec/build.gradle index 7e90608c2ef70..722ef7f0f4fcc 100644 --- a/rest-api-spec/build.gradle +++ b/rest-api-spec/build.gradle @@ -112,13 +112,6 @@ tasks.named("yamlRestCompatTest").configure { 'search/310_match_bool_prefix/multi_match multiple fields with cutoff_frequency throws exception', //cutoff_frequency 'search/340_type_query/type query', // type_query - probably should behave like match_all 'search_shards/10_basic/Search shards aliases with and without filters', - 'snapshot.get/10_basic/Get missing snapshot info succeeds when ignore_unavailable is true', - 'snapshot.get/10_basic/Get missing snapshot info throws an exception', - 'snapshot.get/10_basic/Get snapshot info', - 'snapshot.get/10_basic/Get snapshot info contains include_global_state', - 'snapshot.get/10_basic/Get snapshot info when verbose is false', - 'snapshot.get/10_basic/Get snapshot info with metadata', - 'snapshot.get/10_basic/Get snapshot info with index details', 'suggest/20_completion/Suggestions with source should work' ] + v7compatiblityNotSupportedTests()) .join(',') diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.get.json b/rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.get.json index fd338fe2511fc..01387918e5278 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.get.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.get.json @@ -42,6 +42,10 @@ "type":"boolean", "description":"Whether to include details of each index in the snapshot, if those details are available. Defaults to false." }, + "include_repository":{ + "type":"boolean", + "description":"Whether to include the repository name in the snapshot info. Defaults to true." + }, "verbose":{ "type":"boolean", "description":"Whether to show verbose snapshot info or only show the basic info found in the repository index blob" diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/snapshot.get/10_basic.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/snapshot.get/10_basic.yml index 109ac83e37f87..3e51247543978 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/snapshot.get/10_basic.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/snapshot.get/10_basic.yml @@ -11,9 +11,6 @@ setup: --- "Get snapshot info": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" - do: indices.create: @@ -34,8 +31,8 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot - - is_true: responses.0.snapshots - - is_true: responses.0.snapshots.0.failures + - is_true: snapshots + - is_true: snapshots.0.failures - do: snapshot.delete: @@ -44,23 +41,15 @@ setup: --- "Get missing snapshot info throws an exception": - - skip: - version: " - 7.99.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.99.99" - reason: "8.0 changes get snapshots response format" - do: snapshot.get: @@ -68,14 +57,10 @@ setup: snapshot: test_nonexistent_snapshot ignore_unavailable: true - - is_true: responses.0.snapshots + - is_true: snapshots --- "Get snapshot info when verbose is false": - - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" - - do: indices.create: index: test_index @@ -96,13 +81,13 @@ setup: snapshot: test_snapshot verbose: false - - 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 + - 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 - do: snapshot.delete: @@ -112,8 +97,8 @@ setup: --- "Get snapshot info contains include_global_state": - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" + version: " - 6.1.99" + reason: "include_global_state field has been added in the response in 6.2.0" - do: indices.create: @@ -136,10 +121,10 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_with_include_global_state - - 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 } + - 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 } - do: snapshot.delete: @@ -159,10 +144,10 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_without_include_global_state - - 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 } + - 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 } - do: snapshot.delete: @@ -172,8 +157,8 @@ setup: --- "Get snapshot info with metadata": - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" + version: " - 7.2.99" + reason: "Introduced with 7.3" - do: indices.create: @@ -196,12 +181,12 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_with_metadata - - 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 } - - is_false: responses.0.snapshots.0.index_details + - 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_false: snapshots.0.index_details - do: snapshot.delete: @@ -211,8 +196,8 @@ setup: --- "Get snapshot info with index details": - skip: - version: " - 7.99.99" - reason: "8.0 changes get snapshots response format" + version: " - 7.12.99" + reason: "Introduced in 7.13.0" - do: indices.create: @@ -235,15 +220,52 @@ setup: index_details: true human: true - - is_true: responses.0.snapshots - - match: { responses.0.snapshots.0.snapshot: test_snapshot_with_index_details } - - match: { responses.0.snapshots.0.state: SUCCESS } - - gt: { responses.0.snapshots.0.index_details.test_index.shard_count: 0 } - - gt: { responses.0.snapshots.0.index_details.test_index.size_in_bytes: 0 } - - gte: { responses.0.snapshots.0.index_details.test_index.max_segments_per_shard: 0 } - - is_true: responses.0.snapshots.0.index_details.test_index.size + - is_true: snapshots + - match: { snapshots.0.snapshot: test_snapshot_with_index_details } + - match: { snapshots.0.state: SUCCESS } + - gt: { snapshots.0.index_details.test_index.shard_count: 0 } + - gt: { snapshots.0.index_details.test_index.size_in_bytes: 0 } + - gte: { snapshots.0.index_details.test_index.max_segments_per_shard: 0 } + - is_true: snapshots.0.index_details.test_index.size - do: snapshot.delete: repository: test_repo_get_1 snapshot: test_snapshot_with_index_details + +--- +"Get snapshot info without repository names": + - skip: + version: " - 7.99.99" + reason: "8.0 changes get snapshots response format" + + - do: + indices.create: + index: test_index + body: + settings: + number_of_shards: 1 + number_of_replicas: 0 + + - do: + snapshot.create: + repository: test_repo_get_1 + snapshot: test_snapshot_no_repo_name + wait_for_completion: true + + - do: + snapshot.get: + repository: test_repo_get_1 + snapshot: test_snapshot_no_repo_name + include_repository: false + human: true + + - is_true: snapshots + - match: { snapshots.0.snapshot: test_snapshot_no_repo_name } + - match: { snapshots.0.state: SUCCESS } + - is_false: snapshots.0.repository + + - do: + snapshot.delete: + repository: test_repo_get_1 + snapshot: test_snapshot_no_repo_name diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 0fa3cf33b11f0..b69a95defbd5e 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -180,8 +180,8 @@ public void testGetSnapshotWithBlocks() { try { setClusterReadOnly(true); GetSnapshotsResponse response = client().admin().cluster().prepareGetSnapshots(REPOSITORY_NAME).execute().actionGet(); - assertThat(response.getSnapshots(REPOSITORY_NAME), hasSize(1)); - assertThat(response.getSnapshots(REPOSITORY_NAME).get(0).snapshotId().getName(), equalTo(SNAPSHOT_NAME)); + assertThat(response.getSnapshots(), hasSize(1)); + assertThat(response.getSnapshots().get(0).snapshotId().getName(), equalTo(SNAPSHOT_NAME)); } finally { setClusterReadOnly(false); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java index 980f99068c4d6..81444dbfd9544 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java @@ -254,7 +254,7 @@ public void testRestoreSnapshotOverLimit() { equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); List snapshotInfos = client.admin().cluster().prepareGetSnapshots("test-repo") - .setSnapshots("test-snap").get().getSnapshots("test-repo"); + .setSnapshots("test-snap").get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java b/server/src/internalClusterTest/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java index 283f825c6f68b..fabbb90eeada3 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java @@ -237,7 +237,7 @@ public void testMasterFailOverDuringShardSnapshots() throws Exception { private void assertSnapshotExists(String repository, String snapshot) { GetSnapshotsResponse snapshotsStatusResponse = dataNodeClient().admin().cluster().prepareGetSnapshots(repository) .setSnapshots(snapshot).get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(repository).get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); assertEquals(snapshotInfo.totalShards(), snapshotInfo.successfulShards()); assertEquals(0, snapshotInfo.failedShards()); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index 539f505063e79..bc0cc6e434211 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -641,7 +641,7 @@ public void testSnapshotRecovery() throws Exception { equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); assertThat(client().admin().cluster().prepareGetSnapshots(REPO_NAME).setSnapshots(SNAP_NAME).get() - .getSnapshots(REPO_NAME).get(0).state(), equalTo(SnapshotState.SUCCESS)); + .getSnapshots().get(0).state(), equalTo(SnapshotState.SUCCESS)); client().admin().indices().prepareClose(INDEX_NAME).execute().actionGet(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CloneSnapshotIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CloneSnapshotIT.java index d994220b1d462..02b66df66c8d1 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CloneSnapshotIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CloneSnapshotIT.java @@ -726,6 +726,7 @@ private static BlobStoreIndexShardSnapshots readShardGeneration( ActionRunnable.supply( f, () -> BlobStoreRepository.INDEX_SHARD_SNAPSHOTS_FORMAT.read( + repository.getMetadata().name(), repository.shardContainer(repositoryShardId.index(), repositoryShardId.shardId()), generation, NamedXContentRegistry.EMPTY diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/ConcurrentSnapshotsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/ConcurrentSnapshotsIT.java index 53c36fe19f323..e227142a4c4d3 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/ConcurrentSnapshotsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/ConcurrentSnapshotsIT.java @@ -343,7 +343,7 @@ public void testAbortOneOfMultipleSnapshots() throws Exception { logger.info("--> verify that the first snapshot is gone"); assertThat( - client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(repoName), + client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(), containsInAnyOrder(secondSnapshotInfo, thirdSnapshotInfo) ); } @@ -407,7 +407,7 @@ public void testCascadedAborts() throws Exception { assertAcked(allDeletedResponse.get()); logger.info("--> verify that all snapshots are gone"); - assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(repoName), empty()); + assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(), empty()); } public void testMasterFailOverWithQueuedDeletes() throws Exception { @@ -493,7 +493,7 @@ public void testMasterFailOverWithQueuedDeletes() throws Exception { logger.info("--> verify that all snapshots are gone and no more work is left in the cluster state"); assertBusy(() -> { - assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(repoName), empty()); + assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(), empty()); final ClusterState state = clusterService().state(); final SnapshotsInProgress snapshotsInProgress = state.custom(SnapshotsInProgress.TYPE); assertThat(snapshotsInProgress.entries(), empty()); @@ -557,7 +557,7 @@ public void testQueuedDeletesWithFailures() throws Exception { final SnapshotException snapshotException = expectThrows(SnapshotException.class, snapshotFuture::actionGet); assertThat(snapshotException.getMessage(), containsString(SnapshotsInProgress.ABORTED_FAILURE_TEXT)); - assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(repoName), empty()); + assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(), empty()); } public void testQueuedDeletesWithOverlap() throws Exception { @@ -584,7 +584,7 @@ public void testQueuedDeletesWithOverlap() throws Exception { final SnapshotException snapshotException = expectThrows(SnapshotException.class, snapshotFuture::actionGet); assertThat(snapshotException.getMessage(), containsString(SnapshotsInProgress.ABORTED_FAILURE_TEXT)); - assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(repoName), empty()); + assertThat(client().admin().cluster().prepareGetSnapshots(repoName).get().getSnapshots(), empty()); } public void testQueuedOperationsOnMasterRestart() throws Exception { @@ -1435,7 +1435,7 @@ private static List currentSnapshots(String repoName) { .prepareGetSnapshots(repoName) .setSnapshots(GetSnapshotsRequest.CURRENT_SNAPSHOT) .get() - .getSnapshots(repoName); + .getSnapshots(); } private ActionFuture startAndBlockOnDeleteSnapshot(String repoName, String snapshotName) throws Exception { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java index c3fa3a18906a6..4bc78736c2e59 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/CorruptedBlobStoreRepositoryIT.java @@ -132,7 +132,7 @@ public void testConcurrentlyChangeRepositoryContents() throws Exception { logger.info("--> make sure snapshot doesn't exist"); expectThrows( SnapshotMissingException.class, - () -> client.admin().cluster().prepareGetSnapshots(repoName).addSnapshots(snapshot).get().getSnapshots(repoName) + () -> client.admin().cluster().prepareGetSnapshots(repoName).addSnapshots(snapshot).get() ); } @@ -209,7 +209,7 @@ public void testFindDanglingLatestGeneration() throws Exception { logger.info("--> make sure snapshot doesn't exist"); expectThrows( SnapshotMissingException.class, - () -> client().admin().cluster().prepareGetSnapshots(repoName).addSnapshots(snapshot).get().getSnapshots(repoName) + () -> client().admin().cluster().prepareGetSnapshots(repoName).addSnapshots(snapshot).get() ); } @@ -490,7 +490,7 @@ public void testSnapshotWithCorruptedShardIndexFile() throws Exception { } logger.info("--> verifying snapshot state for [{}]", snapshot1); - List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); + List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo(snapshot1)); @@ -571,7 +571,7 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio expectThrows( SnapshotMissingException.class, - () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get().getSnapshots("test-repo") + () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get() ); for (String index : indices) { @@ -615,7 +615,7 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { logger.info("--> make sure snapshot doesn't exist"); expectThrows( SnapshotMissingException.class, - () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get().getSnapshots("test-repo") + () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get() ); } @@ -663,7 +663,7 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { logger.info("--> make sure snapshot doesn't exist"); expectThrows( SnapshotMissingException.class, - () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get().getSnapshots("test-repo") + () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get().getSnapshots() ); logger.info("--> make sure that we can create the snapshot again"); @@ -712,7 +712,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { } } - List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); + List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap")); @@ -722,10 +722,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); assertAcked(startDeleteSnapshot("test-repo", "test-snap").get()); - expectThrows( - SnapshotMissingException.class, - () -> clusterAdmin().prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo") - ); + expectThrows(SnapshotMissingException.class, () -> clusterAdmin().prepareGetSnapshots("test-repo").addSnapshots("test-snap").get()); assertRequestBuilderThrows( clusterAdmin().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), SnapshotMissingException.class diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 8c9306bd9276d..1f5308718a4e8 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -190,7 +190,7 @@ public void testSnapshotWithStuckNode() throws Exception { logger.info("--> making sure that snapshot no longer exists"); expectThrows( SnapshotMissingException.class, - () -> clusterAdmin().prepareGetSnapshots("test-repo").setSnapshots("test-snap").execute().actionGet().getSnapshots("test-repo") + () -> client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").execute().actionGet() ); logger.info("--> Go through a loop of creating and deleting a snapshot to trigger repository cleanup"); @@ -889,8 +889,8 @@ public void testDataNodeRestartWithBusyMasterDuringSnapshot() throws Exception { .setSnapshots("test-snap") .setIgnoreUnavailable(true) .get(); - assertEquals(1, snapshotsStatusResponse.getSnapshots("test-repo").size()); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); + assertEquals(1, snapshotsStatusResponse.getSnapshots().size()); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertTrue(snapshotInfo.state().toString(), snapshotInfo.state().completed()); }, 60L, TimeUnit.SECONDS); } @@ -943,8 +943,8 @@ public void testDataNodeRestartAfterShardSnapshotFailure() throws Exception { .setSnapshots("test-snap") .setIgnoreUnavailable(true) .get(); - assertEquals(1, snapshotsStatusResponse.getSnapshots("test-repo").size()); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); + assertEquals(1, snapshotsStatusResponse.getSnapshots().size()); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertTrue(snapshotInfo.state().toString(), snapshotInfo.state().completed()); assertThat(snapshotInfo.totalShards(), is(2)); assertThat(snapshotInfo.shardFailures(), hasSize(2)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/GetSnapshotsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/GetSnapshotsIT.java index 2c12224472a73..bd4f81fac1b22 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/GetSnapshotsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/GetSnapshotsIT.java @@ -55,7 +55,7 @@ public void testSortBy() throws Exception { } private void doTestSortOrder(String repoName, Collection allSnapshotNames, SortOrder order) { - final List defaultSorting = clusterAdmin().prepareGetSnapshots(repoName).setOrder(order).get().getSnapshots(repoName); + final List defaultSorting = clusterAdmin().prepareGetSnapshots(repoName).setOrder(order).get().getSnapshots(); assertSnapshotListSorted(defaultSorting, null, order); assertSnapshotListSorted( allSnapshotsSorted(allSnapshotNames, repoName, GetSnapshotsRequest.SortBy.NAME, order), @@ -211,7 +211,7 @@ private static List sortedWithLimit( int size, SortOrder order ) { - return baseGetSnapshotsRequest(repoName).setAfter(after, sortBy).setSize(size).setOrder(order).get().getSnapshots(repoName); + return baseGetSnapshotsRequest(repoName).setAfter(after, sortBy).setSize(size).setOrder(order).get().getSnapshots(); } private static GetSnapshotsRequestBuilder baseGetSnapshotsRequest(String repoName) { @@ -222,7 +222,7 @@ private static GetSnapshotsRequestBuilder baseGetSnapshotsRequest(String repoNam .setSnapshots(AbstractSnapshotIntegTestCase.OLD_VERSION_SNAPSHOT_PREFIX + "*") .setIgnoreUnavailable(true) .get() - .getSnapshots(repoName) + .getSnapshots() .isEmpty() == false) { builder.setSnapshots(RANDOM_SNAPSHOT_NAME_PREFIX + "*"); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index c333ad2cf843a..ec0090e2d1a90 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -81,7 +81,7 @@ public void testWhenMetadataAreLoaded() throws Exception { .addSnapshots("snap") .setVerbose(randomBoolean()) .get(); - assertThat(getSnapshotsResponse.getSnapshots("repository"), hasSize(1)); + assertThat(getSnapshotsResponse.getSnapshots(), hasSize(1)); assertGlobalMetadataLoads("snap", 0); assertIndexMetadataLoads("snap", "docs", 0); assertIndexMetadataLoads("snap", "others", 0); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 7b0b372e7881a..20ec6259e2180 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -153,7 +153,7 @@ public void testBasicWorkFlow() throws Exception { List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo") .setSnapshots(randomFrom("test-snap", "_all", "*", "*-snap", "test*")) .get() - .getSnapshots("test-repo"); + .getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); @@ -1052,8 +1052,7 @@ public void testReadonlyRepository() throws Exception { logger.info("--> list available shapshots"); GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("readonly-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots("readonly-repo"), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); logger.info("--> try deleting snapshot"); assertRequestBuilderThrows( @@ -1205,8 +1204,8 @@ public void testSnapshotStatus() throws Exception { .setCurrentSnapshot() .execute() .actionGet(); - assertThat(getResponse.getSnapshots("test-repo").size(), equalTo(1)); - SnapshotInfo snapshotInfo = getResponse.getSnapshots("test-repo").get(0); + assertThat(getResponse.getSnapshots().size(), equalTo(1)); + SnapshotInfo snapshotInfo = getResponse.getSnapshots().get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.IN_PROGRESS)); logger.info("--> unblocking blocked node"); @@ -1241,7 +1240,7 @@ public void testSnapshotStatus() throws Exception { .addSnapshots("_current") .execute() .actionGet() - .getSnapshots("test-repo") + .getSnapshots() .isEmpty(), equalTo(true) ); @@ -1555,7 +1554,7 @@ 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().getSnapshots("test-repo") + () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo").get() ); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", "_foo").get()); expectThrows( @@ -1599,7 +1598,7 @@ public void testListCorruptedSnapshot() throws Exception { .prepareGetSnapshots("test-repo") .setIgnoreUnavailable(true) .get() - .getSnapshots("test-repo"); + .getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); @@ -1607,7 +1606,7 @@ public void testListCorruptedSnapshot() throws Exception { final SnapshotException ex = expectThrows( SnapshotException.class, - () -> client.admin().cluster().prepareGetSnapshots("test-repo").setIgnoreUnavailable(false).get().getSnapshots("test-repo") + () -> client.admin().cluster().prepareGetSnapshots("test-repo").setIgnoreUnavailable(false).get() ); assertThat(ex.getRepositoryName(), equalTo("test-repo")); assertThat(ex.getSnapshotName(), equalTo("test-snap-2")); @@ -1636,7 +1635,7 @@ public void testRestoreSnapshotWithCorruptedGlobalState() throws Exception { outChan.truncate(randomInt(10)); } - List snapshotInfos = clusterAdmin().prepareGetSnapshots(repoName).get().getSnapshots(repoName); + List snapshotInfos = clusterAdmin().prepareGetSnapshots(repoName).get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo(snapshotName)); @@ -1713,7 +1712,7 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { outChan.truncate(randomInt(10)); } - List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); + List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap")); @@ -1942,18 +1941,18 @@ public void testGetSnapshotsFromIndexBlobOnly() throws Exception { logger.info("--> verify _all returns snapshot info"); GetSnapshotsResponse response = clusterAdmin().prepareGetSnapshots("test-repo").setSnapshots("_all").setVerbose(false).get(); - assertEquals(indicesPerSnapshot.size(), response.getSnapshots("test-repo").size()); + assertEquals(indicesPerSnapshot.size(), response.getSnapshots().size()); verifySnapshotInfo(response, indicesPerSnapshot); logger.info("--> verify wildcard returns snapshot info"); response = clusterAdmin().prepareGetSnapshots("test-repo").setSnapshots("test-snap-*").setVerbose(false).get(); - assertEquals(indicesPerSnapshot.size(), response.getSnapshots("test-repo").size()); + assertEquals(indicesPerSnapshot.size(), response.getSnapshots().size()); verifySnapshotInfo(response, indicesPerSnapshot); logger.info("--> verify individual requests return snapshot info"); for (int i = 0; i < numSnapshots; i++) { response = clusterAdmin().prepareGetSnapshots("test-repo").setSnapshots("test-snap-" + i).setVerbose(false).get(); - assertEquals(1, response.getSnapshots("test-repo").size()); + assertEquals(1, response.getSnapshots().size()); verifySnapshotInfo(response, indicesPerSnapshot); } } @@ -2116,7 +2115,7 @@ public void testBulkDeleteWithOverlappingPatterns() { logger.info("--> deleting all snapshots"); clusterAdmin().prepareDeleteSnapshot("test-repo", "test-snap-*", "*").get(); final GetSnapshotsResponse getSnapshotsResponse = clusterAdmin().prepareGetSnapshots("test-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots("test-repo"), empty()); + assertThat(getSnapshotsResponse.getSnapshots(), empty()); } public void testHiddenIndicesIncludedInSnapshot() throws Exception { @@ -2150,7 +2149,7 @@ public void testHiddenIndicesIncludedInSnapshot() throws Exception { .prepareGetSnapshots(repoName) .setSnapshots(randomFrom(snapName, "_all", "*", "*-snap", "test*")) .get() - .getSnapshots(repoName); + .getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); @@ -2272,7 +2271,7 @@ public void testIndexLatestFailuresIgnored() throws Exception { } private void verifySnapshotInfo(final GetSnapshotsResponse response, final Map> indicesPerSnapshot) { - for (SnapshotInfo snapshotInfo : response.getSnapshots("test-repo")) { + for (SnapshotInfo snapshotInfo : response.getSnapshots()) { final List expected = snapshotInfo.indices(); assertEquals(expected, indicesPerSnapshot.get(snapshotInfo.snapshotId().getName())); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStatusApisIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStatusApisIT.java index e4c4267b45ed8..860d5544dd803 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStatusApisIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStatusApisIT.java @@ -10,7 +10,6 @@ import org.elasticsearch.Version; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse; -import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotIndexShardStage; import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotIndexShardStatus; @@ -77,7 +76,7 @@ public void testStatusApiConsistency() throws Exception { createFullSnapshot("test-repo", "test-snap"); - List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); + List snapshotInfos = clusterAdmin().prepareGetSnapshots("test-repo").get().getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); @@ -131,11 +130,10 @@ public void testExceptionOnMissingSnapBlob() throws IOException { logger.info("--> delete snap-${uuid}.dat file for this snapshot to simulate concurrent delete"); IOUtils.rm(repoPath.resolve(BlobStoreRepository.SNAPSHOT_PREFIX + snapshotInfo.snapshotId().getUUID() + ".dat")); - GetSnapshotsResponse snapshotsResponse = client().admin() - .cluster() - .getSnapshots(new GetSnapshotsRequest(new String[] { "test-repo" }, new String[] { "test-snap" })) - .actionGet(); - assertThat(snapshotsResponse.getFailedResponses().get("test-repo"), instanceOf(SnapshotMissingException.class)); + expectThrows( + SnapshotMissingException.class, + () -> client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").execute().actionGet() + ); } public void testExceptionOnMissingShardLevelSnapBlob() throws IOException { @@ -185,7 +183,7 @@ public void testGetSnapshotsWithoutIndices() throws Exception { .prepareGetSnapshots("test-repo") .setVerbose(false) .get() - .getSnapshots("test-repo"); + .getSnapshots(); assertThat(snapshotInfos, hasSize(1)); final SnapshotInfo found = snapshotInfos.get(0); assertThat(found.snapshotId(), is(snapshotInfo.snapshotId())); @@ -301,9 +299,8 @@ public void testGetSnapshotsNoRepos() { .setSnapshots(randomFrom("_all", "*")) .get(); - assertTrue(getSnapshotsResponse.getRepositories().isEmpty()); - assertTrue(getSnapshotsResponse.getFailedResponses().isEmpty()); - assertTrue(getSnapshotsResponse.getSuccessfulResponses().isEmpty()); + assertTrue(getSnapshotsResponse.getSnapshots().isEmpty()); + assertTrue(getSnapshotsResponse.getFailures().isEmpty()); } public void testGetSnapshotsMultipleRepos() throws Exception { @@ -371,8 +368,11 @@ public void testGetSnapshotsMultipleRepos() throws Exception { 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())); + List snapshots = getSnapshotsResponse.getSnapshots(); + assertEquals( + snapshotNames, + snapshots.stream().filter(s -> s.repository().equals(repo)).map(s -> s.snapshotId().getName()).collect(Collectors.toList()) + ); } logger.info("--> specify all snapshot names with ignoreUnavailable=false"); @@ -384,7 +384,7 @@ public void testGetSnapshotsMultipleRepos() throws Exception { .get(); for (String repo : repoList) { - expectThrows(SnapshotMissingException.class, () -> getSnapshotsResponse2.getSnapshots(repo)); + assertThat(getSnapshotsResponse2.getFailures().get(repo), instanceOf(SnapshotMissingException.class)); } logger.info("--> specify all snapshot names with ignoreUnavailable=true"); @@ -398,8 +398,11 @@ public void testGetSnapshotsMultipleRepos() throws Exception { 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())); + List snapshots = getSnapshotsResponse3.getSnapshots(); + assertEquals( + snapshotNames, + snapshots.stream().filter(s -> s.repository().equals(repo)).map(s -> s.snapshotId().getName()).collect(Collectors.toList()) + ); } } @@ -421,7 +424,7 @@ public void testGetSnapshotsWithSnapshotInProgress() throws Exception { .setSnapshots("test-snap") .setIgnoreUnavailable(true) .get(); - List snapshotInfoList = response1.getSnapshots("test-repo"); + List snapshotInfoList = response1.getSnapshots(); assertEquals(1, snapshotInfoList.size()); assertEquals(SnapshotState.IN_PROGRESS, snapshotInfoList.get(0).state()); @@ -432,15 +435,18 @@ public void testGetSnapshotsWithSnapshotInProgress() throws Exception { .setSnapshots(notExistedSnapshotName) .setIgnoreUnavailable(true) .get(); - assertEquals(0, response2.getSnapshots("test-repo").size()); + assertEquals(0, response2.getSnapshots().size()); - GetSnapshotsResponse response3 = client().admin() - .cluster() - .prepareGetSnapshots("test-repo") - .setSnapshots(notExistedSnapshotName) - .setIgnoreUnavailable(false) - .get(); - expectThrows(SnapshotMissingException.class, () -> response3.getSnapshots("test-repo")); + expectThrows( + SnapshotMissingException.class, + () -> client().admin() + .cluster() + .prepareGetSnapshots("test-repo") + .setSnapshots(notExistedSnapshotName) + .setIgnoreUnavailable(false) + .execute() + .actionGet() + ); logger.info("--> unblock all data nodes"); unblockAllDataNodes("test-repo"); @@ -482,12 +488,7 @@ public void testGetSnapshotsRequest() throws Exception { logger.info("--> get snapshots on an empty repository"); expectThrows( SnapshotMissingException.class, - () -> client.admin() - .cluster() - .prepareGetSnapshots(repositoryName) - .addSnapshots("non-existent-snapshot") - .get() - .getSnapshots(repositoryName) + () -> client.admin().cluster().prepareGetSnapshots(repositoryName).addSnapshots("non-existent-snapshot").get() ); // with ignore unavailable set to true, should not throw an exception GetSnapshotsResponse getSnapshotsResponse = client.admin() @@ -496,7 +497,7 @@ public void testGetSnapshotsRequest() throws Exception { .setIgnoreUnavailable(true) .addSnapshots("non-existent-snapshot") .get(); - assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(0)); + assertThat(getSnapshotsResponse.getSnapshots().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 @@ -520,8 +521,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("test-repo").size()); - assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); + assertEquals(1, getSnapshotsResponse.getSnapshots().size()); + assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots().get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node startDeleteSnapshot(repositoryName, "snap-on-empty-repo").get(); @@ -577,26 +578,18 @@ public void testGetSnapshotsRequest() throws Exception { .get(); List sortedNames = Arrays.asList(snapshotNames); Collections.sort(sortedNames); - assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); assertThat( - getSnapshotsResponse.getSnapshots(repositoryName) - .stream() - .map(s -> s.snapshotId().getName()) - .sorted() - .collect(Collectors.toList()), + getSnapshotsResponse.getSnapshots().stream().map(s -> s.snapshotId().getName()).sorted().collect(Collectors.toList()), equalTo(sortedNames) ); getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots(repositoryName).addSnapshots(snapshotNames).get(); sortedNames = Arrays.asList(snapshotNames); Collections.sort(sortedNames); - assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); assertThat( - getSnapshotsResponse.getSnapshots(repositoryName) - .stream() - .map(s -> s.snapshotId().getName()) - .sorted() - .collect(Collectors.toList()), + getSnapshotsResponse.getSnapshots().stream().map(s -> s.snapshotId().getName()).sorted().collect(Collectors.toList()), equalTo(sortedNames) ); @@ -611,13 +604,9 @@ public void testGetSnapshotsRequest() throws Exception { .addSnapshots(snapshotNames) .addSnapshots(firstRegex, secondRegex) .get(); - assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); assertThat( - getSnapshotsResponse.getSnapshots(repositoryName) - .stream() - .map(s -> s.snapshotId().getName()) - .sorted() - .collect(Collectors.toList()), + getSnapshotsResponse.getSnapshots().stream().map(s -> s.snapshotId().getName()).sorted().collect(Collectors.toList()), equalTo(sortedNames) ); @@ -649,7 +638,7 @@ public void testConcurrentCreateAndStatusAPICalls() throws Exception { } } for (ActionFuture get : gets) { - final List snapshotInfos = get.get().getSnapshots(repoName); + final List snapshotInfos = get.get().getSnapshots(); assertThat(snapshotInfos, hasSize(snapshots)); for (SnapshotInfo snapshotInfo : snapshotInfos) { assertThat(snapshotInfo.state(), is(SnapshotState.SUCCESS)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SystemIndicesSnapshotIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SystemIndicesSnapshotIT.java index 7b6abf0ec2b84..fa73d9ef54b33 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SystemIndicesSnapshotIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SystemIndicesSnapshotIT.java @@ -116,7 +116,7 @@ public void testSnapshotWithoutGlobalState() { clusterAdmin().prepareGetRepositories(REPO_NAME).get(); Set snapshottedIndices = clusterAdmin().prepareGetSnapshots(REPO_NAME) .get() - .getSnapshots(REPO_NAME) + .getSnapshots() .stream() .map(SnapshotInfo::indices) .flatMap(Collection::stream) @@ -274,7 +274,7 @@ public void testSnapshotAndRestoreAssociatedIndices() { // verify the correctness of the snapshot Set snapshottedIndices = clusterAdmin().prepareGetSnapshots(REPO_NAME) .get() - .getSnapshots(REPO_NAME) + .getSnapshots() .stream() .map(SnapshotInfo::indices) .flatMap(Collection::stream) @@ -719,7 +719,7 @@ public void testNoneFeatureStateOnCreation() { // Verify that the system index was not included Set snapshottedIndices = clusterAdmin().prepareGetSnapshots(REPO_NAME) .get() - .getSnapshots(REPO_NAME) + .getSnapshots() .stream() .map(SnapshotInfo::indices) .flatMap(Collection::stream) @@ -843,7 +843,7 @@ public void testPartialSnapshotsOfSystemIndexRemovesFeatureState() throws Except .prepareGetSnapshots(REPO_NAME) .setSnapshots(partialSnapName) .get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(REPO_NAME).get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertNotNull(snapshotInfo); assertThat(snapshotInfo.failedShards(), lessThan(snapshotInfo.totalShards())); List statesInSnapshot = snapshotInfo.featureStates() 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 4f1abfe5b2b7c..90a107d493d70 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 @@ -15,6 +15,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.regex.Regex; import org.elasticsearch.core.Nullable; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.snapshots.SnapshotInfo; @@ -176,6 +177,13 @@ public String[] repositories() { return this.repositories; } + public boolean isSingleRepositoryRequest() { + return repositories.length == 1 + && repositories[0] != null + && "_all".equals(repositories[0]) == false + && Regex.isSimpleMatchPattern(repositories[0]) == false; + } + /** * Returns the names of the snapshots. * 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 df7755acc9082..3e64a6a0889fd 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 @@ -13,217 +13,140 @@ 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.ParseField; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.snapshots.SnapshotInfo; import java.io.IOException; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.Objects; /** * Get snapshots response */ public class GetSnapshotsResponse extends ActionResponse implements ToXContentObject { - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + @SuppressWarnings("unchecked") + private static final ConstructingObjectParser GET_SNAPSHOT_PARSER = new ConstructingObjectParser<>( GetSnapshotsResponse.class.getName(), true, - (args) -> new GetSnapshotsResponse((List) args[0]) + (args) -> new GetSnapshotsResponse((List) args[0], (Map) args[1]) ); static { - PARSER.declareObjectArray( + GET_SNAPSHOT_PARSER.declareObjectArray( ConstructingObjectParser.constructorArg(), - (p, c) -> Response.fromXContent(p), - new ParseField("responses") + (p, c) -> SnapshotInfo.SNAPSHOT_INFO_PARSER.apply(p, c).build(), + new ParseField("snapshots") ); - } - - public GetSnapshotsResponse(StreamInput in) throws IOException { - if (in.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { - Map> successfulResponses = in.readMapOfLists(StreamInput::readString, SnapshotInfo::readFrom); - Map failedResponses = in.readMap(StreamInput::readString, StreamInput::readException); - this.successfulResponses = Collections.unmodifiableMap(successfulResponses); - this.failedResponses = Collections.unmodifiableMap(failedResponses); - } else { - this.successfulResponses = Collections.singletonMap("unknown", in.readList(SnapshotInfo::readFrom)); - this.failedResponses = Collections.emptyMap(); - } - } - - public static class Response { - private final String repository; - private final List snapshots; - private final 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]) + GET_SNAPSHOT_PARSER.declareObject( + ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> p.map(HashMap::new, ElasticsearchException::fromXContent), + new ParseField("failures") ); + } - 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 final List snapshots; - private static Response fromXContent(XContentParser parser) throws IOException { - return RESPONSE_PARSER.parse(parser, null); - } - } + private final Map failures; - 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); + public GetSnapshotsResponse(List snapshots, Map failures) { + this.snapshots = List.copyOf(snapshots); + this.failures = failures == null ? Map.of() : Map.copyOf(failures); } - /** - * 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(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"); + public GetSnapshotsResponse(StreamInput in) throws IOException { + this.snapshots = in.readList(SnapshotInfo::readFrom); + if (in.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + final Map failedResponses = in.readMap(StreamInput::readString, StreamInput::readException); + this.failures = Collections.unmodifiableMap(failedResponses); + } else { + this.failures = Collections.emptyMap(); } - throw error; - } - - /** - * Returns list of repositories for both successful and unsuccessful responses. - */ - public Set getRepositories() { - return Sets.union(successfulResponses.keySet(), failedResponses.keySet()); } /** - * Returns a map of repository name to the list of {@link SnapshotInfo} for each successful response. + * Returns the list of snapshots + * + * @return the list of snapshots */ - public Map> getSuccessfulResponses() { - return successfulResponses; + public List getSnapshots() { + return snapshots; } /** * Returns a map of repository name to {@link ElasticsearchException} for each unsuccessful response. */ - public Map getFailedResponses() { - return failedResponses; + public Map getFailures() { + return failures; } /** * Returns true if there is a least one failed response. */ public boolean isFailed() { - return failedResponses.isEmpty() == false; + return failures.isEmpty() == false; } @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - 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); + public void writeTo(StreamOutput out) throws IOException { + out.writeList(snapshots); + if (out.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + out.writeMap(failures, StreamOutput::writeString, StreamOutput::writeException); + } else { + if (failures.isEmpty() == false) { + assert false : "transport action should have thrown directly for old version but saw " + failures; + throw failures.values().iterator().next(); } - 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(); + @Override + public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { + builder.startObject(); + builder.startArray("snapshots"); + for (SnapshotInfo snapshotInfo : snapshots) { + snapshotInfo.toXContent(builder, params); } - builder.endArray(); + if (failures.isEmpty() == false) { + builder.startObject("failures"); + for (Map.Entry error : failures.entrySet()) { + builder.field(error.getKey(), (b, pa) -> { + b.startObject(); + error.getValue().toXContent(b, pa); + b.endObject(); + return b; + }); + } + builder.endObject(); + } builder.endObject(); return builder; } - @Override - public void writeTo(StreamOutput out) throws IOException { - if (out.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { - out.writeMapOfLists(successfulResponses, StreamOutput::writeString, (o, s) -> s.writeTo(o)); - out.writeMap(failedResponses, StreamOutput::writeString, StreamOutput::writeException); - } 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) { - out.writeList(successfulResponses.values().iterator().next()); - } + public static GetSnapshotsResponse fromXContent(XContentParser parser) throws IOException { + return GET_SNAPSHOT_PARSER.parse(parser, null); + } - 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) && Objects.equals(failures, that.failures); } - public static GetSnapshotsResponse fromXContent(XContentParser parser) throws IOException { - return PARSER.parse(parser, null); + @Override + public int hashCode() { + return Objects.hash(snapshots, failures); } @Override 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 7a605f21776bb..ce5a8f7c596c4 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 @@ -28,6 +28,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.core.Nullable; +import org.elasticsearch.core.Tuple; import org.elasticsearch.repositories.GetSnapshotInfoContext; import org.elasticsearch.repositories.IndexId; import org.elasticsearch.repositories.RepositoriesService; @@ -35,6 +36,7 @@ import org.elasticsearch.repositories.RepositoryData; import org.elasticsearch.repositories.RepositoryMissingException; import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotMissingException; @@ -53,6 +55,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.function.ToLongFunction; @@ -106,6 +109,7 @@ protected void masterOperation( assert task instanceof CancellableTask : task + " not cancellable"; getMultipleReposSnapshotInfo( + request.isSingleRepositoryRequest() == false, state.custom(SnapshotsInProgress.TYPE, SnapshotsInProgress.EMPTY), TransportGetRepositoriesAction.getRepositories(state, request.repositories()), request.snapshots(), @@ -121,6 +125,7 @@ protected void masterOperation( } private void getMultipleReposSnapshotInfo( + boolean isMultiRepoRequest, SnapshotsInProgress snapshotsInProgress, List repos, String[] snapshots, @@ -135,16 +140,23 @@ private void getMultipleReposSnapshotInfo( ) { // short-circuit if there are no repos, because we can not create GroupedActionListener of size 0 if (repos.isEmpty()) { - listener.onResponse(new GetSnapshotsResponse(Collections.emptyList())); + listener.onResponse(new GetSnapshotsResponse(Collections.emptyList(), Collections.emptyMap())); return; } - final GroupedActionListener groupedActionListener = new GroupedActionListener<>( - listener.map(responses -> { + final GroupedActionListener, List>> groupedActionListener = + new GroupedActionListener<>(listener.map(responses -> { assert repos.size() == responses.size(); - return new GetSnapshotsResponse(responses); - }), - repos.size() - ); + final List allSnapshots = responses.stream() + .map(Tuple::v2) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toUnmodifiableList()); + final Map failures = responses.stream() + .map(Tuple::v1) + .filter(Objects::nonNull) + .collect(Collectors.toMap(Tuple::v1, Tuple::v2)); + return new GetSnapshotsResponse(sortSnapshots(allSnapshots, sortBy, after, size, order), failures); + }), repos.size()); for (final RepositoryMetadata repo : repos) { final String repoName = repo.name(); @@ -160,12 +172,12 @@ private void getMultipleReposSnapshotInfo( size, order, groupedActionListener.delegateResponse((groupedListener, e) -> { - if (e instanceof ElasticsearchException) { - groupedListener.onResponse(GetSnapshotsResponse.Response.error(repoName, (ElasticsearchException) e)); + if (isMultiRepoRequest && e instanceof ElasticsearchException) { + groupedListener.onResponse(Tuple.tuple(Tuple.tuple(repoName, (ElasticsearchException) e), null)); } else { groupedListener.onFailure(e); } - }).map(snInfos -> GetSnapshotsResponse.Response.snapshots(repoName, snInfos)) + }).map(snInfos -> Tuple.tuple(null, snInfos)) ); } } @@ -183,11 +195,11 @@ private void getSingleRepoSnapshotInfo( SortOrder order, ActionListener> listener ) { - final Map allSnapshotIds = new HashMap<>(); + final Map allSnapshotIds = new HashMap<>(); final List currentSnapshots = new ArrayList<>(); for (SnapshotInfo snapshotInfo : sortedCurrentSnapshots(snapshotsInProgress, repo, sortBy, after, size, order)) { - SnapshotId snapshotId = snapshotInfo.snapshotId(); - allSnapshotIds.put(snapshotId.getName(), snapshotId); + Snapshot snapshot = snapshotInfo.snapshot(); + allSnapshotIds.put(snapshot.getSnapshotId().getName(), snapshot); currentSnapshots.add(snapshotInfo); } @@ -252,7 +264,7 @@ private void loadSnapshotInfos( String[] snapshots, boolean ignoreUnavailable, boolean verbose, - Map allSnapshotIds, + Map allSnapshotIds, List currentSnapshots, @Nullable RepositoryData repositoryData, CancellableTask task, @@ -269,17 +281,17 @@ private void loadSnapshotInfos( if (repositoryData != null) { for (SnapshotId snapshotId : repositoryData.getSnapshotIds()) { - allSnapshotIds.put(snapshotId.getName(), snapshotId); + allSnapshotIds.put(snapshotId.getName(), new Snapshot(repo, snapshotId)); } } - final Set toResolve = new HashSet<>(); + 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())); + toResolve.addAll(currentSnapshots.stream().map(SnapshotInfo::snapshot).collect(Collectors.toList())); } else if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { if (allSnapshotIds.containsKey(snapshotOrPattern)) { toResolve.add(allSnapshotIds.get(snapshotOrPattern)); @@ -287,7 +299,7 @@ private void loadSnapshotInfos( throw new SnapshotMissingException(repo, snapshotOrPattern); } } else { - for (Map.Entry entry : allSnapshotIds.entrySet()) { + for (Map.Entry entry : allSnapshotIds.entrySet()) { if (Regex.simpleMatch(snapshotOrPattern, entry.getKey())) { toResolve.add(entry.getValue()); } @@ -301,12 +313,23 @@ private void loadSnapshotInfos( } if (verbose) { - snapshots(snapshotsInProgress, repo, toResolve, ignoreUnavailable, task, sortBy, after, size, order, listener); + snapshots( + snapshotsInProgress, + repo, + toResolve.stream().map(Snapshot::getSnapshotId).collect(Collectors.toUnmodifiableList()), + ignoreUnavailable, + task, + sortBy, + after, + size, + order, + listener + ); } else { final List snapshotInfos; if (repositoryData != null) { // want non-current snapshots as well, which are found in the repository data - snapshotInfos = buildSimpleSnapshotInfos(toResolve, repositoryData, currentSnapshots, sortBy, after, size, order); + snapshotInfos = buildSimpleSnapshotInfos(toResolve, repo, repositoryData, currentSnapshots, sortBy, after, size, order); } else { // only want current snapshots snapshotInfos = sortSnapshots( @@ -411,7 +434,8 @@ private boolean isCurrentSnapshotsOnly(String[] snapshots) { } private static List buildSimpleSnapshotInfos( - final Set toResolve, + final Set toResolve, + final String repoName, final RepositoryData repositoryData, final List currentSnapshots, final GetSnapshotsRequest.SortBy sortBy, @@ -421,28 +445,28 @@ private static List buildSimpleSnapshotInfos( ) { List snapshotInfos = new ArrayList<>(); for (SnapshotInfo snapshotInfo : currentSnapshots) { - if (toResolve.remove(snapshotInfo.snapshotId())) { + if (toResolve.remove(snapshotInfo.snapshot())) { snapshotInfos.add(snapshotInfo.basic()); } } Map> snapshotsToIndices = new HashMap<>(); for (IndexId indexId : repositoryData.getIndices().values()) { for (SnapshotId snapshotId : repositoryData.getSnapshots(indexId)) { - if (toResolve.contains(snapshotId)) { + if (toResolve.contains(new Snapshot(repoName, snapshotId))) { snapshotsToIndices.computeIfAbsent(snapshotId, (k) -> new ArrayList<>()).add(indexId.getName()); } } } - for (SnapshotId snapshotId : toResolve) { - final List indices = snapshotsToIndices.getOrDefault(snapshotId, Collections.emptyList()); + for (Snapshot snapshot : toResolve) { + final List indices = snapshotsToIndices.getOrDefault(snapshot.getSnapshotId(), Collections.emptyList()); CollectionUtil.timSort(indices); snapshotInfos.add( new SnapshotInfo( - snapshotId, + snapshot, indices, Collections.emptyList(), Collections.emptyList(), - repositoryData.getSnapshotState(snapshotId) + repositoryData.getSnapshotState(snapshot.getSnapshotId()) ) ); } diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java index 5b9bc8d8440fa..e186e658e5524 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -259,13 +259,13 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent imp public static final ChecksumBlobStoreFormat GLOBAL_METADATA_FORMAT = new ChecksumBlobStoreFormat<>( "metadata", METADATA_NAME_FORMAT, - Metadata::fromXContent + (repoName, parser) -> Metadata.fromXContent(parser) ); public static final ChecksumBlobStoreFormat INDEX_METADATA_FORMAT = new ChecksumBlobStoreFormat<>( "index-metadata", METADATA_NAME_FORMAT, - IndexMetadata::fromXContent + (repoName, parser) -> IndexMetadata.fromXContent(parser) ); private static final String SNAPSHOT_CODEC = "snapshot"; @@ -279,13 +279,13 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent imp public static final ChecksumBlobStoreFormat INDEX_SHARD_SNAPSHOT_FORMAT = new ChecksumBlobStoreFormat<>( SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT, - BlobStoreIndexShardSnapshot::fromXContent + (repoName, parser) -> BlobStoreIndexShardSnapshot.fromXContent(parser) ); public static final ChecksumBlobStoreFormat INDEX_SHARD_SNAPSHOTS_FORMAT = new ChecksumBlobStoreFormat<>( "snapshots", SNAPSHOT_INDEX_NAME_FORMAT, - BlobStoreIndexShardSnapshots::fromXContent + (repoName, parser) -> BlobStoreIndexShardSnapshots.fromXContent(parser) ); public static final Setting MAX_SNAPSHOT_BYTES_PER_SEC = Setting.byteSizeSetting( @@ -997,7 +997,8 @@ private void writeUpdatedShardMetaDataAndComputeDeletes( for (String indexMetaGeneration : indexMetaGenerations) { executor.execute(ActionRunnable.supply(allShardCountsListener, () -> { try { - return INDEX_METADATA_FORMAT.read(indexContainer, indexMetaGeneration, namedXContentRegistry).getNumberOfShards(); + return INDEX_METADATA_FORMAT.read(metadata.name(), indexContainer, indexMetaGeneration, namedXContentRegistry) + .getNumberOfShards(); } catch (Exception ex) { logger.warn( () -> new ParameterizedMessage( @@ -1482,7 +1483,7 @@ private void getOneSnapshotInfo(BlockingQueue queue, GetSnapshotInfo Exception failure = null; SnapshotInfo snapshotInfo = null; try { - snapshotInfo = SNAPSHOT_FORMAT.read(blobContainer(), snapshotId.getUUID(), namedXContentRegistry); + snapshotInfo = SNAPSHOT_FORMAT.read(metadata.name(), blobContainer(), snapshotId.getUUID(), namedXContentRegistry); } catch (NoSuchFileException ex) { failure = new SnapshotMissingException(metadata.name(), snapshotId, ex); } catch (IOException | NotXContentException ex) { @@ -1508,7 +1509,7 @@ private void getOneSnapshotInfo(BlockingQueue queue, GetSnapshotInfo @Override public Metadata getSnapshotGlobalMetadata(final SnapshotId snapshotId) { try { - return GLOBAL_METADATA_FORMAT.read(blobContainer(), snapshotId.getUUID(), namedXContentRegistry); + return GLOBAL_METADATA_FORMAT.read(metadata.name(), blobContainer(), snapshotId.getUUID(), namedXContentRegistry); } catch (NoSuchFileException ex) { throw new SnapshotMissingException(metadata.name(), snapshotId, ex); } catch (IOException ex) { @@ -1520,6 +1521,7 @@ public Metadata getSnapshotGlobalMetadata(final SnapshotId snapshotId) { public IndexMetadata getSnapshotIndexMetaData(RepositoryData repositoryData, SnapshotId snapshotId, IndexId index) throws IOException { try { return INDEX_METADATA_FORMAT.read( + metadata.name(), indexContainer(index), repositoryData.indexMetaDataGenerations().indexMetaBlobId(snapshotId, index), namedXContentRegistry @@ -3213,7 +3215,7 @@ private static List unusedBlobs( */ public BlobStoreIndexShardSnapshot loadShardSnapshot(BlobContainer shardContainer, SnapshotId snapshotId) { try { - return INDEX_SHARD_SNAPSHOT_FORMAT.read(shardContainer, snapshotId.getUUID(), namedXContentRegistry); + return INDEX_SHARD_SNAPSHOT_FORMAT.read(metadata.name(), shardContainer, snapshotId.getUUID(), namedXContentRegistry); } catch (NoSuchFileException ex) { throw new SnapshotMissingException(metadata.name(), snapshotId, ex); } catch (IOException ex) { @@ -3245,7 +3247,10 @@ private Tuple buildBlobStoreIndexShardSnap if (generation.equals(ShardGenerations.NEW_SHARD_GEN)) { return new Tuple<>(BlobStoreIndexShardSnapshots.EMPTY, ShardGenerations.NEW_SHARD_GEN); } - return new Tuple<>(INDEX_SHARD_SNAPSHOTS_FORMAT.read(shardContainer, generation, namedXContentRegistry), generation); + return new Tuple<>( + INDEX_SHARD_SNAPSHOTS_FORMAT.read(metadata.name(), shardContainer, generation, namedXContentRegistry), + generation + ); } final Tuple legacyIndex = buildBlobStoreIndexShardSnapshots(blobs, shardContainer); return new Tuple<>(legacyIndex.v1(), String.valueOf(legacyIndex.v2())); @@ -3262,6 +3267,7 @@ private Tuple buildBlobStoreIndexShardSnapsh long latest = latestGeneration(blobs); if (latest >= 0) { final BlobStoreIndexShardSnapshots shardSnapshots = INDEX_SHARD_SNAPSHOTS_FORMAT.read( + metadata.name(), shardContainer, Long.toString(latest), namedXContentRegistry diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/ChecksumBlobStoreFormat.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/ChecksumBlobStoreFormat.java index 5c75259724168..00f136b6413fa 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/ChecksumBlobStoreFormat.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/ChecksumBlobStoreFormat.java @@ -15,6 +15,7 @@ import org.apache.lucene.store.InputStreamDataInput; import org.apache.lucene.store.OutputStreamIndexOutput; import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.common.CheckedBiFunction; import org.elasticsearch.common.Numbers; import org.elasticsearch.common.blobstore.BlobContainer; import org.elasticsearch.common.bytes.BytesArray; @@ -32,7 +33,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.core.CheckedConsumer; -import org.elasticsearch.core.CheckedFunction; import org.elasticsearch.gateway.CorruptStateException; import java.io.FilterInputStream; @@ -64,14 +64,14 @@ public final class ChecksumBlobStoreFormat { private final String blobNameFormat; - private final CheckedFunction reader; + private final CheckedBiFunction reader; /** * @param codec codec name * @param blobNameFormat format of the blobname in {@link String#format} format * @param reader prototype object that can deserialize T from XContent */ - public ChecksumBlobStoreFormat(String codec, String blobNameFormat, CheckedFunction reader) { + public ChecksumBlobStoreFormat(String codec, String blobNameFormat, CheckedBiFunction reader) { this.reader = reader; this.blobNameFormat = blobNameFormat; this.codec = codec; @@ -84,10 +84,11 @@ public ChecksumBlobStoreFormat(String codec, String blobNameFormat, CheckedFunct * @param name name to be translated into * @return parsed blob object */ - public T read(BlobContainer blobContainer, String name, NamedXContentRegistry namedXContentRegistry) throws IOException { + public T read(String repoName, BlobContainer blobContainer, String name, NamedXContentRegistry namedXContentRegistry) + throws IOException { String blobName = blobName(name); try (InputStream in = blobContainer.readBlob(blobName)) { - return deserialize(namedXContentRegistry, in); + return deserialize(repoName, namedXContentRegistry, in); } } @@ -95,7 +96,7 @@ public String blobName(String name) { return String.format(Locale.ROOT, blobNameFormat, name); } - public T deserialize(NamedXContentRegistry namedXContentRegistry, InputStream input) throws IOException { + public T deserialize(String repoName, NamedXContentRegistry namedXContentRegistry, InputStream input) throws IOException { final DeserializeMetaBlobInputStream deserializeMetaBlobInputStream = new DeserializeMetaBlobInputStream(input); try { CodecUtil.checkHeader(new InputStreamDataInput(deserializeMetaBlobInputStream), codec, VERSION, VERSION); @@ -110,7 +111,7 @@ public T deserialize(NamedXContentRegistry namedXContentRegistry, InputStream in XContentParser parser = XContentType.SMILE.xContent() .createParser(namedXContentRegistry, LoggingDeprecationHandler.INSTANCE, wrappedStream) ) { - result = reader.apply(parser); + result = reader.apply(repoName, parser); } deserializeMetaBlobInputStream.verifyFooter(); return result; diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java index 7df2fc4c7dbb3..e5548d80d072d 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetSnapshotsAction.java @@ -18,12 +18,12 @@ import org.elasticsearch.search.sort.SortOrder; import java.io.IOException; -import java.util.Collections; import java.util.List; import java.util.Set; import static org.elasticsearch.client.Requests.getSnapshotsRequest; import static org.elasticsearch.rest.RestRequest.Method.GET; +import static org.elasticsearch.snapshots.SnapshotInfo.INCLUDE_REPOSITORY_XCONTENT_PARAM; import static org.elasticsearch.snapshots.SnapshotInfo.INDEX_DETAILS_XCONTENT_PARAM; /** @@ -43,7 +43,7 @@ public String getName() { @Override protected Set responseParams() { - return Collections.singleton(INDEX_DETAILS_XCONTENT_PARAM); + return Set.of(INDEX_DETAILS_XCONTENT_PARAM, INCLUDE_REPOSITORY_XCONTENT_PARAM); } @Override diff --git a/server/src/main/java/org/elasticsearch/rest/action/cat/RestSnapshotAction.java b/server/src/main/java/org/elasticsearch/rest/action/cat/RestSnapshotAction.java index 239828ae53039..ae0fd58006dad 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/cat/RestSnapshotAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/cat/RestSnapshotAction.java @@ -26,7 +26,6 @@ import java.time.Instant; import java.time.ZoneOffset; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; import static org.elasticsearch.rest.RestRequest.Method.GET; @@ -100,7 +99,7 @@ private Table buildTable(RestRequest req, GetSnapshotsResponse getSnapshotsRespo if (getSnapshotsResponse.isFailed()) { ElasticsearchException causes = null; - for (ElasticsearchException e : getSnapshotsResponse.getFailedResponses().values()) { + for (ElasticsearchException e : getSnapshotsResponse.getFailures().values()) { if (causes == null) { causes = e; } else { @@ -109,37 +108,34 @@ private Table buildTable(RestRequest req, GetSnapshotsResponse getSnapshotsRespo } throw new ElasticsearchException( "Repositories [" + - Strings.collectionToCommaDelimitedString(getSnapshotsResponse.getFailedResponses().keySet()) + + Strings.collectionToCommaDelimitedString(getSnapshotsResponse.getFailures().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(); + for (SnapshotInfo snapshotStatus: getSnapshotsResponse.getSnapshots()) { + table.startRow(); + + table.addCell(snapshotStatus.snapshotId().getName()); + table.addCell(snapshotStatus.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(); } return table; diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java index ea8759c8d4fb9..5911b719dd0a9 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotInfo.java @@ -46,10 +46,12 @@ public final class SnapshotInfo implements Comparable, ToXContent, Writeable { public static final String INDEX_DETAILS_XCONTENT_PARAM = "index_details"; + public static final String INCLUDE_REPOSITORY_XCONTENT_PARAM = "include_repository"; private static final DateFormatter DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time"); private static final String SNAPSHOT = "snapshot"; private static final String UUID = "uuid"; + private static final String REPOSITORY = "repository"; private static final String INDICES = "indices"; private static final String DATA_STREAMS = "data_streams"; private static final String STATE = "state"; @@ -75,12 +77,15 @@ public final class SnapshotInfo implements Comparable, ToXContent, private static final String FEATURE_STATES = "feature_states"; private static final String INDEX_DETAILS = "index_details"; + private static final String UNKNOWN_REPO_NAME = "_na_"; + private static final Comparator COMPARATOR = Comparator.comparing(SnapshotInfo::startTime) .thenComparing(SnapshotInfo::snapshotId); public static final class SnapshotInfoBuilder { private String snapshotName = null; private String snapshotUUID = null; + private String repository = UNKNOWN_REPO_NAME; private String state = null; private String reason = null; private List indices = null; @@ -103,6 +108,10 @@ private void setSnapshotUUID(String snapshotUUID) { this.snapshotUUID = snapshotUUID; } + private void setRepository(String repository) { + this.repository = repository; + } + private void setState(String state) { this.state = state; } @@ -156,7 +165,7 @@ private void setShardFailures(List shardFailures) { } public SnapshotInfo build() { - SnapshotId snapshotId = new SnapshotId(snapshotName, snapshotUUID); + final Snapshot snapshot = new Snapshot(repository, new SnapshotId(snapshotName, snapshotUUID)); if (indices == null) { indices = Collections.emptyList(); @@ -185,7 +194,7 @@ public SnapshotInfo build() { } return new SnapshotInfo( - snapshotId, + snapshot, indices, dataStreams, featureStates, @@ -240,6 +249,7 @@ int getSuccessfulShards() { static { SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotName, new ParseField(SNAPSHOT)); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotUUID, new ParseField(UUID)); + SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setRepository, new ParseField(REPOSITORY)); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setState, new ParseField(STATE)); SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setReason, new ParseField(REASON)); SNAPSHOT_INFO_PARSER.declareStringArray(SnapshotInfoBuilder::setIndices, new ParseField(INDICES)); @@ -270,7 +280,7 @@ int getSuccessfulShards() { SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setSuccessfulShards, new ParseField(SUCCESSFUL)); } - private final SnapshotId snapshotId; + private final Snapshot snapshot; @Nullable private final SnapshotState state; @@ -306,14 +316,14 @@ int getSuccessfulShards() { private final Map indexSnapshotDetails; public SnapshotInfo( - SnapshotId snapshotId, + Snapshot snapshot, List indices, List dataStreams, List featureStates, SnapshotState state ) { this( - snapshotId, + snapshot, indices, dataStreams, featureStates, @@ -332,7 +342,7 @@ public SnapshotInfo( } public SnapshotInfo( - SnapshotId snapshotId, + Snapshot snapshot, List indices, List dataStreams, List featureStates, @@ -340,7 +350,7 @@ public SnapshotInfo( SnapshotState state ) { this( - snapshotId, + snapshot, indices, dataStreams, featureStates, @@ -360,7 +370,7 @@ public SnapshotInfo( public SnapshotInfo(SnapshotsInProgress.Entry entry) { this( - entry.snapshot().getSnapshotId(), + entry.snapshot(), List.copyOf(entry.indices().keySet()), entry.dataStreams(), entry.featureStates(), @@ -379,7 +389,7 @@ public SnapshotInfo(SnapshotsInProgress.Entry entry) { } public SnapshotInfo( - SnapshotId snapshotId, + Snapshot snapshot, List indices, List dataStreams, List featureStates, @@ -393,7 +403,7 @@ public SnapshotInfo( Map indexSnapshotDetails ) { this( - snapshotId, + snapshot, indices, dataStreams, featureStates, @@ -412,7 +422,7 @@ public SnapshotInfo( } SnapshotInfo( - SnapshotId snapshotId, + Snapshot snapshot, List indices, List dataStreams, List featureStates, @@ -428,7 +438,7 @@ public SnapshotInfo( SnapshotState state, Map indexSnapshotDetails ) { - this.snapshotId = Objects.requireNonNull(snapshotId); + this.snapshot = Objects.requireNonNull(snapshot); this.indices = List.copyOf(indices); this.dataStreams = List.copyOf(dataStreams); this.featureStates = List.copyOf(featureStates); @@ -449,7 +459,12 @@ public SnapshotInfo( * Constructs snapshot information from stream input */ public static SnapshotInfo readFrom(final StreamInput in) throws IOException { - final SnapshotId snapshotId = new SnapshotId(in); + final Snapshot snapshot; + if (in.getVersion().onOrAfter(GetSnapshotsRequest.PAGINATED_GET_SNAPSHOTS_VERSION)) { + snapshot = new Snapshot(in); + } else { + snapshot = new Snapshot(UNKNOWN_REPO_NAME, new SnapshotId(in)); + } final List indices = in.readStringList(); final SnapshotState state = in.readBoolean() ? SnapshotState.fromValue(in.readByte()) : null; final String reason = in.readOptionalString(); @@ -465,7 +480,7 @@ public static SnapshotInfo readFrom(final StreamInput in) throws IOException { final List featureStates = in.readList(SnapshotFeatureInfo::new); final Map indexSnapshotDetails = in.readMap(StreamInput::readString, IndexSnapshotDetails::new); return new SnapshotInfo( - snapshotId, + snapshot, indices, dataStreams, featureStates, @@ -488,7 +503,11 @@ public static SnapshotInfo readFrom(final StreamInput in) throws IOException { * all information stripped out except the snapshot id, state, and indices. */ public SnapshotInfo basic() { - return new SnapshotInfo(snapshotId, indices, Collections.emptyList(), featureStates, state); + return new SnapshotInfo(snapshot, indices, Collections.emptyList(), featureStates, state); + } + + public Snapshot snapshot() { + return snapshot; } /** @@ -497,7 +516,11 @@ public SnapshotInfo basic() { * @return snapshot id */ public SnapshotId snapshotId() { - return snapshotId; + return snapshot.getSnapshotId(); + } + + public String repository() { + return snapshot.getRepository(); } /** @@ -643,8 +666,8 @@ public int compareTo(final SnapshotInfo o) { @Override public String toString() { return "SnapshotInfo{" - + "snapshotId=" - + snapshotId + + "snapshot=" + + snapshot + ", state=" + state + ", reason='" @@ -700,8 +723,14 @@ public XContentBuilder toXContent(final XContentBuilder builder, final Params pa final boolean verbose = params.paramAsBoolean("verbose", GetSnapshotsRequest.DEFAULT_VERBOSE_MODE); // write snapshot info for the API and any other situations builder.startObject(); + final SnapshotId snapshotId = snapshot.getSnapshotId(); builder.field(SNAPSHOT, snapshotId.getName()); builder.field(UUID, snapshotId.getUUID()); + + if (params.paramAsBoolean(INCLUDE_REPOSITORY_XCONTENT_PARAM, true) && UNKNOWN_REPO_NAME.equals(snapshot.getRepository()) == false) { + builder.field(REPOSITORY, snapshot.getRepository()); + } + if (version != null) { builder.field(VERSION_ID, version.id); builder.field(VERSION, version.toString()); @@ -775,6 +804,7 @@ public XContentBuilder toXContent(final XContentBuilder builder, final Params pa private XContentBuilder toXContentInternal(final XContentBuilder builder, final ToXContent.Params params) throws IOException { builder.startObject(SNAPSHOT); + final SnapshotId snapshotId = snapshot.getSnapshotId(); builder.field(NAME, snapshotId.getName()); builder.field(UUID, snapshotId.getUUID()); assert version != null : "version must always be known when writing a snapshot metadata blob"; @@ -830,7 +860,7 @@ private XContentBuilder toXContentInternal(final XContentBuilder builder, final * handle x-content written with the external version as external x-content * is only for display purposes and does not need to be parsed. */ - public static SnapshotInfo fromXContentInternal(final XContentParser parser) throws IOException { + public static SnapshotInfo fromXContentInternal(final String repoName, final XContentParser parser) throws IOException { String name = null; String uuid = null; Version version = Version.CURRENT; @@ -925,7 +955,7 @@ public static SnapshotInfo fromXContentInternal(final XContentParser parser) thr uuid = name; } return new SnapshotInfo( - new SnapshotId(name, uuid), + new Snapshot(repoName, new SnapshotId(name, uuid)), indices, dataStreams, featureStates, @@ -945,7 +975,11 @@ public static SnapshotInfo fromXContentInternal(final XContentParser parser) thr @Override public void writeTo(final StreamOutput out) throws IOException { - snapshotId.writeTo(out); + if (out.getVersion().onOrAfter(GetSnapshotsRequest.PAGINATED_GET_SNAPSHOTS_VERSION)) { + snapshot.writeTo(out); + } else { + snapshot.getSnapshotId().writeTo(out); + } out.writeStringCollection(indices); if (state != null) { out.writeBoolean(true); @@ -994,7 +1028,7 @@ public boolean equals(Object o) { && endTime == that.endTime && totalShards == that.totalShards && successfulShards == that.successfulShards - && Objects.equals(snapshotId, that.snapshotId) + && Objects.equals(snapshot, that.snapshot) && state == that.state && Objects.equals(reason, that.reason) && Objects.equals(indices, that.indices) @@ -1010,7 +1044,7 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( - snapshotId, + snapshot, state, reason, indices, diff --git a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java index 82a33e33dd9e7..ebdff87ee533d 100644 --- a/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java +++ b/server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java @@ -1479,7 +1479,7 @@ private void finalizeSnapshotEntry(SnapshotsInProgress.Entry entry, Metadata met indexSnapshotDetails.entrySet().removeIf(e -> e.getValue().getShardCount() == 0); final SnapshotInfo snapshotInfo = new SnapshotInfo( - snapshot.getSnapshotId(), + snapshot, finalIndices, entry.dataStreams().stream().filter(metaForSnapshot.dataStreams()::containsKey).collect(Collectors.toList()), entry.partial() ? onlySuccessfulFeatureStates(entry, finalIndices) : entry.featureStates(), diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java index cc4d15de094c6..5717def040458 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotResponseTests.java @@ -10,6 +10,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotFeatureInfo; import org.elasticsearch.snapshots.SnapshotFeatureInfoTests; import org.elasticsearch.snapshots.SnapshotId; @@ -67,7 +68,7 @@ protected CreateSnapshotResponse createTestInstance() { return new CreateSnapshotResponse( new SnapshotInfo( - snapshotId, + new Snapshot("test-repo", snapshotId), indices, dataStreams, featureStates, 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 4e81a52e0851a..3dc91f09f1449 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 @@ -16,6 +16,7 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotFeatureInfo; import org.elasticsearch.snapshots.SnapshotFeatureInfoTests; import org.elasticsearch.snapshots.SnapshotId; @@ -28,6 +29,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -62,16 +64,16 @@ private GetSnapshotsResponse copyInstance(GetSnapshotsResponse instance) throws } 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()) { + assertEquals(expectedInstance.getSnapshots(), newInstance.getSnapshots()); + assertEquals(expectedInstance.getFailures().keySet(), newInstance.getFailures().keySet()); + for (Map.Entry expectedEntry : expectedInstance.getFailures().entrySet()) { ElasticsearchException expectedException = expectedEntry.getValue(); - ElasticsearchException newException = newInstance.getFailedResponses().get(expectedEntry.getKey()); + ElasticsearchException newException = newInstance.getFailures().get(expectedEntry.getKey()); assertThat(newException.getMessage(), containsString(expectedException.getMessage())); } } - private List createSnapshotInfos() { + private List createSnapshotInfos(String repoName) { ArrayList snapshots = new ArrayList<>(); final int targetSize = between(5, 10); for (int i = 0; i < targetSize; ++i) { @@ -82,7 +84,7 @@ private List createSnapshotInfos() { List featureInfos = randomList(5, SnapshotFeatureInfoTests::randomSnapshotFeatureInfo); snapshots.add( new SnapshotInfo( - snapshotId, + new Snapshot(repoName, snapshotId), Arrays.asList("index1", "index2"), Collections.singletonList("ds"), featureInfos, @@ -102,21 +104,22 @@ private List createSnapshotInfos() { private GetSnapshotsResponse createTestInstance() { Set repositories = new HashSet<>(); - List responses = new ArrayList<>(); + Map failures = new HashMap<>(); + List responses = new ArrayList<>(); for (int i = 0; i < randomIntBetween(0, 5); i++) { String repository = randomValueOtherThanMany(repositories::contains, () -> randomAlphaOfLength(10)); repositories.add(repository); - responses.add(GetSnapshotsResponse.Response.snapshots(repository, createSnapshotInfos())); + responses.addAll(createSnapshotInfos(repository)); } for (int i = 0; i < randomIntBetween(0, 5); i++) { String repository = randomValueOtherThanMany(repositories::contains, () -> randomAlphaOfLength(10)); repositories.add(repository); - responses.add(GetSnapshotsResponse.Response.error(repository, new ElasticsearchException(randomAlphaOfLength(10)))); + failures.put(repository, new ElasticsearchException(randomAlphaOfLength(10))); } - return new GetSnapshotsResponse(responses); + return new GetSnapshotsResponse(responses, failures); } public void testSerialization() throws IOException { @@ -139,10 +142,11 @@ public void testFromXContent() throws IOException { // are required to be a valid IndexSnapshotDetails // // The actual fields are nested in an array, so this regex matches fields with names of the form - // `responses.0.snapshots.3.metadata` - final Predicate predicate = Pattern.compile("responses\\.\\d+\\.snapshots\\.\\d+\\.metadata.*") + // `snapshots.3.metadata` + final Predicate predicate = Pattern.compile("snapshots\\.\\d+\\.metadata.*") .asMatchPredicate() - .or(Pattern.compile("responses\\.\\d+\\.snapshots\\.\\d+\\.index_details").asMatchPredicate()); + .or(Pattern.compile("snapshots\\.\\d+\\.index_details").asMatchPredicate()) + .or(Pattern.compile("failures\\.*").asMatchPredicate()); xContentTester(this::createParser, this::createTestInstance, params, this::doParseInstance).numberOfTestRuns(1) .supportsUnknownFields(true) .shuffleFieldsExceptions(Strings.EMPTY_ARRAY) diff --git a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryRestoreTests.java b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryRestoreTests.java index 8c8b81a5b7468..4341af98b2d9b 100644 --- a/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryRestoreTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/blobstore/BlobStoreRepositoryRestoreTests.java @@ -177,7 +177,7 @@ public void testSnapshotWithConflictingName() throws Exception { RepositoryData.EMPTY_REPO_GEN, Metadata.builder().put(shard.indexSettings().getIndexMetadata(), false).build(), new SnapshotInfo( - snapshot.getSnapshotId(), + snapshot, shardGenerations.indices().stream().map(IndexId::getName).collect(Collectors.toList()), Collections.emptyList(), Collections.emptyList(), diff --git a/server/src/test/java/org/elasticsearch/snapshots/BlobStoreFormatTests.java b/server/src/test/java/org/elasticsearch/snapshots/BlobStoreFormatTests.java index e0d6203e20628..57aba7691e8c0 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/BlobStoreFormatTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/BlobStoreFormatTests.java @@ -78,7 +78,11 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par public void testBlobStoreOperations() throws IOException { BlobStore blobStore = createTestBlobStore(); BlobContainer blobContainer = blobStore.blobContainer(BlobPath.EMPTY); - ChecksumBlobStoreFormat checksumSMILE = new ChecksumBlobStoreFormat<>(BLOB_CODEC, "%s", BlobObj::fromXContent); + ChecksumBlobStoreFormat checksumSMILE = new ChecksumBlobStoreFormat<>( + BLOB_CODEC, + "%s", + (repoName, parser) -> BlobObj.fromXContent(parser) + ); // Write blobs in different formats final String randomText = randomAlphaOfLengthBetween(0, 1024 * 8 * 3); @@ -88,8 +92,8 @@ public void testBlobStoreOperations() throws IOException { checksumSMILE.write(new BlobObj(compressedText), blobContainer, "check-smile-comp", true, MockBigArrays.NON_RECYCLING_INSTANCE); // Assert that all checksum blobs can be read - assertEquals(normalText, checksumSMILE.read(blobContainer, "check-smile", xContentRegistry()).getText()); - assertEquals(compressedText, checksumSMILE.read(blobContainer, "check-smile-comp", xContentRegistry()).getText()); + assertEquals(normalText, checksumSMILE.read("repo", blobContainer, "check-smile", xContentRegistry()).getText()); + assertEquals(compressedText, checksumSMILE.read("repo", blobContainer, "check-smile-comp", xContentRegistry()).getText()); } public void testCompressionIsApplied() throws IOException { @@ -99,7 +103,11 @@ public void testCompressionIsApplied() throws IOException { for (int i = 0; i < randomIntBetween(100, 300); i++) { veryRedundantText.append("Blah "); } - ChecksumBlobStoreFormat checksumFormat = new ChecksumBlobStoreFormat<>(BLOB_CODEC, "%s", BlobObj::fromXContent); + ChecksumBlobStoreFormat checksumFormat = new ChecksumBlobStoreFormat<>( + BLOB_CODEC, + "%s", + (repo, parser) -> BlobObj.fromXContent(parser) + ); BlobObj blobObj = new BlobObj(veryRedundantText.toString()); checksumFormat.write(blobObj, blobContainer, "blob-comp", true, MockBigArrays.NON_RECYCLING_INSTANCE); checksumFormat.write(blobObj, blobContainer, "blob-not-comp", false, MockBigArrays.NON_RECYCLING_INSTANCE); @@ -113,12 +121,16 @@ public void testBlobCorruption() throws IOException { BlobContainer blobContainer = blobStore.blobContainer(BlobPath.EMPTY); String testString = randomAlphaOfLength(randomInt(10000)); BlobObj blobObj = new BlobObj(testString); - ChecksumBlobStoreFormat checksumFormat = new ChecksumBlobStoreFormat<>(BLOB_CODEC, "%s", BlobObj::fromXContent); + ChecksumBlobStoreFormat checksumFormat = new ChecksumBlobStoreFormat<>( + BLOB_CODEC, + "%s", + (repo, parser) -> BlobObj.fromXContent(parser) + ); checksumFormat.write(blobObj, blobContainer, "test-path", randomBoolean(), MockBigArrays.NON_RECYCLING_INSTANCE); - assertEquals(checksumFormat.read(blobContainer, "test-path", xContentRegistry()).getText(), testString); + assertEquals(checksumFormat.read("repo", blobContainer, "test-path", xContentRegistry()).getText(), testString); randomCorruption(blobContainer, "test-path"); try { - checksumFormat.read(blobContainer, "test-path", xContentRegistry()); + checksumFormat.read("repo", blobContainer, "test-path", xContentRegistry()); fail("Should have failed due to corruption"); } catch (ElasticsearchCorruptionException | EOFException ex) { // expected exceptions from random byte corruption diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoBlobSerializationTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoBlobSerializationTests.java index a0e489228a053..6d1073e14dfb7 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoBlobSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoBlobSerializationTests.java @@ -40,7 +40,11 @@ protected SnapshotInfo copyInstance(SnapshotInfo instance, Version version) thro BigArrays.NON_RECYCLING_INSTANCE, bytes -> ActionListener.completeWith( future, - () -> BlobStoreRepository.SNAPSHOT_FORMAT.deserialize(NamedXContentRegistry.EMPTY, bytes.streamInput()) + () -> BlobStoreRepository.SNAPSHOT_FORMAT.deserialize( + instance.repository(), + NamedXContentRegistry.EMPTY, + bytes.streamInput() + ) ) ); return future.actionGet(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoTestUtils.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoTestUtils.java index ce79151c90537..1824f0f2dcfdb 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoTestUtils.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotInfoTestUtils.java @@ -35,7 +35,7 @@ public class SnapshotInfoTestUtils { private SnapshotInfoTestUtils() {} static SnapshotInfo createRandomSnapshotInfo() { - final SnapshotId snapshotId = new SnapshotId(randomAlphaOfLength(5), randomAlphaOfLength(5)); + final Snapshot snapshot = new Snapshot(randomAlphaOfLength(5), new SnapshotId(randomAlphaOfLength(5), randomAlphaOfLength(5))); final List indices = Arrays.asList(randomArray(1, 10, String[]::new, () -> randomAlphaOfLengthBetween(2, 20))); final List dataStreams = Arrays.asList(randomArray(1, 10, String[]::new, () -> randomAlphaOfLengthBetween(2, 20))); @@ -57,7 +57,7 @@ static SnapshotInfo createRandomSnapshotInfo() { final Map indexSnapshotDetails = randomIndexSnapshotDetails(); return new SnapshotInfo( - snapshotId, + snapshot, indices, dataStreams, snapshotFeatureInfos, @@ -142,8 +142,9 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { final SnapshotId snapshotId = randomBoolean() ? new SnapshotId(instance.snapshotId().getName(), newUuid) : new SnapshotId(newName, instance.snapshotId().getUUID()); + final String repo = randomBoolean() ? instance.repository() : randomAlphaOfLength(5); return new SnapshotInfo( - snapshotId, + new Snapshot(repo, snapshotId), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -162,7 +163,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { randomArray(indicesSize, indicesSize, String[]::new, () -> randomAlphaOfLengthBetween(2, 20)) ); return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), indices, instance.dataStreams(), instance.featureStates(), @@ -177,7 +178,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 2: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -192,7 +193,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 3: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -207,7 +208,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 4: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -224,7 +225,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { final int totalShards = randomValueOtherThan(instance.totalShards(), () -> randomIntBetween(0, 100)); final List shardFailures = randomShardFailures(randomIntBetween(0, totalShards)); return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -239,7 +240,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 6: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -254,7 +255,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 7: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), @@ -273,7 +274,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { () -> Arrays.asList(randomArray(0, 10, String[]::new, () -> randomAlphaOfLengthBetween(2, 20))) ); return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), dataStreams, instance.featureStates(), @@ -288,7 +289,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 9: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), randomValueOtherThan(instance.featureStates(), SnapshotInfoTestUtils::randomSnapshotFeatureInfos), @@ -303,7 +304,7 @@ static SnapshotInfo mutateSnapshotInfo(SnapshotInfo instance) { ); case 10: return new SnapshotInfo( - instance.snapshotId(), + instance.snapshot(), instance.indices(), instance.dataStreams(), instance.featureStates(), 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 e13ca1c4944ea..dad817a3f5655 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -112,7 +112,7 @@ public void testCreateSnapshot() { .prepareGetSnapshots("test-repo") .setSnapshots(snapshotName) .get() - .getSnapshots("test-repo") + .getSnapshots() .get(0) .state(), equalTo(SnapshotState.SUCCESS)); @@ -184,7 +184,7 @@ public void testCleanup() throws Exception { .prepareGetSnapshots("test-repo") .setSnapshots(snapshotName) .get() - .getSnapshots("test-repo") + .getSnapshots() .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 aa0220cd6de91..0ac286dcfe899 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 @@ -346,7 +346,7 @@ protected void testSnapshotAndRestore(boolean recreateRepositoryBeforeRestore) t assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); + client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).execute().actionGet()); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); diff --git a/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java index bbc5932807634..80eb6279c92df 100644 --- a/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java @@ -372,6 +372,7 @@ protected String initWithSnapshotVersion(String repoName, Path repoPath, Version downgradedRepoData.snapshotsToXContent(XContentFactory.jsonBuilder(), version))), StandardOpenOption.TRUNCATE_EXISTING); final SnapshotInfo downgradedSnapshotInfo = SnapshotInfo.fromXContentInternal( + repoName, JsonXContent.jsonXContent.createParser( NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, @@ -459,7 +460,7 @@ protected void addBwCFailedSnapshot(String repoName, String snapshotName, Map adding old version FAILED snapshot [{}] to repository [{}]", snapshotId, repoName); final SnapshotInfo snapshotInfo = new SnapshotInfo( - snapshotId, + new Snapshot(repoName, snapshotId), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), @@ -625,7 +626,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS protected SnapshotInfo getSnapshot(String repository, String snapshot) { final List snapshotInfos = clusterAdmin().prepareGetSnapshots(repository).setSnapshots(snapshot) - .get().getSnapshots(repository); + .get().getSnapshots(); assertThat(snapshotInfos, hasSize(1)); return snapshotInfos.get(0); } @@ -666,7 +667,7 @@ public static List createNSnapshots(Logger logger, String repoName, int clusterAdmin().prepareGetSnapshots(repoName) .setSnapshots(snapshot) .execute(l.delegateFailure((ll, getResponse) -> { - assertEquals(snapshotInfoInResponse, getResponse.getSnapshots(repoName).get(0)); + assertEquals(snapshotInfoInResponse, getResponse.getSnapshots().get(0)); ll.onResponse(response); })); })); diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java index a62226775bddb..8a146aefe42fd 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/repository/CcrRepository.java @@ -72,6 +72,7 @@ import org.elasticsearch.repositories.ShardSnapshotResult; import org.elasticsearch.repositories.SnapshotShardContext; import org.elasticsearch.repositories.blobstore.FileRestoreContext; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotState; @@ -188,7 +189,7 @@ public void getSnapshotInfo(GetSnapshotInfoContext context) { // fork to the snapshot meta pool because the context expects to run on it and asserts that it does threadPool.executor(ThreadPool.Names.SNAPSHOT_META).execute(() -> context.onResponse( new SnapshotInfo( - SNAPSHOT_ID, + new Snapshot(this.metadata.name(), SNAPSHOT_ID), indices, new ArrayList<>(metadata.dataStreams().keySet()), Collections.emptyList(), diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotShardTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotShardTests.java index a6694b6040f59..cf224e3582ce1 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotShardTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/snapshots/sourceonly/SourceOnlySnapshotShardTests.java @@ -233,7 +233,7 @@ public void testRestoreMinmal() throws IOException { ESBlobStoreRepositoryIntegTestCase.getRepositoryData(repository).getGenId(), Metadata.builder().put(shard.indexSettings().getIndexMetadata(), false).build(), new SnapshotInfo( - snapshotId, + new Snapshot(repository.getMetadata().name(), snapshotId), shardGenerations.indices().stream() .map(IndexId::getName).collect(Collectors.toList()), Collections.emptyList(), diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotRetentionConfigurationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotRetentionConfigurationTests.java index 7fd8468d3129e..d432e23452d49 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotRetentionConfigurationTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/slm/SnapshotRetentionConfigurationTests.java @@ -9,6 +9,7 @@ import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotShardFailure; @@ -286,7 +287,7 @@ private SnapshotInfo makeInfo(long startTime) { meta.put(SnapshotLifecyclePolicy.POLICY_ID_METADATA_FIELD, REPO); final int totalShards = between(1,20); SnapshotInfo snapInfo = new SnapshotInfo( - new SnapshotId("snap-" + randomAlphaOfLength(3), "uuid"), + new Snapshot(REPO, new SnapshotId("snap-" + randomAlphaOfLength(3), "uuid")), Collections.singletonList("foo"), Collections.singletonList("bar"), Collections.emptyList(), @@ -322,7 +323,7 @@ private SnapshotInfo makeFailureInfo(long startTime) { } assert failureCount == failures.size(); SnapshotInfo snapInfo = new SnapshotInfo( - new SnapshotId("snap-fail-" + randomAlphaOfLength(3), "uuid-fail"), + new Snapshot(REPO, new SnapshotId("snap-fail-" + randomAlphaOfLength(3), "uuid-fail")), Collections.singletonList("foo-fail"), Collections.singletonList("bar-fail"), Collections.emptyList(), @@ -350,7 +351,7 @@ private SnapshotInfo makePartialInfo(long startTime) { } assert failureCount == failures.size(); SnapshotInfo snapInfo = new SnapshotInfo( - new SnapshotId("snap-fail-" + randomAlphaOfLength(3), "uuid-fail"), + new Snapshot(REPO, new SnapshotId("snap-fail-" + randomAlphaOfLength(3), "uuid-fail")), Collections.singletonList("foo-fail"), Collections.singletonList("bar-fail"), Collections.emptyList(), diff --git a/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/ilm/CCRIndexLifecycleIT.java b/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/ilm/CCRIndexLifecycleIT.java index ffa6f46dab47a..a0460f0318bd2 100644 --- a/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/ilm/CCRIndexLifecycleIT.java +++ b/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/ilm/CCRIndexLifecycleIT.java @@ -800,8 +800,7 @@ private String getSnapshotState(String snapshot) throws IOException { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - Map repoResponse = ((List>) responseMap.get("responses")).get(0); - Map snapResponse = ((List>) repoResponse.get("snapshots")).get(0); + Map snapResponse = ((List>) responseMap.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/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java index d59ea623935ab..d00e52a13f3d8 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java @@ -326,8 +326,7 @@ public static String getSnapshotState(RestClient client, String snapshot) throws responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - Map repoResponse = ((List>) responseMap.get("responses")).get(0); - Map snapResponse = ((List>) repoResponse.get("snapshots")).get(0); + Map snapResponse = ((List>) responseMap.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/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 97da6dccf30bc..ced6944003050 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -883,18 +883,14 @@ public void testDeleteActionDoesntDeleteSearchableSnapshot() throws Exception { try (InputStream is = getSnapshotsResponse.getEntity().getContent()) { snapshotsResponseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - ArrayList responses = (ArrayList) snapshotsResponseMap.get("responses"); - for (Object response : responses) { - Map responseAsMap = (Map) response; - if (responseAsMap.get("snapshots") != null) { - ArrayList snapshots = (ArrayList) responseAsMap.get("snapshots"); - for (Object snapshot : snapshots) { - Map snapshotInfoMap = (Map) snapshot; - if (snapshotInfoMap.get("snapshot").equals(snapshotName[0]) && + if (snapshotsResponseMap.get("snapshots") != null) { + ArrayList snapshots = (ArrayList) snapshotsResponseMap.get("snapshots"); + for (Object snapshot : snapshots) { + Map snapshotInfoMap = (Map) snapshot; + if (snapshotInfoMap.get("snapshot").equals(snapshotName[0]) && // wait for the snapshot to be completed (successfully or not) otherwise the teardown might fail SnapshotState.valueOf((String) snapshotInfoMap.get("state")).completed()) { - return true; - } + return true; } } } diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java index 0ec97e815128d..a4fd849a7886a 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/actions/SearchableSnapshotActionIT.java @@ -205,8 +205,7 @@ public void testDeleteActionDeletesSearchableSnapshot() throws Exception { try (InputStream is = getSnapshotsResponse.getEntity().getContent()) { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - List responses = (List) responseMap.get("responses"); - Object snapshots = ((Map) responses.get(0)).get("snapshots"); + Object snapshots = responseMap.get("snapshots"); return ((List>) snapshots).size() == 0; } catch (Exception e) { logger.error(e.getMessage(), e); @@ -401,9 +400,7 @@ public void testIdenticalSearchableSnapshotActionIsNoop() throws Exception { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } assertThat("expected to have only one snapshot, but got: " + responseMap, - ((List>) - ((Map) - ((List) responseMap.get("responses")).get(0)).get("snapshots")).size(), equalTo(1)); + ((List>) responseMap.get("snapshots")).size(), equalTo(1)); Request hitCount = new Request("GET", "/" + searchableSnapMountedIndexName + "/_count"); Map count = entityAsMap(client().performRequest(hitCount)); @@ -451,9 +448,7 @@ public void testConvertingSearchableSnapshotFromFullToPartial() throws Exception responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } assertThat("expected to have only one snapshot, but got: " + responseMap, - ((List>) - ((Map) - ((List) responseMap.get("responses")).get(0)).get("snapshots")).size(), equalTo(1)); + ((List>) responseMap.get("snapshots")).size(), equalTo(1)); Request hitCount = new Request("GET", "/" + searchableSnapMountedIndexName + "/_count"); Map count = entityAsMap(client().performRequest(hitCount)); diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/slm/SnapshotLifecycleRestIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/slm/SnapshotLifecycleRestIT.java index 78cb1b92cb769..1f366664188d1 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/slm/SnapshotLifecycleRestIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/slm/SnapshotLifecycleRestIT.java @@ -46,10 +46,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.Function; -import java.util.function.Predicate; import java.util.stream.Collectors; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; @@ -60,9 +58,11 @@ import static org.elasticsearch.xpack.core.slm.history.SnapshotHistoryStore.SLM_HISTORY_DATA_STREAM; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; public class SnapshotLifecycleRestIT extends ESRestTestCase { @@ -115,11 +115,6 @@ public void testFullPolicySnapshot() throws Exception { createSnapshotPolicy(policyName, "snap", "*/1 * * * * ?", repoId, indexName, true); - // A test for whether the repository's snapshots have any snapshots starting with "snap-" - Predicate> repoHasSnapshot = snapMap -> Optional.ofNullable((String) snapMap.get("snapshot")) - .map(snapName -> snapName.startsWith("snap-")) - .orElse(false); - // Check that the snapshot was actually taken assertBusy(() -> { Response response = client().performRequest(new Request("GET", "/_snapshot/" + repoId + "/_all")); @@ -128,15 +123,10 @@ public void testFullPolicySnapshot() throws Exception { snapshotResponseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } assertThat(snapshotResponseMap.size(), greaterThan(0)); - List> snapResponse = ((List>) snapshotResponseMap.get("responses")).stream() - .peek(m -> logger.info("--> responses: {}", m)) - .map(m -> (List>) m.get("snapshots")) - .peek(allReposSnapshots -> logger.info("--> all repository's snapshots: {}", allReposSnapshots)) - .filter(allReposSnapshots -> allReposSnapshots.stream().anyMatch(repoHasSnapshot)) - .peek(allRepos -> logger.info("--> snapshots with 'snap-' snapshot: {}", allRepos)) - .findFirst() - .orElseThrow(() -> new AssertionError("failed to find snapshot response in " + snapshotResponseMap)); + List> snapResponse = ((List>) snapshotResponseMap.get("snapshots")); + assertThat(snapResponse, not(empty())); assertThat(snapResponse.get(0).get("indices"), equalTo(Collections.singletonList(indexName))); + assertThat((String) snapResponse.get(0).get("snapshot"), startsWith("snap-")); Map metadata = (Map) snapResponse.get(0).get("metadata"); assertNotNull(metadata); assertThat(metadata.get("policy"), equalTo(policyName)); @@ -607,10 +597,7 @@ private static Map extractMetadata(Map snapshotR @SuppressWarnings("unchecked") private static Map extractSnapshot(Map snapshotResponseMap, String snapshotPrefix) { - List> snapResponse = ((List>) snapshotResponseMap.get("responses")).stream() - .findFirst() - .map(m -> (List>) m.get("snapshots")) - .orElseThrow(() -> new AssertionError("failed to find snapshot response in " + snapshotResponseMap)); + List> snapResponse = ((List>) snapshotResponseMap.get("snapshots")); return snapResponse.stream() .filter(snapshot -> ((String) snapshot.get("snapshot")).startsWith(snapshotPrefix)) .findFirst() diff --git a/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java b/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java index c64ade49a2a5d..1bebd70b4ad7f 100644 --- a/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java +++ b/x-pack/plugin/ilm/qa/with-security/src/javaRestTest/java/org/elasticsearch/xpack/security/PermissionsIT.java @@ -237,7 +237,7 @@ public void testSLMWithPermissions() throws Exception { GetSnapshotsRequest getSnaps = new GetSnapshotsRequest(repo); getSnaps.snapshots(new String[]{snapName}); GetSnapshotsResponse getResp = adminHLRC.snapshot().get(getSnaps, RequestOptions.DEFAULT); - assertThat(getResp.getSnapshots(repo).get(0).state(), equalTo(SnapshotState.SUCCESS)); + assertThat(getResp.getSnapshots().get(0).state(), equalTo(SnapshotState.SUCCESS)); } catch (ElasticsearchException e) { fail("expected snapshot to exist but it does not: " + e.getDetailedMessage()); } @@ -257,7 +257,7 @@ public void testSLMWithPermissions() throws Exception { GetSnapshotsRequest getSnaps = new GetSnapshotsRequest(repo); getSnaps.snapshots(new String[]{snapName}); GetSnapshotsResponse getResp = adminHLRC.snapshot().get(getSnaps, RequestOptions.DEFAULT); - assertThat(getResp.getSnapshots(repo).size(), equalTo(0)); + assertThat(getResp.getSnapshots().size(), equalTo(0)); } catch (ElasticsearchException e) { // great, we want it to not exist assertThat(e.getDetailedMessage(), containsString("snapshot_missing_exception")); diff --git a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java index ded4c31f9109b..9fcb487f202aa 100644 --- a/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java +++ b/x-pack/plugin/ilm/src/internalClusterTest/java/org/elasticsearch/xpack/slm/SLMSnapshotBlockingIntegTests.java @@ -332,7 +332,7 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex try { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots(REPO).setSnapshots(failedSnapshotName.get()).get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(REPO).get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertEquals(expectedUnsuccessfulState, snapshotInfo.state()); } catch (SnapshotMissingException ex) { logger.info("failed to find snapshot {}, retrying", failedSnapshotName); @@ -367,11 +367,11 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex assertNotNull(successfulSnapshotName.get()); logger.info("--> verify that snapshot [{}] succeeded", successfulSnapshotName.get()); assertBusy(() -> { - GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() - .prepareGetSnapshots(REPO).setSnapshots(successfulSnapshotName.get()).execute().get(); final SnapshotInfo snapshotInfo; try { - snapshotInfo = snapshotsStatusResponse.getSnapshots(REPO).get(0); + GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() + .prepareGetSnapshots(REPO).setSnapshots(successfulSnapshotName.get()).execute().actionGet(); + snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); } catch (SnapshotMissingException sme) { throw new AssertionError(sme); } @@ -384,7 +384,7 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex logger.info("--> verify that snapshot [{}] still exists", failedSnapshotName.get()); GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots(REPO).setSnapshots(failedSnapshotName.get()).get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(REPO).get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertEquals(expectedUnsuccessfulState, snapshotInfo.state()); } @@ -397,7 +397,7 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex try { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots(REPO).setSnapshots(failedSnapshotName.get()).get(); - assertThat(snapshotsStatusResponse.getSnapshots(REPO), empty()); + assertThat(snapshotsStatusResponse.getSnapshots(), empty()); } catch (SnapshotMissingException e) { // This is what we want to happen } @@ -405,7 +405,7 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex expectedUnsuccessfulState, failedSnapshotName.get(), successfulSnapshotName.get()); GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots(REPO).setSnapshots(successfulSnapshotName.get()).get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(REPO).get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); }, 30L, TimeUnit.SECONDS); } @@ -453,7 +453,7 @@ public void testSLMRetentionAfterRestore() throws Exception { try { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots(REPO).setSnapshots(snapshotName).get(); - assertThat(snapshotsStatusResponse.getSnapshots(REPO), empty()); + assertThat(snapshotsStatusResponse.getSnapshots(), empty()); } catch (SnapshotMissingException e) { // This is what we want to happen } diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java index 7922008fa201e..837f05344faa9 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SnapshotRetentionTask.java @@ -249,16 +249,20 @@ void getAllRetainableSnapshots(Collection repositories, ActionListener resp.getSnapshots(repo).stream().map(si -> si.snapshotId().getName())) - .collect(Collectors.toList())); + .flatMap(repo -> + resp.getSnapshots() + .stream() + .filter(info -> repo.equals(info.repository())) + .map(si -> si.snapshotId().getName()) + ).collect(Collectors.toList())); } Map> snapshots = new HashMap<>(); final Set retainableStates = Set.of(SnapshotState.SUCCESS, SnapshotState.FAILED, SnapshotState.PARTIAL); repositories.forEach(repo -> { snapshots.put(repo, // Only return snapshots in the SUCCESS state - resp.getSnapshots(repo).stream() - .filter(info -> retainableStates.contains(info.state())) + resp.getSnapshots().stream() + .filter(info -> repo.equals(info.repository()) && retainableStates.contains(info.state())) .collect(Collectors.toList())); }); listener.onResponse(snapshots); diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotLifecycleTaskTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotLifecycleTaskTests.java index 66e86b628fc56..baf7ed3ccdf75 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotLifecycleTaskTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotLifecycleTaskTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotShardFailure; @@ -242,7 +243,7 @@ public void testPartialFailureSnapshot() throws Exception { long endTime = randomLongBetween(startTime, Long.MAX_VALUE); return new CreateSnapshotResponse( new SnapshotInfo( - new SnapshotId(req.snapshot(), "uuid"), + new Snapshot(req.repository(), new SnapshotId(req.snapshot(), "uuid")), Arrays.asList(req.indices()), Collections.emptyList(), Collections.emptyList(), "snapshot started", endTime, 3, Collections.singletonList( diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java index 5a397fcab44b3..6ceb431542d87 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/slm/SnapshotRetentionTaskTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.core.TimeValue; +import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.test.ClusterServiceUtils; @@ -100,18 +101,19 @@ public void testGetAllPoliciesWithRetentionEnabled() { } public void testSnapshotEligibleForDeletion() { + final String repoName = "repo"; SnapshotLifecyclePolicy policy = new SnapshotLifecyclePolicy("policy", "snap", "1 * * * * ?", - "repo", null, new SnapshotRetentionConfiguration(TimeValue.timeValueDays(30), null, null)); + repoName, null, new SnapshotRetentionConfiguration(TimeValue.timeValueDays(30), null, null)); SnapshotLifecyclePolicy policyWithNoRetention = new SnapshotLifecyclePolicy("policy", "snap", "1 * * * * ?", - "repo", null, randomBoolean() ? null : SnapshotRetentionConfiguration.EMPTY); + repoName, null, randomBoolean() ? null : SnapshotRetentionConfiguration.EMPTY); Map policyMap = Collections.singletonMap("policy", policy); Map policyWithNoRetentionMap = Collections.singletonMap("policy", policyWithNoRetention); Function>> mkInfos = i -> - Collections.singletonMap("repo", Collections.singletonList(i)); + Collections.singletonMap(repoName, Collections.singletonList(i)); // Test when user metadata is null SnapshotInfo info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -127,7 +129,7 @@ public void testSnapshotEligibleForDeletion() { // Test when no retention is configured info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -143,7 +145,7 @@ public void testSnapshotEligibleForDeletion() { // Test when user metadata is a map that doesn't contain "policy" info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -159,7 +161,7 @@ public void testSnapshotEligibleForDeletion() { // Test with an ancient snapshot that should be expunged info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -176,7 +178,7 @@ public void testSnapshotEligibleForDeletion() { // Test with a snapshot that's start date is old enough to be expunged (but the finish date is not) long time = System.currentTimeMillis() - TimeValue.timeValueDays(30).millis() - 1; info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -192,7 +194,7 @@ public void testSnapshotEligibleForDeletion() { // Test with a fresh snapshot that should not be expunged info = new SnapshotInfo( - new SnapshotId("name", "uuid"), + new Snapshot(repoName, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -228,11 +230,12 @@ private void retentionTaskTest(final boolean deletionSuccess) throws Exception { ClusterState state = createState(policy); ClusterServiceUtils.setState(clusterService, state); - final SnapshotInfo eligibleSnapshot = new SnapshotInfo(new SnapshotId("name", "uuid"), Collections.singletonList("index"), + final SnapshotInfo eligibleSnapshot = new SnapshotInfo( + new Snapshot(repoId, new SnapshotId("name", "uuid")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), null, 1L, 1, Collections.emptyList(), true, Collections.singletonMap("policy", policyId), 0L, Collections.emptyMap()); final SnapshotInfo ineligibleSnapshot = new SnapshotInfo( - new SnapshotId("name2", "uuid2"), + new Snapshot(repoId, new SnapshotId("name2", "uuid2")), Collections.singletonList("index"), Collections.emptyList(), Collections.emptyList(), @@ -313,8 +316,7 @@ public void testErrStillRunsFailureHandlerWhenRetrieving() throws Exception { void doExecute(ActionType action, Request request, ActionListener listener) { if (request instanceof GetSnapshotsRequest) { logger.info("--> called"); - listener.onResponse((Response) new GetSnapshotsResponse( - Collections.singleton(GetSnapshotsResponse.Response.snapshots(repoId, Collections.emptyList())))); + listener.onResponse((Response) new GetSnapshotsResponse(Collections.emptyList(), Collections.emptyMap())); } else { super.doExecute(action, request, listener); } diff --git a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java index 6710b433c69ac..dd85c619d580c 100644 --- a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java +++ b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java @@ -51,10 +51,10 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; @@ -594,13 +594,8 @@ public void testWrongRepositoryPassword() throws Exception { () -> client().admin().cluster().prepareCreateSnapshot(repositoryName, snapshotName + "2").setWaitForCompletion(true).get() ); assertThat(e.getCause().getMessage(), containsString("repository password is incorrect")); - GetSnapshotsResponse getSnapshotResponse = client().admin().cluster().prepareGetSnapshots(repositoryName).get(); - assertThat(getSnapshotResponse.getSuccessfulResponses().keySet(), empty()); - assertThat(getSnapshotResponse.getFailedResponses().keySet(), contains(repositoryName)); - assertThat( - getSnapshotResponse.getFailedResponses().get(repositoryName).getCause().getMessage(), - containsString("repository password is incorrect") - ); + e = expectThrows(RepositoryException.class, () -> client().admin().cluster().prepareGetSnapshots(repositoryName).get()); + assertThat(e.getCause().getMessage(), containsString("repository password is incorrect")); e = expectThrows( RepositoryException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repositoryName, snapshotName).setWaitForCompletion(true).get() @@ -619,9 +614,8 @@ public void testWrongRepositoryPassword() throws Exception { internalCluster().fullRestart(); ensureGreen(); // ensure get snapshot works - getSnapshotResponse = client().admin().cluster().prepareGetSnapshots(repositoryName).get(); - assertThat(getSnapshotResponse.getFailedResponses().keySet(), empty()); - assertThat(getSnapshotResponse.getSuccessfulResponses().keySet(), contains(repositoryName)); + GetSnapshotsResponse getSnapshotResponse = client().admin().cluster().prepareGetSnapshots(repositoryName).get(); + assertThat(getSnapshotResponse.getSnapshots(), hasSize(1)); } public void testSnapshotFailsForMasterFailoverWithWrongPassword() throws Exception { @@ -769,7 +763,7 @@ public SnapshotInfo waitForCompletion(String repository, String snapshotName, Ti .prepareGetSnapshots(repository) .setSnapshots(snapshotName) .get() - .getSnapshots(repository); + .getSnapshots(); assertThat(snapshotInfos.size(), equalTo(1)); if (snapshotInfos.get(0).state().completed()) { // Make sure that snapshot clean up operations are finished diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 996d7495f72aa..fef193edfe410 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -89,9 +89,9 @@ 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("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, + 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)); } diff --git a/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java b/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java index 3e1e3cc961159..6a6593531aa2a 100644 --- a/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java +++ b/x-pack/plugin/voting-only-node/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/votingonly/VotingOnlyNodePluginTests.java @@ -239,7 +239,7 @@ public void testBasicSnapshotRestoreWorkFlow() { .prepareGetSnapshots("test-repo") .setSnapshots(randomFrom("test-snap", "_all", "*", "*-snap", "test*")) .get() - .getSnapshots("test-repo"); + .getSnapshots(); assertThat(snapshotInfos.size(), Matchers.equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), Matchers.equalTo(SnapshotState.SUCCESS));