Skip to content

Commit 9ac81a1

Browse files
authored
Add Get Snapshots High Level REST API (#31537)
With this commit we add the get snapshots API to the Java high level REST client. Relates #27205
1 parent d0c276c commit 9ac81a1

File tree

11 files changed

+497
-96
lines changed

11 files changed

+497
-96
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
3939
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
4040
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
41+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
4142
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
4243
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4344
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
@@ -894,6 +895,26 @@ static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) throw
894895
return request;
895896
}
896897

898+
static Request getSnapshots(GetSnapshotsRequest getSnapshotsRequest) {
899+
EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPartAsIs("_snapshot")
900+
.addPathPart(getSnapshotsRequest.repository());
901+
String endpoint;
902+
if (getSnapshotsRequest.snapshots().length == 0) {
903+
endpoint = endpointBuilder.addPathPart("_all").build();
904+
} else {
905+
endpoint = endpointBuilder.addCommaSeparatedPathParts(getSnapshotsRequest.snapshots()).build();
906+
}
907+
908+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
909+
910+
Params parameters = new Params(request);
911+
parameters.withMasterTimeout(getSnapshotsRequest.masterNodeTimeout());
912+
parameters.putParam("ignore_unavailable", Boolean.toString(getSnapshotsRequest.ignoreUnavailable()));
913+
parameters.putParam("verbose", Boolean.toString(getSnapshotsRequest.verbose()));
914+
915+
return request;
916+
}
917+
897918
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
898919
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
899920
.addPathPart(deleteSnapshotRequest.repository())

client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
3333
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
3434
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
35+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
36+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
3537

3638
import java.io.IOException;
3739

@@ -190,6 +192,35 @@ public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, Req
190192
CreateSnapshotResponse::fromXContent, listener, emptySet());
191193
}
192194

195+
/**
196+
* Get snapshots.
197+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
198+
* API on elastic.co</a>
199+
*
200+
* @param getSnapshotsRequest the request
201+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
202+
* @return the response
203+
* @throws IOException in case there is a problem sending the request or parsing back the response
204+
*/
205+
public GetSnapshotsResponse get(GetSnapshotsRequest getSnapshotsRequest, RequestOptions options) throws IOException {
206+
return restHighLevelClient.performRequestAndParseEntity(getSnapshotsRequest, RequestConverters::getSnapshots, options,
207+
GetSnapshotsResponse::fromXContent, emptySet());
208+
}
209+
210+
/**
211+
* Asynchronously get snapshots.
212+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
213+
* API on elastic.co</a>
214+
*
215+
* @param getSnapshotsRequest the request
216+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
217+
* @param listener the listener to be notified upon request completion
218+
*/
219+
public void getAsync(GetSnapshotsRequest getSnapshotsRequest, RequestOptions options, ActionListener<GetSnapshotsResponse> listener) {
220+
restHighLevelClient.performRequestAsyncAndParseEntity(getSnapshotsRequest, RequestConverters::getSnapshots, options,
221+
GetSnapshotsResponse::fromXContent, listener, emptySet());
222+
}
223+
193224
/**
194225
* Deletes a snapshot.
195226
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
4040
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
4141
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
42+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
4243
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
4344
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4445
import org.elasticsearch.action.admin.indices.alias.Alias;
@@ -2011,6 +2012,58 @@ public void testCreateSnapshot() throws IOException {
20112012
assertToXContentBody(createSnapshotRequest, request.getEntity());
20122013
}
20132014

2015+
public void testGetSnapshots() {
2016+
Map<String, String> expectedParams = new HashMap<>();
2017+
String repository = randomIndicesNames(1, 1)[0];
2018+
String snapshot1 = "snapshot1-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
2019+
String snapshot2 = "snapshot2-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
2020+
2021+
String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s,%s", repository, snapshot1, snapshot2);
2022+
2023+
GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest();
2024+
getSnapshotsRequest.repository(repository);
2025+
getSnapshotsRequest.snapshots(Arrays.asList(snapshot1, snapshot2).toArray(new String[0]));
2026+
setRandomMasterTimeout(getSnapshotsRequest, expectedParams);
2027+
2028+
boolean ignoreUnavailable = randomBoolean();
2029+
getSnapshotsRequest.ignoreUnavailable(ignoreUnavailable);
2030+
expectedParams.put("ignore_unavailable", Boolean.toString(ignoreUnavailable));
2031+
2032+
boolean verbose = randomBoolean();
2033+
getSnapshotsRequest.verbose(verbose);
2034+
expectedParams.put("verbose", Boolean.toString(verbose));
2035+
2036+
Request request = RequestConverters.getSnapshots(getSnapshotsRequest);
2037+
assertThat(endpoint, equalTo(request.getEndpoint()));
2038+
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
2039+
assertThat(expectedParams, equalTo(request.getParameters()));
2040+
assertNull(request.getEntity());
2041+
}
2042+
2043+
public void testGetAllSnapshots() {
2044+
Map<String, String> expectedParams = new HashMap<>();
2045+
String repository = randomIndicesNames(1, 1)[0];
2046+
2047+
String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/_all", repository);
2048+
2049+
GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest(repository);
2050+
setRandomMasterTimeout(getSnapshotsRequest, expectedParams);
2051+
2052+
boolean ignoreUnavailable = randomBoolean();
2053+
getSnapshotsRequest.ignoreUnavailable(ignoreUnavailable);
2054+
expectedParams.put("ignore_unavailable", Boolean.toString(ignoreUnavailable));
2055+
2056+
boolean verbose = randomBoolean();
2057+
getSnapshotsRequest.verbose(verbose);
2058+
expectedParams.put("verbose", Boolean.toString(verbose));
2059+
2060+
Request request = RequestConverters.getSnapshots(getSnapshotsRequest);
2061+
assertThat(endpoint, equalTo(request.getEndpoint()));
2062+
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
2063+
assertThat(expectedParams, equalTo(request.getParameters()));
2064+
assertNull(request.getEntity());
2065+
}
2066+
20142067
public void testDeleteSnapshot() {
20152068
Map<String, String> expectedParams = new HashMap<>();
20162069
String repository = randomIndicesNames(1, 1)[0];

client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@
3232
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
3333
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
3434
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
35+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
36+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
3537
import org.elasticsearch.common.xcontent.XContentType;
3638
import org.elasticsearch.repositories.fs.FsRepository;
3739
import org.elasticsearch.rest.RestStatus;
3840

3941
import java.io.IOException;
42+
import java.util.stream.Collectors;
4043

44+
import static org.hamcrest.Matchers.contains;
4145
import static org.hamcrest.Matchers.equalTo;
4246

4347
public class SnapshotIT extends ESRestHighLevelClientTestCase {
@@ -135,6 +139,40 @@ public void testCreateSnapshot() throws IOException {
135139
assertEquals(waitForCompletion ? RestStatus.OK : RestStatus.ACCEPTED, response.status());
136140
}
137141

142+
public void testGetSnapshots() throws IOException {
143+
String repository = "test_repository";
144+
String snapshot1 = "test_snapshot1";
145+
String snapshot2 = "test_snapshot2";
146+
147+
PutRepositoryResponse putRepositoryResponse = createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}");
148+
assertTrue(putRepositoryResponse.isAcknowledged());
149+
150+
CreateSnapshotRequest createSnapshotRequest1 = new CreateSnapshotRequest(repository, snapshot1);
151+
createSnapshotRequest1.waitForCompletion(true);
152+
CreateSnapshotResponse putSnapshotResponse1 = createTestSnapshot(createSnapshotRequest1);
153+
CreateSnapshotRequest createSnapshotRequest2 = new CreateSnapshotRequest(repository, snapshot2);
154+
createSnapshotRequest2.waitForCompletion(true);
155+
CreateSnapshotResponse putSnapshotResponse2 = createTestSnapshot(createSnapshotRequest2);
156+
// check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead.
157+
assertEquals(RestStatus.OK, putSnapshotResponse1.status());
158+
assertEquals(RestStatus.OK, putSnapshotResponse2.status());
159+
160+
GetSnapshotsRequest request;
161+
if (randomBoolean()) {
162+
request = new GetSnapshotsRequest(repository);
163+
} else if (randomBoolean()) {
164+
request = new GetSnapshotsRequest(repository, new String[] {"_all"});
165+
166+
} else {
167+
request = new GetSnapshotsRequest(repository, new String[] {snapshot1, snapshot2});
168+
}
169+
GetSnapshotsResponse response = execute(request, highLevelClient().snapshot()::get, highLevelClient().snapshot()::getAsync);
170+
171+
assertEquals(2, response.getSnapshots().size());
172+
assertThat(response.getSnapshots().stream().map((s) -> s.snapshotId().getName()).collect(Collectors.toList()),
173+
contains("test_snapshot1", "test_snapshot2"));
174+
}
175+
138176
public void testDeleteSnapshot() throws IOException {
139177
String repository = "test_repository";
140178
String snapshot = "test_snapshot";

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
3232
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
3333
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
34+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
35+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
3436
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
3537
import org.elasticsearch.action.support.IndicesOptions;
3638
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
@@ -46,6 +48,7 @@
4648
import org.elasticsearch.common.xcontent.XContentType;
4749
import org.elasticsearch.repositories.fs.FsRepository;
4850
import org.elasticsearch.rest.RestStatus;
51+
import org.elasticsearch.snapshots.SnapshotInfo;
4952

5053
import java.io.IOException;
5154
import java.util.HashMap;
@@ -456,6 +459,76 @@ public void onFailure(Exception exception) {
456459
}
457460
}
458461

462+
public void testSnapshotGetSnapshots() throws IOException {
463+
RestHighLevelClient client = highLevelClient();
464+
465+
createTestRepositories();
466+
createTestSnapshots();
467+
468+
// tag::get-snapshots-request
469+
GetSnapshotsRequest request = new GetSnapshotsRequest(repositoryName);
470+
// end::get-snapshots-request
471+
472+
// tag::get-snapshots-request-snapshots
473+
String[] snapshots = { snapshotName };
474+
request.snapshots(snapshots); // <1>
475+
// end::get-snapshots-request-snapshots
476+
477+
// tag::get-snapshots-request-masterTimeout
478+
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
479+
request.masterNodeTimeout("1m"); // <2>
480+
// end::get-snapshots-request-masterTimeout
481+
482+
// tag::get-snapshots-request-verbose
483+
request.verbose(true); // <1>
484+
// end::get-snapshots-request-verbose
485+
486+
// tag::get-snapshots-request-ignore-unavailable
487+
request.ignoreUnavailable(false); // <1>
488+
// end::get-snapshots-request-ignore-unavailable
489+
490+
// tag::get-snapshots-execute
491+
GetSnapshotsResponse response = client.snapshot().get(request, RequestOptions.DEFAULT);
492+
// end::get-snapshots-execute
493+
494+
// tag::get-snapshots-response
495+
List<SnapshotInfo> snapshotsInfos = response.getSnapshots(); // <1>
496+
// end::get-snapshots-response
497+
assertEquals(1, snapshotsInfos.size());
498+
}
499+
500+
public void testSnapshotGetSnapshotsAsync() throws InterruptedException {
501+
RestHighLevelClient client = highLevelClient();
502+
{
503+
GetSnapshotsRequest request = new GetSnapshotsRequest();
504+
505+
// tag::get-snapshots-execute-listener
506+
ActionListener<GetSnapshotsResponse> listener =
507+
new ActionListener<GetSnapshotsResponse>() {
508+
@Override
509+
public void onResponse(GetSnapshotsResponse deleteSnapshotResponse) {
510+
// <1>
511+
}
512+
513+
@Override
514+
public void onFailure(Exception e) {
515+
// <2>
516+
}
517+
};
518+
// end::get-snapshots-execute-listener
519+
520+
// Replace the empty listener by a blocking listener in test
521+
final CountDownLatch latch = new CountDownLatch(1);
522+
listener = new LatchedActionListener<>(listener, latch);
523+
524+
// tag::get-snapshots-execute-async
525+
client.snapshot().getAsync(request, RequestOptions.DEFAULT, listener); // <1>
526+
// end::get-snapshots-execute-async
527+
528+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
529+
}
530+
}
531+
459532
public void testSnapshotDeleteSnapshot() throws IOException {
460533
RestHighLevelClient client = highLevelClient();
461534

0 commit comments

Comments
 (0)