Add Create Snapshot to High-Level Rest Client (#31215)
Added support to the high-level rest client for the create snapshot API call. This required several changes to toXContent which may need to be cleaned up in a later PR. Also added several parsers for fromXContent to be able to retrieve appropriate responses along with tests.
This commit is contained in:
parent
01623f66de
commit
61eefc84f3
|
@ -37,6 +37,7 @@ import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRe
|
|||
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
||||
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;
|
||||
|
@ -880,6 +881,19 @@ final class RequestConverters {
|
|||
return request;
|
||||
}
|
||||
|
||||
static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) throws IOException {
|
||||
String endpoint = new EndpointBuilder().addPathPart("_snapshot")
|
||||
.addPathPart(createSnapshotRequest.repository())
|
||||
.addPathPart(createSnapshotRequest.snapshot())
|
||||
.build();
|
||||
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
|
||||
Params params = new Params(request);
|
||||
params.withMasterTimeout(createSnapshotRequest.masterNodeTimeout());
|
||||
params.withWaitForCompletion(createSnapshotRequest.waitForCompletion());
|
||||
request.setEntity(createEntity(createSnapshotRequest, REQUEST_BODY_CONTENT_TYPE));
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
|
||||
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
|
||||
.addPathPart(deleteSnapshotRequest.repository())
|
||||
|
|
|
@ -28,6 +28,8 @@ 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.create.CreateSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
|
||||
|
||||
|
@ -164,6 +166,30 @@ public final class SnapshotClient {
|
|||
VerifyRepositoryResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a snapshot.
|
||||
* <p>
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||
* API on elastic.co</a>
|
||||
*/
|
||||
public CreateSnapshotResponse createSnapshot(CreateSnapshotRequest createSnapshotRequest, RequestOptions options)
|
||||
throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, options,
|
||||
CreateSnapshotResponse::fromXContent, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously creates a snapshot.
|
||||
* <p>
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||
* API on elastic.co</a>
|
||||
*/
|
||||
public void createSnapshotAsync(CreateSnapshotRequest createSnapshotRequest, RequestOptions options,
|
||||
ActionListener<CreateSnapshotResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(createSnapshotRequest, RequestConverters::createSnapshot, options,
|
||||
CreateSnapshotResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a snapshot.
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRe
|
|||
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
|
@ -1988,6 +1989,28 @@ public class RequestConvertersTests extends ESTestCase {
|
|||
assertThat(expectedParams, equalTo(request.getParameters()));
|
||||
}
|
||||
|
||||
public void testCreateSnapshot() throws IOException {
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
String repository = randomIndicesNames(1, 1)[0];
|
||||
String snapshot = "snapshot-" + generateRandomStringArray(1, randomInt(10), false, false)[0];
|
||||
String endpoint = "/_snapshot/" + repository + "/" + snapshot;
|
||||
|
||||
CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot);
|
||||
setRandomMasterTimeout(createSnapshotRequest, expectedParams);
|
||||
Boolean waitForCompletion = randomBoolean();
|
||||
createSnapshotRequest.waitForCompletion(waitForCompletion);
|
||||
|
||||
if (waitForCompletion) {
|
||||
expectedParams.put("wait_for_completion", waitForCompletion.toString());
|
||||
}
|
||||
|
||||
Request request = RequestConverters.createSnapshot(createSnapshotRequest);
|
||||
assertThat(endpoint, equalTo(request.getEndpoint()));
|
||||
assertThat(HttpPut.METHOD_NAME, equalTo(request.getMethod()));
|
||||
assertThat(expectedParams, equalTo(request.getParameters()));
|
||||
assertToXContentBody(createSnapshotRequest, request.getEntity());
|
||||
}
|
||||
|
||||
public void testDeleteSnapshot() {
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
String repository = randomIndicesNames(1, 1)[0];
|
||||
|
|
|
@ -28,6 +28,8 @@ 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.create.CreateSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
@ -35,7 +37,6 @@ import org.elasticsearch.repositories.fs.FsRepository;
|
|||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
|
@ -49,12 +50,12 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
|||
highLevelClient().snapshot()::createRepositoryAsync);
|
||||
}
|
||||
|
||||
private Response createTestSnapshot(String repository, String snapshot) throws IOException {
|
||||
Request createSnapshot = new Request("put", String.format(Locale.ROOT, "_snapshot/%s/%s", repository, snapshot));
|
||||
createSnapshot.addParameter("wait_for_completion", "true");
|
||||
return highLevelClient().getLowLevelClient().performRequest(createSnapshot);
|
||||
}
|
||||
private CreateSnapshotResponse createTestSnapshot(CreateSnapshotRequest createSnapshotRequest) throws IOException {
|
||||
// assumes the repository already exists
|
||||
|
||||
return execute(createSnapshotRequest, highLevelClient().snapshot()::createSnapshot,
|
||||
highLevelClient().snapshot()::createSnapshotAsync);
|
||||
}
|
||||
|
||||
public void testCreateRepository() throws IOException {
|
||||
PutRepositoryResponse response = createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}");
|
||||
|
@ -119,6 +120,21 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
|||
assertThat(response.getNodes().size(), equalTo(1));
|
||||
}
|
||||
|
||||
public void testCreateSnapshot() throws IOException {
|
||||
String repository = "test_repository";
|
||||
assertTrue(createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged());
|
||||
|
||||
String snapshot = "test_snapshot";
|
||||
CreateSnapshotRequest request = new CreateSnapshotRequest(repository, snapshot);
|
||||
boolean waitForCompletion = randomBoolean();
|
||||
request.waitForCompletion(waitForCompletion);
|
||||
request.partial(randomBoolean());
|
||||
request.includeGlobalState(randomBoolean());
|
||||
|
||||
CreateSnapshotResponse response = createTestSnapshot(request);
|
||||
assertEquals(waitForCompletion ? RestStatus.OK : RestStatus.ACCEPTED, response.status());
|
||||
}
|
||||
|
||||
public void testDeleteSnapshot() throws IOException {
|
||||
String repository = "test_repository";
|
||||
String snapshot = "test_snapshot";
|
||||
|
@ -126,9 +142,11 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
|||
PutRepositoryResponse putRepositoryResponse = createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}");
|
||||
assertTrue(putRepositoryResponse.isAcknowledged());
|
||||
|
||||
Response putSnapshotResponse = createTestSnapshot(repository, snapshot);
|
||||
CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot);
|
||||
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(200, putSnapshotResponse.getStatusLine().getStatusCode());
|
||||
assertEquals(RestStatus.OK, createSnapshotResponse.status());
|
||||
|
||||
DeleteSnapshotRequest request = new DeleteSnapshotRequest(repository, snapshot);
|
||||
DeleteSnapshotResponse response = execute(request, highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync);
|
||||
|
|
|
@ -29,6 +29,10 @@ 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.create.CreateSnapshotRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
||||
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.client.ESRestHighLevelClientTestCase;
|
||||
|
@ -41,6 +45,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.repositories.fs.FsRepository;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -367,6 +372,90 @@ public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
}
|
||||
}
|
||||
|
||||
public void testSnapshotCreate() throws IOException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest("test-index0");
|
||||
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
createIndexRequest = new CreateIndexRequest("test-index1");
|
||||
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
createTestRepositories();
|
||||
|
||||
// tag::create-snapshot-request
|
||||
CreateSnapshotRequest request = new CreateSnapshotRequest();
|
||||
// end::create-snapshot-request
|
||||
|
||||
// tag::create-snapshot-request-repositoryName
|
||||
request.repository(repositoryName); // <1>
|
||||
// end::create-snapshot-request-repositoryName
|
||||
// tag::create-snapshot-request-snapshotName
|
||||
request.snapshot(snapshotName); // <1>
|
||||
// end::create-snapshot-request-snapshotName
|
||||
// tag::create-snapshot-request-indices
|
||||
request.indices("test-index0", "test-index1"); // <1>
|
||||
// end::create-snapshot-request-indices
|
||||
// tag::create-snapshot-request-indicesOptions
|
||||
request.indicesOptions(IndicesOptions.fromOptions(false, false, true, true)); // <1>
|
||||
// end::create-snapshot-request-indicesOptions
|
||||
// tag::create-snapshot-request-partial
|
||||
request.partial(false); // <1>
|
||||
// end::create-snapshot-request-partial
|
||||
// tag::create-snapshot-request-includeGlobalState
|
||||
request.includeGlobalState(true); // <1>
|
||||
// end::create-snapshot-request-includeGlobalState
|
||||
|
||||
// tag::create-snapshot-request-masterTimeout
|
||||
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
|
||||
request.masterNodeTimeout("1m"); // <2>
|
||||
// end::create-snapshot-request-masterTimeout
|
||||
// tag::create-snapshot-request-waitForCompletion
|
||||
request.waitForCompletion(true); // <1>
|
||||
// end::create-snapshot-request-waitForCompletion
|
||||
|
||||
// tag::create-snapshot-execute
|
||||
CreateSnapshotResponse response = client.snapshot().createSnapshot(request, RequestOptions.DEFAULT);
|
||||
// end::create-snapshot-execute
|
||||
|
||||
// tag::create-snapshot-response
|
||||
RestStatus status = response.status(); // <1>
|
||||
// end::create-snapshot-response
|
||||
|
||||
assertEquals(RestStatus.OK, status);
|
||||
}
|
||||
|
||||
public void testSnapshotCreateAsync() throws InterruptedException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
{
|
||||
CreateSnapshotRequest request = new CreateSnapshotRequest(repositoryName, snapshotName);
|
||||
|
||||
// tag::create-snapshot-execute-listener
|
||||
ActionListener<CreateSnapshotResponse> listener =
|
||||
new ActionListener<CreateSnapshotResponse>() {
|
||||
@Override
|
||||
public void onResponse(CreateSnapshotResponse createSnapshotResponse) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception exception) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::create-snapshot-execute-listener
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
// tag::create-snapshot-execute-async
|
||||
client.snapshot().createSnapshotAsync(request, RequestOptions.DEFAULT, listener); // <1>
|
||||
// end::create-snapshot-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSnapshotDeleteSnapshot() throws IOException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
[[java-rest-high-snapshot-create-snapshot]]
|
||||
=== Create Snapshot API
|
||||
|
||||
Use the Create Snapshot API to create a new snapshot.
|
||||
|
||||
[[java-rest-high-snapshot-create-snapshot-request]]
|
||||
==== Create Snapshot Request
|
||||
|
||||
A `CreateSnapshotRequest`:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request]
|
||||
--------------------------------------------------
|
||||
|
||||
==== Required Arguments
|
||||
The following arguments are mandatory:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-repositoryName]
|
||||
--------------------------------------------------
|
||||
<1> The name of the repository.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-snapshotName]
|
||||
--------------------------------------------------
|
||||
<1> The name of the snapshot.
|
||||
|
||||
==== Optional Arguments
|
||||
The following arguments are optional:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-indices]
|
||||
--------------------------------------------------
|
||||
<1> A list of indices the snapshot is applied to.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-indicesOptions]
|
||||
--------------------------------------------------
|
||||
<1> Options applied to the indices.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-partial]
|
||||
--------------------------------------------------
|
||||
<1> Set `partial` to `true` to allow a successful snapshot without the
|
||||
availability of all the indices primary shards. Defaults to `false`.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-includeGlobalState]
|
||||
--------------------------------------------------
|
||||
<1> Set `includeGlobalState` to `false` to prevent writing the cluster's global
|
||||
state as part of the snapshot. Defaults to `true`.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-masterTimeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to connect to the master node as a `TimeValue`.
|
||||
<2> Timeout to connect to the master node as a `String`.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-request-waitForCompletion]
|
||||
--------------------------------------------------
|
||||
<1> Waits for the snapshot to be completed before a response is returned.
|
||||
|
||||
[[java-rest-high-snapshot-create-snapshot-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-snapshot-create-snapshot-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The asynchronous execution of a create snapshot request requires both the
|
||||
`CreateSnapshotRequest` instance and an `ActionListener` instance to be
|
||||
passed as arguments to the asynchronous method:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `CreateSnapshotRequest` 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 with the `onResponse` method
|
||||
if the execution is successful or the `onFailure` method if the execution
|
||||
failed.
|
||||
|
||||
A typical listener for `CreateSnapshotResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-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-create-snapshot-response]]
|
||||
==== Snapshot Create Response
|
||||
|
||||
Use the `CreateSnapshotResponse` to retrieve information about the evaluated
|
||||
request:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-snapshot-response]
|
||||
--------------------------------------------------
|
||||
<1> Indicates the node has started the request.
|
|
@ -142,12 +142,14 @@ The Java High Level REST Client supports the following Snapshot APIs:
|
|||
* <<java-rest-high-snapshot-create-repository>>
|
||||
* <<java-rest-high-snapshot-delete-repository>>
|
||||
* <<java-rest-high-snapshot-verify-repository>>
|
||||
* <<java-rest-high-snapshot-create-snapshot>>
|
||||
* <<java-rest-high-snapshot-delete-snapshot>>
|
||||
|
||||
include::snapshot/get_repository.asciidoc[]
|
||||
include::snapshot/create_repository.asciidoc[]
|
||||
include::snapshot/delete_repository.asciidoc[]
|
||||
include::snapshot/verify_repository.asciidoc[]
|
||||
include::snapshot/create_snapshot.asciidoc[]
|
||||
include::snapshot/delete_snapshot.asciidoc[]
|
||||
|
||||
== Tasks APIs
|
||||
|
|
|
@ -28,14 +28,17 @@ import org.elasticsearch.common.Strings;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
import static org.elasticsearch.common.Strings.EMPTY_ARRAY;
|
||||
|
@ -58,7 +61,8 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBo
|
|||
* <li>must not contain invalid file name characters {@link org.elasticsearch.common.Strings#INVALID_FILENAME_CHARS} </li>
|
||||
* </ul>
|
||||
*/
|
||||
public class CreateSnapshotRequest extends MasterNodeRequest<CreateSnapshotRequest> implements IndicesRequest.Replaceable {
|
||||
public class CreateSnapshotRequest extends MasterNodeRequest<CreateSnapshotRequest>
|
||||
implements IndicesRequest.Replaceable, ToXContentObject {
|
||||
|
||||
private String snapshot;
|
||||
|
||||
|
@ -407,6 +411,34 @@ public class CreateSnapshotRequest extends MasterNodeRequest<CreateSnapshotReque
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field("repository", repository);
|
||||
builder.field("snapshot", snapshot);
|
||||
builder.startArray("indices");
|
||||
for (String index : indices) {
|
||||
builder.value(index);
|
||||
}
|
||||
builder.endArray();
|
||||
builder.field("partial", partial);
|
||||
if (settings != null) {
|
||||
builder.startObject("settings");
|
||||
if (settings.isEmpty() == false) {
|
||||
settings.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.field("include_global_state", includeGlobalState);
|
||||
if (indicesOptions != null) {
|
||||
indicesOptions.toXContent(builder, params);
|
||||
}
|
||||
builder.field("wait_for_completion", waitForCompletion);
|
||||
builder.field("master_node_timeout", masterNodeTimeout.toString());
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
||||
|
@ -416,4 +448,42 @@ public class CreateSnapshotRequest extends MasterNodeRequest<CreateSnapshotReque
|
|||
public String getDescription() {
|
||||
return "snapshot [" + repository + ":" + snapshot + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CreateSnapshotRequest that = (CreateSnapshotRequest) o;
|
||||
return partial == that.partial &&
|
||||
includeGlobalState == that.includeGlobalState &&
|
||||
waitForCompletion == that.waitForCompletion &&
|
||||
Objects.equals(snapshot, that.snapshot) &&
|
||||
Objects.equals(repository, that.repository) &&
|
||||
Arrays.equals(indices, that.indices) &&
|
||||
Objects.equals(indicesOptions, that.indicesOptions) &&
|
||||
Objects.equals(settings, that.settings) &&
|
||||
Objects.equals(masterNodeTimeout, that.masterNodeTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(snapshot, repository, indicesOptions, partial, settings, includeGlobalState, waitForCompletion);
|
||||
result = 31 * result + Arrays.hashCode(indices);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CreateSnapshotRequest{" +
|
||||
"snapshot='" + snapshot + '\'' +
|
||||
", repository='" + repository + '\'' +
|
||||
", indices=" + (indices == null ? null : Arrays.asList(indices)) +
|
||||
", indicesOptions=" + indicesOptions +
|
||||
", partial=" + partial +
|
||||
", settings=" + settings +
|
||||
", includeGlobalState=" + includeGlobalState +
|
||||
", waitForCompletion=" + waitForCompletion +
|
||||
", masterNodeTimeout=" + masterNodeTimeout +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,13 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.snapshots.SnapshotInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Create snapshot response
|
||||
|
@ -45,6 +48,10 @@ public class CreateSnapshotResponse extends ActionResponse implements ToXContent
|
|||
CreateSnapshotResponse() {
|
||||
}
|
||||
|
||||
void setSnapshotInfo(SnapshotInfo snapshotInfo) {
|
||||
this.snapshotInfo = snapshotInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns snapshot information if snapshot was completed by the time this method returned or null otherwise.
|
||||
*
|
||||
|
@ -93,4 +100,58 @@ public class CreateSnapshotResponse extends ActionResponse implements ToXContent
|
|||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static CreateSnapshotResponse fromXContent(XContentParser parser) throws IOException {
|
||||
CreateSnapshotResponse createSnapshotResponse = new CreateSnapshotResponse();
|
||||
|
||||
parser.nextToken(); // move to '{'
|
||||
|
||||
if (parser.currentToken() != Token.START_OBJECT) {
|
||||
throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['{']");
|
||||
}
|
||||
|
||||
parser.nextToken(); // move to 'snapshot' || 'accepted'
|
||||
|
||||
if ("snapshot".equals(parser.currentName())) {
|
||||
createSnapshotResponse.snapshotInfo = SnapshotInfo.fromXContent(parser);
|
||||
} else if ("accepted".equals(parser.currentName())) {
|
||||
parser.nextToken(); // move to 'accepted' field value
|
||||
|
||||
if (parser.booleanValue()) {
|
||||
// ensure accepted is a boolean value
|
||||
}
|
||||
|
||||
parser.nextToken(); // move past 'true'/'false'
|
||||
} else {
|
||||
throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "] expected ['snapshot', 'accepted']");
|
||||
}
|
||||
|
||||
if (parser.currentToken() != Token.END_OBJECT) {
|
||||
throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['}']");
|
||||
}
|
||||
|
||||
parser.nextToken(); // move past '}'
|
||||
|
||||
return createSnapshotResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CreateSnapshotResponse{" +
|
||||
"snapshotInfo=" + snapshotInfo +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CreateSnapshotResponse that = (CreateSnapshotResponse) o;
|
||||
return Objects.equals(snapshotInfo, that.snapshotInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(snapshotInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,15 @@ package org.elasticsearch.action.support;
|
|||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -38,7 +41,7 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeSt
|
|||
* Controls how to deal with unavailable concrete indices (closed or missing), how wildcard expressions are expanded
|
||||
* to actual indices (all, closed or open indices) and how to deal with wildcard expressions that resolve to no indices.
|
||||
*/
|
||||
public class IndicesOptions {
|
||||
public class IndicesOptions implements ToXContentFragment {
|
||||
|
||||
public enum WildcardStates {
|
||||
OPEN,
|
||||
|
@ -313,6 +316,18 @@ public class IndicesOptions {
|
|||
defaultSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startArray("expand_wildcards");
|
||||
for (WildcardStates expandWildcard : expandWildcards) {
|
||||
builder.value(expandWildcard.toString().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
builder.endArray();
|
||||
builder.field("ignore_unavailable", ignoreUnavailable());
|
||||
builder.field("allow_no_indices", allowNoIndices());
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the name represents a valid name for one of the indices option
|
||||
* false otherwise
|
||||
|
|
|
@ -257,7 +257,7 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent imp
|
|||
indexMetaDataFormat = new ChecksumBlobStoreFormat<>(INDEX_METADATA_CODEC, METADATA_NAME_FORMAT,
|
||||
IndexMetaData::fromXContent, namedXContentRegistry, isCompress());
|
||||
snapshotFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT,
|
||||
SnapshotInfo::fromXContent, namedXContentRegistry, isCompress());
|
||||
SnapshotInfo::fromXContentInternal, namedXContentRegistry, isCompress());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,18 +23,23 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||
import org.elasticsearch.common.joda.Joda;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -79,6 +84,170 @@ public final class SnapshotInfo implements Comparable<SnapshotInfo>, ToXContent,
|
|||
private static final Comparator<SnapshotInfo> COMPARATOR =
|
||||
Comparator.comparing(SnapshotInfo::startTime).thenComparing(SnapshotInfo::snapshotId);
|
||||
|
||||
private static final class SnapshotInfoBuilder {
|
||||
private String snapshotName = null;
|
||||
private String snapshotUUID = null;
|
||||
private String state = null;
|
||||
private String reason = null;
|
||||
private List<String> indices = null;
|
||||
private long startTime = 0L;
|
||||
private long endTime = 0L;
|
||||
private ShardStatsBuilder shardStatsBuilder = null;
|
||||
private Boolean includeGlobalState = null;
|
||||
private int version = -1;
|
||||
private List<SnapshotShardFailure> shardFailures = null;
|
||||
|
||||
private void setSnapshotName(String snapshotName) {
|
||||
this.snapshotName = snapshotName;
|
||||
}
|
||||
|
||||
private void setSnapshotUUID(String snapshotUUID) {
|
||||
this.snapshotUUID = snapshotUUID;
|
||||
}
|
||||
|
||||
private void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
private void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
private void setIndices(List<String> indices) {
|
||||
this.indices = indices;
|
||||
}
|
||||
|
||||
private void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
private void setEndTime(long endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
private void setShardStatsBuilder(ShardStatsBuilder shardStatsBuilder) {
|
||||
this.shardStatsBuilder = shardStatsBuilder;
|
||||
}
|
||||
|
||||
private void setIncludeGlobalState(Boolean includeGlobalState) {
|
||||
this.includeGlobalState = includeGlobalState;
|
||||
}
|
||||
|
||||
private void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
private void setShardFailures(XContentParser parser) {
|
||||
if (shardFailures == null) {
|
||||
shardFailures = new ArrayList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
if (parser.currentToken() == Token.START_ARRAY) {
|
||||
parser.nextToken();
|
||||
}
|
||||
|
||||
while (parser.currentToken() != Token.END_ARRAY) {
|
||||
shardFailures.add(SnapshotShardFailure.fromXContent(parser));
|
||||
parser.nextToken();
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
throw new UncheckedIOException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void ignoreVersion(String version) {
|
||||
// ignore extra field
|
||||
}
|
||||
|
||||
private void ignoreStartTime(String startTime) {
|
||||
// ignore extra field
|
||||
}
|
||||
|
||||
private void ignoreEndTime(String endTime) {
|
||||
// ignore extra field
|
||||
}
|
||||
|
||||
private void ignoreDurationInMillis(long durationInMillis) {
|
||||
// ignore extra field
|
||||
}
|
||||
|
||||
private SnapshotInfo build() {
|
||||
SnapshotId snapshotId = new SnapshotId(snapshotName, snapshotUUID);
|
||||
|
||||
if (indices == null) {
|
||||
indices = Collections.emptyList();
|
||||
}
|
||||
|
||||
SnapshotState snapshotState = state == null ? null : SnapshotState.valueOf(state);
|
||||
Version version = this.version == -1 ? Version.CURRENT : Version.fromId(this.version);
|
||||
|
||||
int totalShards = shardStatsBuilder == null ? 0 : shardStatsBuilder.getTotalShards();
|
||||
int successfulShards = shardStatsBuilder == null ? 0 : shardStatsBuilder.getSuccessfulShards();
|
||||
|
||||
if (shardFailures == null) {
|
||||
shardFailures = new ArrayList<>();
|
||||
}
|
||||
|
||||
return new SnapshotInfo(snapshotId, indices, snapshotState, reason, version, startTime, endTime,
|
||||
totalShards, successfulShards, shardFailures, includeGlobalState);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ShardStatsBuilder {
|
||||
private int totalShards;
|
||||
private int successfulShards;
|
||||
|
||||
private void setTotalShards(int totalShards) {
|
||||
this.totalShards = totalShards;
|
||||
}
|
||||
|
||||
int getTotalShards() {
|
||||
return totalShards;
|
||||
}
|
||||
|
||||
private void setSuccessfulShards(int successfulShards) {
|
||||
this.successfulShards = successfulShards;
|
||||
}
|
||||
|
||||
int getSuccessfulShards() {
|
||||
return successfulShards;
|
||||
}
|
||||
|
||||
private void ignoreFailedShards(int failedShards) {
|
||||
// ignore extra field
|
||||
}
|
||||
}
|
||||
|
||||
private static final ObjectParser<SnapshotInfoBuilder, Void> SNAPSHOT_INFO_PARSER =
|
||||
new ObjectParser<>(SnapshotInfoBuilder.class.getName(), SnapshotInfoBuilder::new);
|
||||
|
||||
private static final ObjectParser<ShardStatsBuilder, Void> SHARD_STATS_PARSER =
|
||||
new ObjectParser<>(ShardStatsBuilder.class.getName(), ShardStatsBuilder::new);
|
||||
|
||||
static {
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotName, new ParseField(SNAPSHOT));
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setSnapshotUUID, new ParseField(UUID));
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setState, new ParseField(STATE));
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::setReason, new ParseField(REASON));
|
||||
SNAPSHOT_INFO_PARSER.declareStringArray(SnapshotInfoBuilder::setIndices, new ParseField(INDICES));
|
||||
SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::setStartTime, new ParseField(START_TIME_IN_MILLIS));
|
||||
SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::setEndTime, new ParseField(END_TIME_IN_MILLIS));
|
||||
SNAPSHOT_INFO_PARSER.declareObject(SnapshotInfoBuilder::setShardStatsBuilder, SHARD_STATS_PARSER, new ParseField(SHARDS));
|
||||
SNAPSHOT_INFO_PARSER.declareBoolean(SnapshotInfoBuilder::setIncludeGlobalState, new ParseField(INCLUDE_GLOBAL_STATE));
|
||||
SNAPSHOT_INFO_PARSER.declareInt(SnapshotInfoBuilder::setVersion, new ParseField(VERSION_ID));
|
||||
SNAPSHOT_INFO_PARSER.declareField(
|
||||
SnapshotInfoBuilder::setShardFailures, parser -> parser, new ParseField(FAILURES), ValueType.OBJECT_ARRAY_OR_STRING);
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreVersion, new ParseField(VERSION));
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreStartTime, new ParseField(START_TIME));
|
||||
SNAPSHOT_INFO_PARSER.declareString(SnapshotInfoBuilder::ignoreEndTime, new ParseField(END_TIME));
|
||||
SNAPSHOT_INFO_PARSER.declareLong(SnapshotInfoBuilder::ignoreDurationInMillis, new ParseField(DURATION_IN_MILLIS));
|
||||
|
||||
SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setTotalShards, new ParseField(TOTAL));
|
||||
SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::setSuccessfulShards, new ParseField(SUCCESSFUL));
|
||||
SHARD_STATS_PARSER.declareInt(ShardStatsBuilder::ignoreFailedShards, new ParseField(FAILED));
|
||||
}
|
||||
|
||||
private final SnapshotId snapshotId;
|
||||
|
||||
@Nullable
|
||||
|
@ -317,29 +486,21 @@ public final class SnapshotInfo implements Comparable<SnapshotInfo>, ToXContent,
|
|||
return COMPARATOR.compare(this, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SnapshotInfo that = (SnapshotInfo) o;
|
||||
return startTime == that.startTime && snapshotId.equals(that.snapshotId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = snapshotId.hashCode();
|
||||
result = 31 * result + Long.hashCode(startTime);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SnapshotInfo[snapshotId=" + snapshotId + ", state=" + state + ", indices=" + indices + "]";
|
||||
return "SnapshotInfo{" +
|
||||
"snapshotId=" + snapshotId +
|
||||
", state=" + state +
|
||||
", reason='" + reason + '\'' +
|
||||
", indices=" + indices +
|
||||
", startTime=" + startTime +
|
||||
", endTime=" + endTime +
|
||||
", totalShards=" + totalShards +
|
||||
", successfulShards=" + successfulShards +
|
||||
", includeGlobalState=" + includeGlobalState +
|
||||
", version=" + version +
|
||||
", shardFailures=" + shardFailures +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -448,12 +609,30 @@ public final class SnapshotInfo implements Comparable<SnapshotInfo>, ToXContent,
|
|||
return builder;
|
||||
}
|
||||
|
||||
public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException {
|
||||
parser.nextToken(); // // move to '{'
|
||||
|
||||
if (parser.currentToken() != Token.START_OBJECT) {
|
||||
throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['{']");
|
||||
}
|
||||
|
||||
SnapshotInfo snapshotInfo = SNAPSHOT_INFO_PARSER.apply(parser, null).build();
|
||||
|
||||
if (parser.currentToken() != Token.END_OBJECT) {
|
||||
throw new IllegalArgumentException("unexpected token [" + parser.currentToken() + "], expected ['}']");
|
||||
}
|
||||
|
||||
parser.nextToken(); // move past '}'
|
||||
|
||||
return snapshotInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a SnapshotInfo from internal x-content. It does not
|
||||
* handle x-content written with the external version as external x-content
|
||||
* is only for display purposes and does not need to be parsed.
|
||||
*/
|
||||
public static SnapshotInfo fromXContent(final XContentParser parser) throws IOException {
|
||||
public static SnapshotInfo fromXContentInternal(final XContentParser parser) throws IOException {
|
||||
String name = null;
|
||||
String uuid = null;
|
||||
Version version = Version.CURRENT;
|
||||
|
@ -607,4 +786,28 @@ public final class SnapshotInfo implements Comparable<SnapshotInfo>, ToXContent,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SnapshotInfo that = (SnapshotInfo) o;
|
||||
return startTime == that.startTime &&
|
||||
endTime == that.endTime &&
|
||||
totalShards == that.totalShards &&
|
||||
successfulShards == that.successfulShards &&
|
||||
Objects.equals(snapshotId, that.snapshotId) &&
|
||||
state == that.state &&
|
||||
Objects.equals(reason, that.reason) &&
|
||||
Objects.equals(indices, that.indices) &&
|
||||
Objects.equals(includeGlobalState, that.includeGlobalState) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(shardFailures, that.shardFailures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(snapshotId, state, reason, indices, startTime, endTime,
|
||||
totalShards, successfulShards, includeGlobalState, version, shardFailures);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException;
|
|||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Stores information about failures that occurred during shard snapshotting process
|
||||
|
@ -151,7 +152,12 @@ public class SnapshotShardFailure implements ShardOperationFailedException {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return shardId + " failed, reason [" + reason + "]";
|
||||
return "SnapshotShardFailure{" +
|
||||
"shardId=" + shardId +
|
||||
", reason='" + reason + '\'' +
|
||||
", nodeId='" + nodeId + '\'' +
|
||||
", status=" + status +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,4 +244,23 @@ public class SnapshotShardFailure implements ShardOperationFailedException {
|
|||
builder.field("status", status.name());
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SnapshotShardFailure that = (SnapshotShardFailure) o;
|
||||
// customized to account for discrepancies in shardId/Index toXContent/fromXContent related to uuid
|
||||
return shardId.id() == that.shardId.id() &&
|
||||
shardId.getIndexName().equals(shardId.getIndexName()) &&
|
||||
Objects.equals(reason, that.reason) &&
|
||||
Objects.equals(nodeId, that.nodeId) &&
|
||||
status.getStatus() == that.status.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// customized to account for discrepancies in shardId/Index toXContent/fromXContent related to uuid
|
||||
return Objects.hash(shardId.id(), shardId.getIndexName(), reason, nodeId, status.getStatus());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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.create;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateSnapshotRequestTests extends ESTestCase {
|
||||
|
||||
// tests creating XContent and parsing with source(Map) equivalency
|
||||
public void testToXContent() throws IOException {
|
||||
String repo = randomAlphaOfLength(5);
|
||||
String snap = randomAlphaOfLength(10);
|
||||
|
||||
CreateSnapshotRequest original = new CreateSnapshotRequest(repo, snap);
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
List<String> indices = new ArrayList<>();
|
||||
int count = randomInt(3) + 1;
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
indices.add(randomAlphaOfLength(randomInt(3) + 2));
|
||||
}
|
||||
|
||||
original.indices(indices);
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
original.partial(randomBoolean());
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
Map<String, Object> settings = new HashMap<>();
|
||||
int count = randomInt(3) + 1;
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
settings.put(randomAlphaOfLength(randomInt(3) + 2), randomAlphaOfLength(randomInt(3) + 2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
original.includeGlobalState(randomBoolean());
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
IndicesOptions[] indicesOptions = new IndicesOptions[] {
|
||||
IndicesOptions.STRICT_EXPAND_OPEN,
|
||||
IndicesOptions.STRICT_EXPAND_OPEN_CLOSED,
|
||||
IndicesOptions.LENIENT_EXPAND_OPEN,
|
||||
IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED,
|
||||
IndicesOptions.STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED};
|
||||
|
||||
original.indicesOptions(randomFrom(indicesOptions));
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
original.waitForCompletion(randomBoolean());
|
||||
}
|
||||
|
||||
if (randomBoolean()) { // replace
|
||||
original.masterNodeTimeout("60s");
|
||||
}
|
||||
|
||||
XContentBuilder builder = original.toXContent(XContentFactory.jsonBuilder(), null);
|
||||
XContentParser parser = XContentType.JSON.xContent().createParser(
|
||||
NamedXContentRegistry.EMPTY, null, BytesReference.bytes(builder).streamInput());
|
||||
Map<String, Object> map = parser.mapOrdered();
|
||||
CreateSnapshotRequest processed = new CreateSnapshotRequest((String)map.get("repository"), (String)map.get("snapshot"));
|
||||
processed.waitForCompletion((boolean)map.getOrDefault("wait_for_completion", false));
|
||||
processed.masterNodeTimeout((String)map.getOrDefault("master_node_timeout", "30s"));
|
||||
processed.source(map);
|
||||
|
||||
assertEquals(original, processed);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.create;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.snapshots.SnapshotId;
|
||||
import org.elasticsearch.snapshots.SnapshotInfo;
|
||||
import org.elasticsearch.snapshots.SnapshotShardFailure;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CreateSnapshotResponseTests extends AbstractXContentTestCase<CreateSnapshotResponse> {
|
||||
|
||||
@Override
|
||||
protected CreateSnapshotResponse doParseInstance(XContentParser parser) throws IOException {
|
||||
return CreateSnapshotResponse.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CreateSnapshotResponse createTestInstance() {
|
||||
SnapshotId snapshotId = new SnapshotId("test", UUID.randomUUID().toString());
|
||||
List<String> indices = new ArrayList<>();
|
||||
indices.add("test0");
|
||||
indices.add("test1");
|
||||
String reason = "reason";
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = startTime + 10000;
|
||||
int totalShards = randomIntBetween(1, 3);
|
||||
int successfulShards = randomIntBetween(0, totalShards);
|
||||
List<SnapshotShardFailure> shardFailures = new ArrayList<>();
|
||||
|
||||
for (int count = successfulShards; count < totalShards; ++count) {
|
||||
shardFailures.add(new SnapshotShardFailure(
|
||||
"node-id", new ShardId("index-" + count, UUID.randomUUID().toString(), randomInt()), "reason"));
|
||||
}
|
||||
|
||||
boolean globalState = randomBoolean();
|
||||
|
||||
CreateSnapshotResponse response = new CreateSnapshotResponse();
|
||||
response.setSnapshotInfo(
|
||||
new SnapshotInfo(snapshotId, indices, startTime, reason, endTime, totalShards, shardFailures, globalState));
|
||||
return response;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue