Add Snapshots Status API to High Level Rest Client (#31515)
This PR adds the Snapshots Status API to the Snapshot Client, as well as additional documentation for the status api.
This commit is contained in:
parent
51bb27a991
commit
5bcdff73d7
|
@ -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.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;
|
||||
|
@ -963,6 +964,20 @@ final class RequestConverters {
|
|||
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())
|
||||
|
@ -1262,7 +1277,7 @@ final class RequestConverters {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -1281,6 +1296,12 @@ final class RequestConverters {
|
|||
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));
|
||||
|
|
|
@ -30,6 +30,8 @@ import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyReposito
|
|||
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;
|
||||
|
@ -221,6 +223,35 @@ public final class SnapshotClient {
|
|||
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
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotReq
|
|||
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;
|
||||
|
@ -175,6 +176,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXC
|
|||
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;
|
||||
|
||||
|
@ -2171,6 +2173,29 @@ public class RequestConvertersTests extends ESTestCase {
|
|||
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];
|
||||
|
|
|
@ -28,6 +28,9 @@ import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequ
|
|||
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;
|
||||
|
@ -43,6 +46,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
||||
|
||||
|
@ -173,6 +177,34 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
|||
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";
|
||||
|
|
|
@ -37,11 +37,16 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
|||
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;
|
||||
|
@ -84,8 +89,8 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
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();
|
||||
|
@ -466,6 +471,7 @@ public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
createTestRepositories();
|
||||
createTestIndex();
|
||||
createTestSnapshots();
|
||||
|
||||
// tag::get-snapshots-request
|
||||
|
@ -543,10 +549,84 @@ public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -608,9 +688,14 @@ public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
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());
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
[[java-rest-high-snapshot-snapshots-status]]
|
||||
=== Snapshots Status API
|
||||
|
||||
The Snapshots Status API allows to retrieve detailed information about snapshots in progress.
|
||||
|
||||
[[java-rest-high-snapshot-snapshots-status-request]]
|
||||
==== Snapshots Status Request
|
||||
|
||||
A `SnapshotsStatusRequest`:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request]
|
||||
--------------------------------------------------
|
||||
|
||||
==== Required Arguments
|
||||
The following arguments must be provided:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request-repository]
|
||||
--------------------------------------------------
|
||||
<1> Sets the repository to check for snapshot statuses
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request-snapshots]
|
||||
--------------------------------------------------
|
||||
<1> The list of snapshot names to check the status of
|
||||
|
||||
==== Optional Arguments
|
||||
The following arguments can optionally be provided:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request-ignoreUnavailable]
|
||||
--------------------------------------------------
|
||||
<1> The command will fail if some of the snapshots are unavailable. The `ignore_unavailable` flag
|
||||
set to true will return all snapshots that are currently available.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request-masterTimeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to connect to the master node as a `TimeValue`
|
||||
<2> Timeout to connect to the master node as a `String`
|
||||
|
||||
[[java-rest-high-snapshot-snapshots-status-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-snapshot-snapshots-status-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The asynchronous execution of retrieving snapshot statuses requires both the
|
||||
`SnapshotsStatusRequest` instance and an `ActionListener` instance to be
|
||||
passed to the asynchronous method:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `SnapshotsStatusRequest` to execute and the `ActionListener`
|
||||
to use when the execution completes
|
||||
|
||||
The asynchronous method does not block and returns immediately. Once it is
|
||||
completed the `ActionListener` is called back using the `onResponse` method
|
||||
if the execution successfully completed or using the `onFailure` method if
|
||||
it failed.
|
||||
|
||||
A typical listener for `SnapshotsStatusResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-execute-listener]
|
||||
--------------------------------------------------
|
||||
<1> Called when the execution is successfully completed. The response is
|
||||
provided as an argument
|
||||
<2> Called in case of a failure. The raised exception is provided as an argument
|
||||
|
||||
[[java-rest-high-snapshot-snapshots-status-response]]
|
||||
==== Snapshots Status Response
|
||||
|
||||
The returned `SnapshotsStatusResponse` allows to retrieve information about the
|
||||
executed operation as follows:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-response]
|
||||
--------------------------------------------------
|
||||
<1> Request contains a list of snapshot statuses
|
||||
<2> Each status contains information about the snapshot
|
||||
<3> Example of reading snapshot statistics about a specific index and shard
|
|
@ -154,6 +154,7 @@ The Java High Level REST Client supports the following Snapshot APIs:
|
|||
* <<java-rest-high-snapshot-verify-repository>>
|
||||
* <<java-rest-high-snapshot-create-snapshot>>
|
||||
* <<java-rest-high-snapshot-get-snapshots>>
|
||||
* <<java-rest-high-snapshot-snapshots-status>>
|
||||
* <<java-rest-high-snapshot-delete-snapshot>>
|
||||
|
||||
include::snapshot/get_repository.asciidoc[]
|
||||
|
@ -162,6 +163,7 @@ include::snapshot/delete_repository.asciidoc[]
|
|||
include::snapshot/verify_repository.asciidoc[]
|
||||
include::snapshot/create_snapshot.asciidoc[]
|
||||
include::snapshot/get_snapshots.asciidoc[]
|
||||
include::snapshot/snapshots_status.asciidoc[]
|
||||
include::snapshot/delete_snapshot.asciidoc[]
|
||||
|
||||
== Tasks APIs
|
||||
|
|
|
@ -19,16 +19,27 @@
|
|||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.action.support.broadcast.BroadcastShardResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
|
||||
|
||||
public class SnapshotIndexShardStatus extends BroadcastShardResponse implements ToXContentFragment {
|
||||
|
||||
private SnapshotIndexShardStage stage = SnapshotIndexShardStage.INIT;
|
||||
|
@ -80,6 +91,14 @@ public class SnapshotIndexShardStatus extends BroadcastShardResponse implements
|
|||
this.nodeId = nodeId;
|
||||
}
|
||||
|
||||
SnapshotIndexShardStatus(ShardId shardId, SnapshotIndexShardStage stage, SnapshotStats stats, String nodeId, String failure) {
|
||||
super(shardId);
|
||||
this.stage = stage;
|
||||
this.stats = stats;
|
||||
this.nodeId = nodeId;
|
||||
this.failure = failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns snapshot stage
|
||||
*/
|
||||
|
@ -143,7 +162,7 @@ public class SnapshotIndexShardStatus extends BroadcastShardResponse implements
|
|||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(Integer.toString(getShardId().getId()));
|
||||
builder.field(Fields.STAGE, getStage());
|
||||
stats.toXContent(builder, params);
|
||||
builder.field(SnapshotStats.Fields.STATS, stats, params);
|
||||
if (getNodeId() != null) {
|
||||
builder.field(Fields.NODE, getNodeId());
|
||||
}
|
||||
|
@ -153,4 +172,72 @@ public class SnapshotIndexShardStatus extends BroadcastShardResponse implements
|
|||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
static final ObjectParser.NamedObjectParser<SnapshotIndexShardStatus, String> PARSER;
|
||||
static {
|
||||
ConstructingObjectParser<SnapshotIndexShardStatus, ShardId> innerParser = new ConstructingObjectParser<>(
|
||||
"snapshot_index_shard_status", true,
|
||||
(Object[] parsedObjects, ShardId shard) -> {
|
||||
int i = 0;
|
||||
String rawStage = (String) parsedObjects[i++];
|
||||
String nodeId = (String) parsedObjects[i++];
|
||||
String failure = (String) parsedObjects[i++];
|
||||
SnapshotStats stats = (SnapshotStats) parsedObjects[i];
|
||||
|
||||
SnapshotIndexShardStage stage;
|
||||
try {
|
||||
stage = SnapshotIndexShardStage.valueOf(rawStage);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new ElasticsearchParseException(
|
||||
"failed to parse snapshot index shard status [{}][{}], unknonwn stage [{}]",
|
||||
shard.getIndex().getName(), shard.getId(), rawStage);
|
||||
}
|
||||
return new SnapshotIndexShardStatus(shard, stage, stats, nodeId, failure);
|
||||
}
|
||||
);
|
||||
innerParser.declareString(constructorArg(), new ParseField(Fields.STAGE));
|
||||
innerParser.declareString(optionalConstructorArg(), new ParseField(Fields.NODE));
|
||||
innerParser.declareString(optionalConstructorArg(), new ParseField(Fields.REASON));
|
||||
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotStats.fromXContent(p), new ParseField(SnapshotStats.Fields.STATS));
|
||||
PARSER = (p, indexId, shardName) -> {
|
||||
// Combine the index name in the context with the shard name passed in for the named object parser
|
||||
// into a ShardId to pass as context for the inner parser.
|
||||
int shard;
|
||||
try {
|
||||
shard = Integer.parseInt(shardName);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ElasticsearchParseException(
|
||||
"failed to parse snapshot index shard status [{}], expected numeric shard id but got [{}]", indexId, shardName);
|
||||
}
|
||||
ShardId shardId = new ShardId(new Index(indexId, IndexMetaData.INDEX_UUID_NA_VALUE), shard);
|
||||
return innerParser.parse(p, shardId);
|
||||
};
|
||||
}
|
||||
|
||||
public static SnapshotIndexShardStatus fromXContent(XContentParser parser, String indexId) throws IOException {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
|
||||
return PARSER.parse(parser, indexId, parser.currentName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotIndexShardStatus that = (SnapshotIndexShardStatus) o;
|
||||
|
||||
if (stage != that.stage) return false;
|
||||
if (stats != null ? !stats.equals(that.stats) : that.stats != null) return false;
|
||||
if (nodeId != null ? !nodeId.equals(that.nodeId) : that.nodeId != null) return false;
|
||||
return failure != null ? failure.equals(that.failure) : that.failure == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = stage != null ? stage.hashCode() : 0;
|
||||
result = 31 * result + (stats != null ? stats.hashCode() : 0);
|
||||
result = 31 * result + (nodeId != null ? nodeId.hashCode() : 0);
|
||||
result = 31 * result + (failure != null ? failure.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,17 +19,24 @@
|
|||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import org.elasticsearch.common.xcontent.ToXContent.Params;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
|
||||
|
||||
/**
|
||||
* Represents snapshot status of all shards in the index
|
||||
|
@ -57,6 +64,14 @@ public class SnapshotIndexStatus implements Iterable<SnapshotIndexShardStatus>,
|
|||
this.indexShards = unmodifiableMap(indexShards);
|
||||
}
|
||||
|
||||
public SnapshotIndexStatus(String index, Map<Integer, SnapshotIndexShardStatus> indexShards, SnapshotShardsStats shardsStats,
|
||||
SnapshotStats stats) {
|
||||
this.index = index;
|
||||
this.indexShards = indexShards;
|
||||
this.shardsStats = shardsStats;
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index name
|
||||
*/
|
||||
|
@ -97,8 +112,8 @@ public class SnapshotIndexStatus implements Iterable<SnapshotIndexShardStatus>,
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(getIndex());
|
||||
shardsStats.toXContent(builder, params);
|
||||
stats.toXContent(builder, params);
|
||||
builder.field(SnapshotShardsStats.Fields.SHARDS_STATS, shardsStats, params);
|
||||
builder.field(SnapshotStats.Fields.STATS, stats, params);
|
||||
builder.startObject(Fields.SHARDS);
|
||||
for (SnapshotIndexShardStatus shard : indexShards.values()) {
|
||||
shard.toXContent(builder, params);
|
||||
|
@ -107,4 +122,61 @@ public class SnapshotIndexStatus implements Iterable<SnapshotIndexShardStatus>,
|
|||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
static final ObjectParser.NamedObjectParser<SnapshotIndexStatus, Void> PARSER;
|
||||
static {
|
||||
ConstructingObjectParser<SnapshotIndexStatus, String> innerParser = new ConstructingObjectParser<>(
|
||||
"snapshot_index_status", true,
|
||||
(Object[] parsedObjects, String index) -> {
|
||||
int i = 0;
|
||||
SnapshotShardsStats shardsStats = ((SnapshotShardsStats) parsedObjects[i++]);
|
||||
SnapshotStats stats = ((SnapshotStats) parsedObjects[i++]);
|
||||
@SuppressWarnings("unchecked") List<SnapshotIndexShardStatus> shardStatuses =
|
||||
(List<SnapshotIndexShardStatus>) parsedObjects[i];
|
||||
|
||||
final Map<Integer, SnapshotIndexShardStatus> indexShards;
|
||||
if (shardStatuses == null || shardStatuses.isEmpty()) {
|
||||
indexShards = emptyMap();
|
||||
} else {
|
||||
indexShards = new HashMap<>(shardStatuses.size());
|
||||
for (SnapshotIndexShardStatus shardStatus : shardStatuses) {
|
||||
indexShards.put(shardStatus.getShardId().getId(), shardStatus);
|
||||
}
|
||||
}
|
||||
return new SnapshotIndexStatus(index, indexShards, shardsStats, stats);
|
||||
});
|
||||
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotShardsStats.PARSER.apply(p, null),
|
||||
new ParseField(SnapshotShardsStats.Fields.SHARDS_STATS));
|
||||
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotStats.fromXContent(p),
|
||||
new ParseField(SnapshotStats.Fields.STATS));
|
||||
innerParser.declareNamedObjects(constructorArg(), SnapshotIndexShardStatus.PARSER, new ParseField(Fields.SHARDS));
|
||||
PARSER = ((p, c, name) -> innerParser.apply(p, name));
|
||||
}
|
||||
|
||||
public static SnapshotIndexStatus fromXContent(XContentParser parser) throws IOException {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
|
||||
return PARSER.parse(parser, null, parser.currentName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotIndexStatus that = (SnapshotIndexStatus) o;
|
||||
|
||||
if (index != null ? !index.equals(that.index) : that.index != null) return false;
|
||||
if (indexShards != null ? !indexShards.equals(that.indexShards) : that.indexShards != null) return false;
|
||||
if (shardsStats != null ? !shardsStats.equals(that.shardsStats) : that.shardsStats != null) return false;
|
||||
return stats != null ? stats.equals(that.stats) : that.stats == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = index != null ? index.hashCode() : 0;
|
||||
result = 31 * result + (indexShards != null ? indexShards.hashCode() : 0);
|
||||
result = 31 * result + (shardsStats != null ? shardsStats.hashCode() : 0);
|
||||
result = 31 * result + (stats != null ? stats.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,17 +19,22 @@
|
|||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
|
||||
|
||||
/**
|
||||
* Status of a snapshot shards
|
||||
*/
|
||||
public class SnapshotShardsStats implements ToXContentFragment {
|
||||
public class SnapshotShardsStats implements ToXContentObject {
|
||||
|
||||
private int initializingShards;
|
||||
private int startedShards;
|
||||
|
@ -63,6 +68,16 @@ public class SnapshotShardsStats implements ToXContentFragment {
|
|||
}
|
||||
}
|
||||
|
||||
public SnapshotShardsStats(int initializingShards, int startedShards, int finalizingShards, int doneShards, int failedShards,
|
||||
int totalShards) {
|
||||
this.initializingShards = initializingShards;
|
||||
this.startedShards = startedShards;
|
||||
this.finalizingShards = finalizingShards;
|
||||
this.doneShards = doneShards;
|
||||
this.failedShards = failedShards;
|
||||
this.totalShards = totalShards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of shards with the snapshot in the initializing stage
|
||||
*/
|
||||
|
@ -117,15 +132,68 @@ public class SnapshotShardsStats implements ToXContentFragment {
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject(Fields.SHARDS_STATS);
|
||||
builder.startObject();
|
||||
{
|
||||
builder.field(Fields.INITIALIZING, getInitializingShards());
|
||||
builder.field(Fields.STARTED, getStartedShards());
|
||||
builder.field(Fields.FINALIZING, getFinalizingShards());
|
||||
builder.field(Fields.DONE, getDoneShards());
|
||||
builder.field(Fields.FAILED, getFailedShards());
|
||||
builder.field(Fields.TOTAL, getTotalShards());
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
static final ConstructingObjectParser<SnapshotShardsStats, Void> PARSER = new ConstructingObjectParser<>(
|
||||
Fields.SHARDS_STATS, true,
|
||||
(Object[] parsedObjects) -> {
|
||||
int i = 0;
|
||||
int initializingShards = (int) parsedObjects[i++];
|
||||
int startedShards = (int) parsedObjects[i++];
|
||||
int finalizingShards = (int) parsedObjects[i++];
|
||||
int doneShards = (int) parsedObjects[i++];
|
||||
int failedShards = (int) parsedObjects[i++];
|
||||
int totalShards = (int) parsedObjects[i];
|
||||
return new SnapshotShardsStats(initializingShards, startedShards, finalizingShards, doneShards, failedShards, totalShards);
|
||||
}
|
||||
);
|
||||
static {
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.INITIALIZING));
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.STARTED));
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.FINALIZING));
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.DONE));
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.FAILED));
|
||||
PARSER.declareInt(constructorArg(), new ParseField(Fields.TOTAL));
|
||||
}
|
||||
|
||||
public static SnapshotShardsStats fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotShardsStats that = (SnapshotShardsStats) o;
|
||||
|
||||
if (initializingShards != that.initializingShards) return false;
|
||||
if (startedShards != that.startedShards) return false;
|
||||
if (finalizingShards != that.finalizingShards) return false;
|
||||
if (doneShards != that.doneShards) return false;
|
||||
if (failedShards != that.failedShards) return false;
|
||||
return totalShards == that.totalShards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = initializingShards;
|
||||
result = 31 * result + startedShards;
|
||||
result = 31 * result + finalizingShards;
|
||||
result = 31 * result + doneShards;
|
||||
result = 31 * result + failedShards;
|
||||
result = 31 * result + totalShards;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,14 @@ import org.elasticsearch.common.io.stream.Streamable;
|
|||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SnapshotStats implements Streamable, ToXContentFragment {
|
||||
public class SnapshotStats implements Streamable, ToXContentObject {
|
||||
|
||||
private long startTime;
|
||||
private long time;
|
||||
|
@ -176,35 +178,132 @@ public class SnapshotStats implements Streamable, ToXContentFragment {
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject(Fields.STATS)
|
||||
// incremental starts
|
||||
.startObject(Fields.INCREMENTAL)
|
||||
.field(Fields.FILE_COUNT, getIncrementalFileCount())
|
||||
.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getIncrementalSize()))
|
||||
// incremental ends
|
||||
.endObject();
|
||||
builder.startObject();
|
||||
{
|
||||
builder.startObject(Fields.INCREMENTAL);
|
||||
{
|
||||
builder.field(Fields.FILE_COUNT, getIncrementalFileCount());
|
||||
builder.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getIncrementalSize()));
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
if (getProcessedFileCount() != getIncrementalFileCount()) {
|
||||
// processed starts
|
||||
builder.startObject(Fields.PROCESSED)
|
||||
.field(Fields.FILE_COUNT, getProcessedFileCount())
|
||||
.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getProcessedSize()))
|
||||
// processed ends
|
||||
.endObject();
|
||||
builder.startObject(Fields.PROCESSED);
|
||||
{
|
||||
builder.field(Fields.FILE_COUNT, getProcessedFileCount());
|
||||
builder.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getProcessedSize()));
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
// total starts
|
||||
builder.startObject(Fields.TOTAL)
|
||||
.field(Fields.FILE_COUNT, getTotalFileCount())
|
||||
.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getTotalSize()))
|
||||
// total ends
|
||||
.endObject();
|
||||
// timings stats
|
||||
builder.field(Fields.START_TIME_IN_MILLIS, getStartTime())
|
||||
.humanReadableField(Fields.TIME_IN_MILLIS, Fields.TIME, new TimeValue(getTime()));
|
||||
|
||||
builder.startObject(Fields.TOTAL);
|
||||
{
|
||||
builder.field(Fields.FILE_COUNT, getTotalFileCount());
|
||||
builder.humanReadableField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(getTotalSize()));
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
// timings stats
|
||||
builder.field(Fields.START_TIME_IN_MILLIS, getStartTime());
|
||||
builder.humanReadableField(Fields.TIME_IN_MILLIS, Fields.TIME, new TimeValue(getTime()));
|
||||
}
|
||||
return builder.endObject();
|
||||
}
|
||||
|
||||
public static SnapshotStats fromXContent(XContentParser parser) throws IOException {
|
||||
// Parse this old school style instead of using the ObjectParser since there's an impedance mismatch between how the
|
||||
// object has historically been written as JSON versus how it is structured in Java.
|
||||
XContentParser.Token token = parser.currentToken();
|
||||
if (token == null) {
|
||||
token = parser.nextToken();
|
||||
}
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
|
||||
long startTime = 0;
|
||||
long time = 0;
|
||||
int incrementalFileCount = 0;
|
||||
int totalFileCount = 0;
|
||||
int processedFileCount = 0;
|
||||
long incrementalSize = 0;
|
||||
long totalSize = 0;
|
||||
long processedSize = 0;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
|
||||
String currentName = parser.currentName();
|
||||
token = parser.nextToken();
|
||||
if (currentName.equals(Fields.INCREMENTAL)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
|
||||
String innerName = parser.currentName();
|
||||
token = parser.nextToken();
|
||||
if (innerName.equals(Fields.FILE_COUNT)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
incrementalFileCount = parser.intValue();
|
||||
} else if (innerName.equals(Fields.SIZE_IN_BYTES)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
incrementalSize = parser.longValue();
|
||||
} else {
|
||||
// Unknown sub field, skip
|
||||
if (token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentName.equals(Fields.PROCESSED)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
|
||||
String innerName = parser.currentName();
|
||||
token = parser.nextToken();
|
||||
if (innerName.equals(Fields.FILE_COUNT)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
processedFileCount = parser.intValue();
|
||||
} else if (innerName.equals(Fields.SIZE_IN_BYTES)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
processedSize = parser.longValue();
|
||||
} else {
|
||||
// Unknown sub field, skip
|
||||
if (token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentName.equals(Fields.TOTAL)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
|
||||
String innerName = parser.currentName();
|
||||
token = parser.nextToken();
|
||||
if (innerName.equals(Fields.FILE_COUNT)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
totalFileCount = parser.intValue();
|
||||
} else if (innerName.equals(Fields.SIZE_IN_BYTES)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
totalSize = parser.longValue();
|
||||
} else {
|
||||
// Unknown sub field, skip
|
||||
if (token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (currentName.equals(Fields.START_TIME_IN_MILLIS)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
startTime = parser.longValue();
|
||||
} else if (currentName.equals(Fields.TIME_IN_MILLIS)) {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation);
|
||||
time = parser.longValue();
|
||||
} else {
|
||||
// Unknown field, skip
|
||||
if (token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
return new SnapshotStats(startTime, time, incrementalFileCount, totalFileCount, processedFileCount, incrementalSize, totalSize,
|
||||
processedSize);
|
||||
}
|
||||
|
||||
void add(SnapshotStats stats) {
|
||||
incrementalFileCount += stats.incrementalFileCount;
|
||||
totalFileCount += stats.totalFileCount;
|
||||
|
@ -229,4 +328,34 @@ public class SnapshotStats implements Streamable, ToXContentFragment {
|
|||
time = endTime - startTime;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotStats that = (SnapshotStats) o;
|
||||
|
||||
if (startTime != that.startTime) return false;
|
||||
if (time != that.time) return false;
|
||||
if (incrementalFileCount != that.incrementalFileCount) return false;
|
||||
if (totalFileCount != that.totalFileCount) return false;
|
||||
if (processedFileCount != that.processedFileCount) return false;
|
||||
if (incrementalSize != that.incrementalSize) return false;
|
||||
if (totalSize != that.totalSize) return false;
|
||||
return processedSize == that.processedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (startTime ^ (startTime >>> 32));
|
||||
result = 31 * result + (int) (time ^ (time >>> 32));
|
||||
result = 31 * result + incrementalFileCount;
|
||||
result = 31 * result + totalFileCount;
|
||||
result = 31 * result + processedFileCount;
|
||||
result = 31 * result + (int) (incrementalSize ^ (incrementalSize >>> 32));
|
||||
result = 31 * result + (int) (totalSize ^ (totalSize >>> 32));
|
||||
result = 31 * result + (int) (processedSize ^ (processedSize >>> 32));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,15 +20,21 @@
|
|||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.SnapshotsInProgress;
|
||||
import org.elasticsearch.cluster.SnapshotsInProgress.State;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.snapshots.Snapshot;
|
||||
import org.elasticsearch.snapshots.SnapshotId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -40,7 +46,11 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
|
||||
|
||||
/**
|
||||
* Status of a snapshot
|
||||
|
@ -72,6 +82,18 @@ public class SnapshotStatus implements ToXContentObject, Streamable {
|
|||
updateShardStats();
|
||||
}
|
||||
|
||||
private SnapshotStatus(Snapshot snapshot, State state, List<SnapshotIndexShardStatus> shards,
|
||||
Map<String, SnapshotIndexStatus> indicesStatus, SnapshotShardsStats shardsStats,
|
||||
SnapshotStats stats, Boolean includeGlobalState) {
|
||||
this.snapshot = snapshot;
|
||||
this.state = state;
|
||||
this.shards = shards;
|
||||
this.indicesStatus = indicesStatus;
|
||||
this.shardsStats = shardsStats;
|
||||
this.stats = stats;
|
||||
this.includeGlobalState = includeGlobalState;
|
||||
}
|
||||
|
||||
SnapshotStatus() {
|
||||
}
|
||||
|
||||
|
@ -207,8 +229,8 @@ public class SnapshotStatus implements ToXContentObject, Streamable {
|
|||
if (includeGlobalState != null) {
|
||||
builder.field(INCLUDE_GLOBAL_STATE, includeGlobalState);
|
||||
}
|
||||
shardsStats.toXContent(builder, params);
|
||||
stats.toXContent(builder, params);
|
||||
builder.field(SnapshotShardsStats.Fields.SHARDS_STATS, shardsStats, params);
|
||||
builder.field(SnapshotStats.Fields.STATS, stats, params);
|
||||
builder.startObject(INDICES);
|
||||
for (SnapshotIndexStatus indexStatus : getIndices().values()) {
|
||||
indexStatus.toXContent(builder, params);
|
||||
|
@ -218,6 +240,52 @@ public class SnapshotStatus implements ToXContentObject, Streamable {
|
|||
return builder;
|
||||
}
|
||||
|
||||
static final ConstructingObjectParser<SnapshotStatus, Void> PARSER = new ConstructingObjectParser<>(
|
||||
"snapshot_status", true,
|
||||
(Object[] parsedObjects) -> {
|
||||
int i = 0;
|
||||
String name = (String) parsedObjects[i++];
|
||||
String repository = (String) parsedObjects[i++];
|
||||
String uuid = (String) parsedObjects[i++];
|
||||
String rawState = (String) parsedObjects[i++];
|
||||
Boolean includeGlobalState = (Boolean) parsedObjects[i++];
|
||||
SnapshotStats stats = ((SnapshotStats) parsedObjects[i++]);
|
||||
SnapshotShardsStats shardsStats = ((SnapshotShardsStats) parsedObjects[i++]);
|
||||
@SuppressWarnings("unchecked") List<SnapshotIndexStatus> indices = ((List<SnapshotIndexStatus>) parsedObjects[i]);
|
||||
|
||||
Snapshot snapshot = new Snapshot(repository, new SnapshotId(name, uuid));
|
||||
SnapshotsInProgress.State state = SnapshotsInProgress.State.valueOf(rawState);
|
||||
Map<String, SnapshotIndexStatus> indicesStatus;
|
||||
List<SnapshotIndexShardStatus> shards;
|
||||
if (indices == null || indices.isEmpty()) {
|
||||
indicesStatus = emptyMap();
|
||||
shards = emptyList();
|
||||
} else {
|
||||
indicesStatus = new HashMap<>(indices.size());
|
||||
shards = new ArrayList<>();
|
||||
for (SnapshotIndexStatus index : indices) {
|
||||
indicesStatus.put(index.getIndex(), index);
|
||||
shards.addAll(index.getShards().values());
|
||||
}
|
||||
}
|
||||
return new SnapshotStatus(snapshot, state, shards, indicesStatus, shardsStats, stats, includeGlobalState);
|
||||
});
|
||||
static {
|
||||
PARSER.declareString(constructorArg(), new ParseField(SNAPSHOT));
|
||||
PARSER.declareString(constructorArg(), new ParseField(REPOSITORY));
|
||||
PARSER.declareString(constructorArg(), new ParseField(UUID));
|
||||
PARSER.declareString(constructorArg(), new ParseField(STATE));
|
||||
PARSER.declareBoolean(optionalConstructorArg(), new ParseField(INCLUDE_GLOBAL_STATE));
|
||||
PARSER.declareField(constructorArg(), SnapshotStats::fromXContent, new ParseField(SnapshotStats.Fields.STATS),
|
||||
ObjectParser.ValueType.OBJECT);
|
||||
PARSER.declareObject(constructorArg(), SnapshotShardsStats.PARSER, new ParseField(SnapshotShardsStats.Fields.SHARDS_STATS));
|
||||
PARSER.declareNamedObjects(constructorArg(), SnapshotIndexStatus.PARSER, new ParseField(INDICES));
|
||||
}
|
||||
|
||||
public static SnapshotStatus fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.parse(parser, null);
|
||||
}
|
||||
|
||||
private void updateShardStats() {
|
||||
stats = new SnapshotStats();
|
||||
shardsStats = new SnapshotShardsStats(shards);
|
||||
|
@ -225,4 +293,31 @@ public class SnapshotStatus implements ToXContentObject, Streamable {
|
|||
stats.add(shard.getStats());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotStatus that = (SnapshotStatus) o;
|
||||
|
||||
if (snapshot != null ? !snapshot.equals(that.snapshot) : that.snapshot != null) return false;
|
||||
if (state != that.state) return false;
|
||||
if (indicesStatus != null ? !indicesStatus.equals(that.indicesStatus) : that.indicesStatus != null)
|
||||
return false;
|
||||
if (shardsStats != null ? !shardsStats.equals(that.shardsStats) : that.shardsStats != null) return false;
|
||||
if (stats != null ? !stats.equals(that.stats) : that.stats != null) return false;
|
||||
return includeGlobalState != null ? includeGlobalState.equals(that.includeGlobalState) : that.includeGlobalState == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = snapshot != null ? snapshot.hashCode() : 0;
|
||||
result = 31 * result + (state != null ? state.hashCode() : 0);
|
||||
result = 31 * result + (indicesStatus != null ? indicesStatus.hashCode() : 0);
|
||||
result = 31 * result + (shardsStats != null ? shardsStats.hashCode() : 0);
|
||||
result = 31 * result + (stats != null ? stats.hashCode() : 0);
|
||||
result = 31 * result + (includeGlobalState != null ? includeGlobalState.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,21 @@
|
|||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
|
||||
|
||||
/**
|
||||
* Snapshot status response
|
||||
*/
|
||||
|
@ -85,4 +90,33 @@ public class SnapshotsStatusResponse extends ActionResponse implements ToXConten
|
|||
return builder;
|
||||
}
|
||||
|
||||
private static final ConstructingObjectParser<SnapshotsStatusResponse, Void> PARSER = new ConstructingObjectParser<>(
|
||||
"snapshots_status_response", true,
|
||||
(Object[] parsedObjects) -> {
|
||||
@SuppressWarnings("unchecked") List<SnapshotStatus> snapshots = (List<SnapshotStatus>) parsedObjects[0];
|
||||
return new SnapshotsStatusResponse(snapshots);
|
||||
}
|
||||
);
|
||||
static {
|
||||
PARSER.declareObjectArray(constructorArg(), SnapshotStatus.PARSER, new ParseField("snapshots"));
|
||||
}
|
||||
|
||||
public static SnapshotsStatusResponse fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.parse(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SnapshotsStatusResponse response = (SnapshotsStatusResponse) o;
|
||||
|
||||
return snapshots != null ? snapshots.equals(response.snapshots) : response.snapshots == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return snapshots != null ? snapshots.hashCode() : 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
public class SnapshotIndexShardStatusTests extends AbstractXContentTestCase<SnapshotIndexShardStatus> {
|
||||
|
||||
@Override
|
||||
protected SnapshotIndexShardStatus createTestInstance() {
|
||||
return createForIndex(randomAlphaOfLength(10));
|
||||
}
|
||||
|
||||
protected SnapshotIndexShardStatus createForIndex(String indexName) {
|
||||
ShardId shardId = new ShardId(new Index(indexName, IndexMetaData.INDEX_UUID_NA_VALUE), randomIntBetween(0, 500));
|
||||
SnapshotIndexShardStage stage = randomFrom(SnapshotIndexShardStage.values());
|
||||
SnapshotStats stats = new SnapshotStatsTests().createTestInstance();
|
||||
String nodeId = randomAlphaOfLength(20);
|
||||
String failure = null;
|
||||
if (rarely()) {
|
||||
failure = randomAlphaOfLength(200);
|
||||
}
|
||||
return new SnapshotIndexShardStatus(shardId, stage, stats, nodeId, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
// Do not place random fields in the root object since its fields correspond to shard names.
|
||||
return String::isEmpty;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotIndexShardStatus doParseInstance(XContentParser parser) throws IOException {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.nextToken(), parser::getTokenLocation);
|
||||
SnapshotIndexShardStatus status = SnapshotIndexShardStatus.fromXContent(parser, parser.currentName());
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
|
||||
public class SnapshotIndexStatusTests extends AbstractXContentTestCase<SnapshotIndexStatus> {
|
||||
|
||||
@Override
|
||||
protected SnapshotIndexStatus createTestInstance() {
|
||||
String index = randomAlphaOfLength(10);
|
||||
List<SnapshotIndexShardStatus> shardStatuses = new ArrayList<>();
|
||||
SnapshotIndexShardStatusTests builder = new SnapshotIndexShardStatusTests();
|
||||
for (int idx = 0; idx < randomIntBetween(0, 10); idx++) {
|
||||
shardStatuses.add(builder.createForIndex(index));
|
||||
}
|
||||
return new SnapshotIndexStatus(index, shardStatuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
// Do not place random fields in the root object or the shards field since their fields correspond to names.
|
||||
return (s) -> s.isEmpty() || s.endsWith("shards");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotIndexStatus doParseInstance(XContentParser parser) throws IOException {
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.nextToken(), parser::getTokenLocation);
|
||||
SnapshotIndexStatus status = SnapshotIndexStatus.fromXContent(parser);
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
public class SnapshotShardsStatsTests extends AbstractXContentTestCase<SnapshotShardsStats> {
|
||||
|
||||
@Override
|
||||
protected SnapshotShardsStats createTestInstance() {
|
||||
int initializingShards = randomInt();
|
||||
int startedShards = randomInt();
|
||||
int finalizingShards = randomInt();
|
||||
int doneShards = randomInt();
|
||||
int failedShards = randomInt();
|
||||
int totalShards = randomInt();
|
||||
return new SnapshotShardsStats(initializingShards, startedShards, finalizingShards, doneShards, failedShards, totalShards);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotShardsStats doParseInstance(XContentParser parser) throws IOException {
|
||||
return SnapshotShardsStats.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
public class SnapshotStatsTests extends AbstractXContentTestCase<SnapshotStats> {
|
||||
|
||||
@Override
|
||||
protected SnapshotStats createTestInstance() {
|
||||
long startTime = randomNonNegativeLong();
|
||||
long time = randomNonNegativeLong();
|
||||
int incrementalFileCount = randomIntBetween(0, Integer.MAX_VALUE);
|
||||
int totalFileCount = randomIntBetween(0, Integer.MAX_VALUE);
|
||||
int processedFileCount = randomIntBetween(0, Integer.MAX_VALUE);
|
||||
long incrementalSize = ((long)randomIntBetween(0, Integer.MAX_VALUE)) * 2;
|
||||
long totalSize = ((long)randomIntBetween(0, Integer.MAX_VALUE)) * 2;
|
||||
long processedSize = ((long)randomIntBetween(0, Integer.MAX_VALUE)) * 2;
|
||||
return new SnapshotStats(startTime, time, incrementalFileCount, totalFileCount,
|
||||
processedFileCount, incrementalSize, totalSize, processedSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotStats doParseInstance(XContentParser parser) throws IOException {
|
||||
return SnapshotStats.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -21,16 +21,19 @@ package org.elasticsearch.action.admin.cluster.snapshots.status;
|
|||
|
||||
import org.elasticsearch.cluster.SnapshotsInProgress;
|
||||
import org.elasticsearch.common.UUIDs;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.snapshots.Snapshot;
|
||||
import org.elasticsearch.snapshots.SnapshotId;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
||||
public class SnapshotStatusTests extends ESTestCase {
|
||||
public class SnapshotStatusTests extends AbstractXContentTestCase<SnapshotStatus> {
|
||||
|
||||
|
||||
public void testToString() throws Exception {
|
||||
|
@ -146,4 +149,39 @@ public class SnapshotStatusTests extends ESTestCase {
|
|||
"}";
|
||||
assertEquals(expected, status.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotStatus createTestInstance() {
|
||||
SnapshotsInProgress.State state = randomFrom(SnapshotsInProgress.State.values());
|
||||
String uuid = UUIDs.randomBase64UUID();
|
||||
SnapshotId id = new SnapshotId("test-snap", uuid);
|
||||
Snapshot snapshot = new Snapshot("test-repo", id);
|
||||
|
||||
SnapshotIndexShardStatusTests builder = new SnapshotIndexShardStatusTests();
|
||||
builder.createTestInstance();
|
||||
|
||||
List<SnapshotIndexShardStatus> snapshotIndexShardStatuses = new ArrayList<>();
|
||||
for (int idx = 0; idx < randomIntBetween(0, 10); idx++) {
|
||||
SnapshotIndexShardStatus snapshotIndexShardStatus = builder.createTestInstance();
|
||||
snapshotIndexShardStatuses.add(snapshotIndexShardStatus);
|
||||
}
|
||||
boolean includeGlobalState = randomBoolean();
|
||||
return new SnapshotStatus(snapshot, state, snapshotIndexShardStatuses, includeGlobalState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
// Do not place random fields in the indices field or shards field since their fields correspond to names.
|
||||
return (s) -> s.endsWith("shards") || s.endsWith("indices");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotStatus doParseInstance(XContentParser parser) throws IOException {
|
||||
return SnapshotStatus.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.cluster.snapshots.status;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
public class SnapshotsStatusResponseTests extends AbstractXContentTestCase<SnapshotsStatusResponse> {
|
||||
|
||||
@Override
|
||||
protected SnapshotsStatusResponse doParseInstance(XContentParser parser) throws IOException {
|
||||
return SnapshotsStatusResponse.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
// Do not place random fields in the indices field or shards field since their fields correspond to names.
|
||||
return (s) -> s.endsWith("shards") || s.endsWith("indices");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SnapshotsStatusResponse createTestInstance() {
|
||||
SnapshotStatusTests statusBuilder = new SnapshotStatusTests();
|
||||
List<SnapshotStatus> snapshotStatuses = new ArrayList<>();
|
||||
for (int idx = 0; idx < randomIntBetween(0, 5); idx++) {
|
||||
snapshotStatuses.add(statusBuilder.createTestInstance());
|
||||
}
|
||||
return new SnapshotsStatusResponse(snapshotStatuses);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue