Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport to 6.x - Add Snapshots Status API to High Level Rest Client #32295

Merged
merged 2 commits into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequest;
Expand Down Expand Up @@ -975,6 +976,20 @@ static Request getSnapshots(GetSnapshotsRequest getSnapshotsRequest) {
return request;
}

static Request snapshotsStatus(SnapshotsStatusRequest snapshotsStatusRequest) {
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
.addPathPart(snapshotsStatusRequest.repository())
.addCommaSeparatedPathParts(snapshotsStatusRequest.snapshots())
.addPathPartAsIs("_status")
.build();
Request request = new Request(HttpGet.METHOD_NAME, endpoint);

Params parameters = new Params(request);
parameters.withMasterTimeout(snapshotsStatusRequest.masterNodeTimeout());
parameters.withIgnoreUnavailable(snapshotsStatusRequest.ignoreUnavailable());
return request;
}

static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
.addPathPart(deleteSnapshotRequest.repository())
Expand Down Expand Up @@ -1288,7 +1303,7 @@ Params withWaitForActiveShards(ActiveShardCount currentActiveShardCount, ActiveS
}

Params withIndicesOptions(IndicesOptions indicesOptions) {
putParam("ignore_unavailable", Boolean.toString(indicesOptions.ignoreUnavailable()));
withIgnoreUnavailable(indicesOptions.ignoreUnavailable());
putParam("allow_no_indices", Boolean.toString(indicesOptions.allowNoIndices()));
String expandWildcards;
if (indicesOptions.expandWildcardsOpen() == false && indicesOptions.expandWildcardsClosed() == false) {
Expand All @@ -1307,6 +1322,12 @@ Params withIndicesOptions(IndicesOptions indicesOptions) {
return this;
}

Params withIgnoreUnavailable(boolean ignoreUnavailable) {
// Always explicitly place the ignore_unavailable value.
putParam("ignore_unavailable", Boolean.toString(ignoreUnavailable));
return this;
}

Params withHuman(boolean human) {
if (human) {
putParam("human", Boolean.toString(human));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
Expand Down Expand Up @@ -221,6 +223,35 @@ public void getAsync(GetSnapshotsRequest getSnapshotsRequest, RequestOptions opt
GetSnapshotsResponse::fromXContent, listener, emptySet());
}

/**
* Gets the status of requested snapshots.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
* API on elastic.co</a>
* @param snapshotsStatusRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public SnapshotsStatusResponse status(SnapshotsStatusRequest snapshotsStatusRequest, RequestOptions options)
throws IOException {
return restHighLevelClient.performRequestAndParseEntity(snapshotsStatusRequest, RequestConverters::snapshotsStatus, options,
SnapshotsStatusResponse::fromXContent, emptySet());
}

/**
* Asynchronously gets the status of requested snapshots.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
* API on elastic.co</a>
* @param snapshotsStatusRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
*/
public void statusAsync(SnapshotsStatusRequest snapshotsStatusRequest, RequestOptions options,
ActionListener<SnapshotsStatusResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(snapshotsStatusRequest, RequestConverters::snapshotsStatus, options,
SnapshotsStatusResponse::fromXContent, listener, emptySet());
}

/**
* Deletes a snapshot.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
Expand Down Expand Up @@ -175,6 +176,7 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

Expand Down Expand Up @@ -2204,6 +2206,29 @@ public void testGetAllSnapshots() {
assertNull(request.getEntity());
}

public void testSnapshotsStatus() {
Map<String, String> expectedParams = new HashMap<>();
String repository = randomIndicesNames(1, 1)[0];
String[] snapshots = randomIndicesNames(1, 5);
StringBuilder snapshotNames = new StringBuilder(snapshots[0]);
for (int idx = 1; idx < snapshots.length; idx++) {
snapshotNames.append(",").append(snapshots[idx]);
}
boolean ignoreUnavailable = randomBoolean();
String endpoint = "/_snapshot/" + repository + "/" + snapshotNames.toString() + "/_status";

SnapshotsStatusRequest snapshotsStatusRequest = new SnapshotsStatusRequest(repository, snapshots);
setRandomMasterTimeout(snapshotsStatusRequest, expectedParams);
snapshotsStatusRequest.ignoreUnavailable(ignoreUnavailable);
expectedParams.put("ignore_unavailable", Boolean.toString(ignoreUnavailable));

Request request = RequestConverters.snapshotsStatus(snapshotsStatusRequest);
assertThat(request.getEndpoint(), equalTo(endpoint));
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME));
assertThat(request.getParameters(), equalTo(expectedParams));
assertThat(request.getEntity(), is(nullValue()));
}

public void testDeleteSnapshot() {
Map<String, String> expectedParams = new HashMap<>();
String repository = randomIndicesNames(1, 1)[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,6 @@ public void testApiNamingConventions() throws Exception {
"render_search_template",
"scripts_painless_execute",
"snapshot.restore",
"snapshot.status",
"tasks.get",
"termvectors",
"update_by_query"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse;
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
Expand All @@ -43,6 +46,7 @@

import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class SnapshotIT extends ESRestHighLevelClientTestCase {

Expand Down Expand Up @@ -173,6 +177,34 @@ public void testGetSnapshots() throws IOException {
contains("test_snapshot1", "test_snapshot2"));
}

public void testSnapshotsStatus() throws IOException {
String testRepository = "test";
String testSnapshot = "snapshot";
String testIndex = "test_index";

PutRepositoryResponse putRepositoryResponse = createTestRepository(testRepository, FsRepository.TYPE, "{\"location\": \".\"}");
assertTrue(putRepositoryResponse.isAcknowledged());

createIndex(testIndex, Settings.EMPTY);

CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(testRepository, testSnapshot);
createSnapshotRequest.indices(testIndex);
createSnapshotRequest.waitForCompletion(true);
CreateSnapshotResponse createSnapshotResponse = createTestSnapshot(createSnapshotRequest);
// check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead.
assertEquals(RestStatus.OK, createSnapshotResponse.status());

SnapshotsStatusRequest request = new SnapshotsStatusRequest();
request.repository(testRepository);
request.snapshots(new String[]{testSnapshot});
SnapshotsStatusResponse response = execute(request, highLevelClient().snapshot()::status,
highLevelClient().snapshot()::statusAsync);
assertThat(response.getSnapshots().size(), equalTo(1));
assertThat(response.getSnapshots().get(0).getSnapshot().getRepository(), equalTo(testRepository));
assertThat(response.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo(testSnapshot));
assertThat(response.getSnapshots().get(0).getIndices().containsKey(testIndex), is(true));
}

public void testDeleteSnapshot() throws IOException {
String repository = "test_repository";
String snapshot = "test_snapshot";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStats;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStatus;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.cluster.SnapshotsInProgress;
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
Expand Down Expand Up @@ -84,8 +89,8 @@
public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase {

private static final String repositoryName = "test_repository";

private static final String snapshotName = "test_snapshot";
private static final String indexName = "test_index";

public void testSnapshotCreateRepository() throws IOException {
RestHighLevelClient client = highLevelClient();
Expand Down Expand Up @@ -472,6 +477,7 @@ public void testSnapshotGetSnapshots() throws IOException {
RestHighLevelClient client = highLevelClient();

createTestRepositories();
createTestIndex();
createTestSnapshots();

// tag::get-snapshots-request
Expand Down Expand Up @@ -549,10 +555,84 @@ public void onFailure(Exception e) {
}
}

public void testSnapshotSnapshotsStatus() throws IOException {
RestHighLevelClient client = highLevelClient();
createTestRepositories();
createTestIndex();
createTestSnapshots();

// tag::snapshots-status-request
SnapshotsStatusRequest request = new SnapshotsStatusRequest();
// end::snapshots-status-request

// tag::snapshots-status-request-repository
request.repository(repositoryName); // <1>
// end::snapshots-status-request-repository
// tag::snapshots-status-request-snapshots
String [] snapshots = new String[] {snapshotName};
request.snapshots(snapshots); // <1>
// end::snapshots-status-request-snapshots
// tag::snapshots-status-request-ignoreUnavailable
request.ignoreUnavailable(true); // <1>
// end::snapshots-status-request-ignoreUnavailable
// tag::snapshots-status-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.masterNodeTimeout("1m"); // <2>
// end::snapshots-status-request-masterTimeout

// tag::snapshots-status-execute
SnapshotsStatusResponse response = client.snapshot().status(request, RequestOptions.DEFAULT);
// end::snapshots-status-execute

// tag::snapshots-status-response
List<SnapshotStatus> snapshotStatusesResponse = response.getSnapshots();
SnapshotStatus snapshotStatus = snapshotStatusesResponse.get(0); // <1>
SnapshotsInProgress.State snapshotState = snapshotStatus.getState(); // <2>
SnapshotStats shardStats = snapshotStatus.getIndices().get(indexName).getShards().get(0).getStats(); // <3>
// end::snapshots-status-response
assertThat(snapshotStatusesResponse.size(), equalTo(1));
assertThat(snapshotStatusesResponse.get(0).getSnapshot().getRepository(), equalTo(SnapshotClientDocumentationIT.repositoryName));
assertThat(snapshotStatusesResponse.get(0).getSnapshot().getSnapshotId().getName(), equalTo(snapshotName));
assertThat(snapshotState.completed(), equalTo(true));
}

public void testSnapshotSnapshotsStatusAsync() throws InterruptedException {
RestHighLevelClient client = highLevelClient();
{
SnapshotsStatusRequest request = new SnapshotsStatusRequest();

// tag::snapshots-status-execute-listener
ActionListener<SnapshotsStatusResponse> listener =
new ActionListener<SnapshotsStatusResponse>() {
@Override
public void onResponse(SnapshotsStatusResponse snapshotsStatusResponse) {
// <1>
}

@Override
public void onFailure(Exception e) {
// <2>
}
};
// end::snapshots-status-execute-listener

// Replace the empty listener with a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);

// tag::snapshots-status-execute-async
client.snapshot().statusAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::snapshots-status-execute-async

assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}

public void testSnapshotDeleteSnapshot() throws IOException {
RestHighLevelClient client = highLevelClient();

createTestRepositories();
createTestIndex();
createTestSnapshots();

// tag::delete-snapshot-request
Expand Down Expand Up @@ -614,9 +694,14 @@ private void createTestRepositories() throws IOException {
assertTrue(highLevelClient().snapshot().createRepository(request, RequestOptions.DEFAULT).isAcknowledged());
}

private void createTestIndex() throws IOException {
createIndex(indexName, Settings.EMPTY);
}

private void createTestSnapshots() throws IOException {
Request createSnapshot = new Request("put", String.format(Locale.ROOT, "_snapshot/%s/%s", repositoryName, snapshotName));
createSnapshot.addParameter("wait_for_completion", "true");
createSnapshot.setJsonEntity("{\"indices\":\"" + indexName + "\"}");
Response response = highLevelClient().getLowLevelClient().performRequest(createSnapshot);
// check that the request went ok without parsing JSON here. When using the high level client, check acknowledgement instead.
assertEquals(200, response.getStatusLine().getStatusCode());
Expand Down
Loading