Skip to content

Commit cd1b120

Browse files
committed
Add Get Snapshots High Level REST API (elastic#31537)
With this commit we add the get snapshots API to the Java high level REST client. Relates elastic#27205
1 parent 4214375 commit cd1b120

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
@@ -39,6 +39,7 @@
3939
import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRequest;
4040
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
4141
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
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.cluster.snapshots.delete.DeleteSnapshotRequest;
@@ -953,6 +954,26 @@ static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) throw
953954
return request;
954955
}
955956

957+
static Request getSnapshots(GetSnapshotsRequest getSnapshotsRequest) {
958+
EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPartAsIs("_snapshot")
959+
.addPathPart(getSnapshotsRequest.repository());
960+
String endpoint;
961+
if (getSnapshotsRequest.snapshots().length == 0) {
962+
endpoint = endpointBuilder.addPathPart("_all").build();
963+
} else {
964+
endpoint = endpointBuilder.addCommaSeparatedPathParts(getSnapshotsRequest.snapshots()).build();
965+
}
966+
967+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
968+
969+
Params parameters = new Params(request);
970+
parameters.withMasterTimeout(getSnapshotsRequest.masterNodeTimeout());
971+
parameters.putParam("ignore_unavailable", Boolean.toString(getSnapshotsRequest.ignoreUnavailable()));
972+
parameters.putParam("verbose", Boolean.toString(getSnapshotsRequest.verbose()));
973+
974+
return request;
975+
}
976+
956977
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
957978
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
958979
.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
@@ -40,6 +40,7 @@
4040
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
4141
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
4242
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
43+
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
4344
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
4445
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4546
import org.elasticsearch.action.admin.indices.alias.Alias;
@@ -2143,6 +2144,58 @@ public void testCreateSnapshot() throws IOException {
21432144
assertToXContentBody(createSnapshotRequest, request.getEntity());
21442145
}
21452146

2147+
public void testGetSnapshots() {
2148+
Map<String, String> expectedParams = new HashMap<>();
2149+
String repository = randomIndicesNames(1, 1)[0];
2150+
String snapshot1 = "snapshot1-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
2151+
String snapshot2 = "snapshot2-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
2152+
2153+
String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s,%s", repository, snapshot1, snapshot2);
2154+
2155+
GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest();
2156+
getSnapshotsRequest.repository(repository);
2157+
getSnapshotsRequest.snapshots(Arrays.asList(snapshot1, snapshot2).toArray(new String[0]));
2158+
setRandomMasterTimeout(getSnapshotsRequest, expectedParams);
2159+
2160+
boolean ignoreUnavailable = randomBoolean();
2161+
getSnapshotsRequest.ignoreUnavailable(ignoreUnavailable);
2162+
expectedParams.put("ignore_unavailable", Boolean.toString(ignoreUnavailable));
2163+
2164+
boolean verbose = randomBoolean();
2165+
getSnapshotsRequest.verbose(verbose);
2166+
expectedParams.put("verbose", Boolean.toString(verbose));
2167+
2168+
Request request = RequestConverters.getSnapshots(getSnapshotsRequest);
2169+
assertThat(endpoint, equalTo(request.getEndpoint()));
2170+
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
2171+
assertThat(expectedParams, equalTo(request.getParameters()));
2172+
assertNull(request.getEntity());
2173+
}
2174+
2175+
public void testGetAllSnapshots() {
2176+
Map<String, String> expectedParams = new HashMap<>();
2177+
String repository = randomIndicesNames(1, 1)[0];
2178+
2179+
String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/_all", repository);
2180+
2181+
GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest(repository);
2182+
setRandomMasterTimeout(getSnapshotsRequest, expectedParams);
2183+
2184+
boolean ignoreUnavailable = randomBoolean();
2185+
getSnapshotsRequest.ignoreUnavailable(ignoreUnavailable);
2186+
expectedParams.put("ignore_unavailable", Boolean.toString(ignoreUnavailable));
2187+
2188+
boolean verbose = randomBoolean();
2189+
getSnapshotsRequest.verbose(verbose);
2190+
expectedParams.put("verbose", Boolean.toString(verbose));
2191+
2192+
Request request = RequestConverters.getSnapshots(getSnapshotsRequest);
2193+
assertThat(endpoint, equalTo(request.getEndpoint()));
2194+
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
2195+
assertThat(expectedParams, equalTo(request.getParameters()));
2196+
assertNull(request.getEntity());
2197+
}
2198+
21462199
public void testDeleteSnapshot() {
21472200
Map<String, String> expectedParams = new HashMap<>();
21482201
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)