Add Restore Snapshot High Level REST API
With this commit we add the restore snapshot API to the Java high level REST client. Relates #27205 Relates #32155
This commit is contained in:
parent
59cf600e03
commit
73a38895fd
|
@ -40,6 +40,7 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRequest
|
||||||
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||||
|
@ -980,6 +981,20 @@ final class RequestConverters {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Request restoreSnapshot(RestoreSnapshotRequest restoreSnapshotRequest) throws IOException {
|
||||||
|
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
|
||||||
|
.addPathPart(restoreSnapshotRequest.repository())
|
||||||
|
.addPathPart(restoreSnapshotRequest.snapshot())
|
||||||
|
.addPathPartAsIs("_restore")
|
||||||
|
.build();
|
||||||
|
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
|
||||||
|
Params parameters = new Params(request);
|
||||||
|
parameters.withMasterTimeout(restoreSnapshotRequest.masterNodeTimeout());
|
||||||
|
parameters.withWaitForCompletion(restoreSnapshotRequest.waitForCompletion());
|
||||||
|
request.setEntity(createEntity(restoreSnapshotRequest, REQUEST_BODY_CONTENT_TYPE));
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
|
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
|
||||||
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
|
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
|
||||||
.addPathPart(deleteSnapshotRequest.repository())
|
.addPathPart(deleteSnapshotRequest.repository())
|
||||||
|
|
|
@ -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.repositories.verify.VerifyRepositoryResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
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.create.CreateSnapshotResponse;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
|
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.status.SnapshotsStatusResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||||
|
@ -252,6 +254,36 @@ public final class SnapshotClient {
|
||||||
SnapshotsStatusResponse::fromXContent, listener, emptySet());
|
SnapshotsStatusResponse::fromXContent, listener, emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores a snapshot.
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||||
|
* API on elastic.co</a>
|
||||||
|
*
|
||||||
|
* @param restoreSnapshotRequest 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 RestoreSnapshotResponse restore(RestoreSnapshotRequest restoreSnapshotRequest, RequestOptions options) throws IOException {
|
||||||
|
return restHighLevelClient.performRequestAndParseEntity(restoreSnapshotRequest, RequestConverters::restoreSnapshot, options,
|
||||||
|
RestoreSnapshotResponse::fromXContent, emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously restores a snapshot.
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||||
|
* API on elastic.co</a>
|
||||||
|
*
|
||||||
|
* @param restoreSnapshotRequest 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 restoreAsync(RestoreSnapshotRequest restoreSnapshotRequest, RequestOptions options,
|
||||||
|
ActionListener<RestoreSnapshotResponse> listener) {
|
||||||
|
restHighLevelClient.performRequestAsyncAndParseEntity(restoreSnapshotRequest, RequestConverters::restoreSnapshot, options,
|
||||||
|
RestoreSnapshotResponse::fromXContent, listener, emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a snapshot.
|
* Deletes a snapshot.
|
||||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequ
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||||
|
@ -2198,6 +2199,31 @@ public class RequestConvertersTests extends ESTestCase {
|
||||||
assertThat(request.getEntity(), is(nullValue()));
|
assertThat(request.getEntity(), is(nullValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRestoreSnapshot() throws IOException {
|
||||||
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
|
String repository = randomIndicesNames(1, 1)[0];
|
||||||
|
String snapshot = "snapshot-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
|
||||||
|
String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s/_restore", repository, snapshot);
|
||||||
|
|
||||||
|
RestoreSnapshotRequest restoreSnapshotRequest = new RestoreSnapshotRequest(repository, snapshot);
|
||||||
|
setRandomMasterTimeout(restoreSnapshotRequest, expectedParams);
|
||||||
|
if (randomBoolean()) {
|
||||||
|
restoreSnapshotRequest.waitForCompletion(true);
|
||||||
|
expectedParams.put("wait_for_completion", "true");
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
String timeout = randomTimeValue();
|
||||||
|
restoreSnapshotRequest.masterNodeTimeout(timeout);
|
||||||
|
expectedParams.put("master_timeout", timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = RequestConverters.restoreSnapshot(restoreSnapshotRequest);
|
||||||
|
assertThat(endpoint, equalTo(request.getEndpoint()));
|
||||||
|
assertThat(HttpPost.METHOD_NAME, equalTo(request.getMethod()));
|
||||||
|
assertThat(expectedParams, equalTo(request.getParameters()));
|
||||||
|
assertToXContentBody(restoreSnapshotRequest, request.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
public void testDeleteSnapshot() {
|
public void testDeleteSnapshot() {
|
||||||
Map<String, String> expectedParams = new HashMap<>();
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
String repository = randomIndicesNames(1, 1)[0];
|
String repository = randomIndicesNames(1, 1)[0];
|
||||||
|
|
|
@ -665,7 +665,6 @@ public class RestHighLevelClientTests extends ESTestCase {
|
||||||
"reindex_rethrottle",
|
"reindex_rethrottle",
|
||||||
"render_search_template",
|
"render_search_template",
|
||||||
"scripts_painless_execute",
|
"scripts_painless_execute",
|
||||||
"snapshot.restore",
|
|
||||||
"tasks.get",
|
"tasks.get",
|
||||||
"termvectors",
|
"termvectors",
|
||||||
"update_by_query"
|
"update_by_query"
|
||||||
|
|
|
@ -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.put.PutRepositoryResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
|
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
|
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
|
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.status.SnapshotsStatusResponse;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
@ -40,12 +42,15 @@ import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.repositories.fs.FsRepository;
|
import org.elasticsearch.repositories.fs.FsRepository;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
import org.elasticsearch.snapshots.RestoreInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
||||||
|
@ -205,6 +210,42 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
||||||
assertThat(response.getSnapshots().get(0).getIndices().containsKey(testIndex), is(true));
|
assertThat(response.getSnapshots().get(0).getIndices().containsKey(testIndex), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRestoreSnapshot() throws IOException {
|
||||||
|
String testRepository = "test";
|
||||||
|
String testSnapshot = "snapshot_1";
|
||||||
|
String testIndex = "test_index";
|
||||||
|
String restoredIndex = testIndex + "_restored";
|
||||||
|
|
||||||
|
PutRepositoryResponse putRepositoryResponse = createTestRepository(testRepository, FsRepository.TYPE, "{\"location\": \".\"}");
|
||||||
|
assertTrue(putRepositoryResponse.isAcknowledged());
|
||||||
|
|
||||||
|
createIndex(testIndex, Settings.EMPTY);
|
||||||
|
assertTrue("index [" + testIndex + "] should have been created", indexExists(testIndex));
|
||||||
|
|
||||||
|
CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(testRepository, testSnapshot);
|
||||||
|
createSnapshotRequest.indices(testIndex);
|
||||||
|
createSnapshotRequest.waitForCompletion(true);
|
||||||
|
CreateSnapshotResponse createSnapshotResponse = createTestSnapshot(createSnapshotRequest);
|
||||||
|
assertEquals(RestStatus.OK, createSnapshotResponse.status());
|
||||||
|
|
||||||
|
deleteIndex(testIndex);
|
||||||
|
assertFalse("index [" + testIndex + "] should have been deleted", indexExists(testIndex));
|
||||||
|
|
||||||
|
RestoreSnapshotRequest request = new RestoreSnapshotRequest(testRepository, testSnapshot);
|
||||||
|
request.waitForCompletion(true);
|
||||||
|
request.renamePattern(testIndex);
|
||||||
|
request.renameReplacement(restoredIndex);
|
||||||
|
|
||||||
|
RestoreSnapshotResponse response = execute(request, highLevelClient().snapshot()::restore,
|
||||||
|
highLevelClient().snapshot()::restoreAsync);
|
||||||
|
|
||||||
|
RestoreInfo restoreInfo = response.getRestoreInfo();
|
||||||
|
assertThat(restoreInfo.name(), equalTo(testSnapshot));
|
||||||
|
assertThat(restoreInfo.indices(), equalTo(Collections.singletonList(restoredIndex)));
|
||||||
|
assertThat(restoreInfo.successfulShards(), greaterThan(0));
|
||||||
|
assertThat(restoreInfo.failedShards(), equalTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
public void testDeleteSnapshot() throws IOException {
|
public void testDeleteSnapshot() throws IOException {
|
||||||
String repository = "test_repository";
|
String repository = "test_repository";
|
||||||
String snapshot = "test_snapshot";
|
String snapshot = "test_snapshot";
|
||||||
|
|
|
@ -33,6 +33,8 @@ import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotReq
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
|
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
||||||
|
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
|
||||||
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
||||||
import org.elasticsearch.action.support.IndicesOptions;
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
|
||||||
|
@ -53,12 +55,15 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.repositories.fs.FsRepository;
|
import org.elasticsearch.repositories.fs.FsRepository;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
import org.elasticsearch.snapshots.RestoreInfo;
|
||||||
import org.elasticsearch.snapshots.SnapshotId;
|
import org.elasticsearch.snapshots.SnapshotId;
|
||||||
import org.elasticsearch.snapshots.SnapshotInfo;
|
import org.elasticsearch.snapshots.SnapshotInfo;
|
||||||
import org.elasticsearch.snapshots.SnapshotShardFailure;
|
import org.elasticsearch.snapshots.SnapshotShardFailure;
|
||||||
import org.elasticsearch.snapshots.SnapshotState;
|
import org.elasticsearch.snapshots.SnapshotState;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -263,6 +268,107 @@ public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRestoreSnapshot() throws IOException {
|
||||||
|
RestHighLevelClient client = highLevelClient();
|
||||||
|
|
||||||
|
createTestRepositories();
|
||||||
|
createTestIndex();
|
||||||
|
createTestSnapshots();
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request
|
||||||
|
RestoreSnapshotRequest request = new RestoreSnapshotRequest(repositoryName, snapshotName);
|
||||||
|
// end::restore-snapshot-request
|
||||||
|
// we need to restore as a different index name
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-masterTimeout
|
||||||
|
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
|
||||||
|
request.masterNodeTimeout("1m"); // <2>
|
||||||
|
// end::restore-snapshot-request-masterTimeout
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-waitForCompletion
|
||||||
|
request.waitForCompletion(true); // <1>
|
||||||
|
// end::restore-snapshot-request-waitForCompletion
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-partial
|
||||||
|
request.partial(false); // <1>
|
||||||
|
// end::restore-snapshot-request-partial
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-include-global-state
|
||||||
|
request.includeGlobalState(false); // <1>
|
||||||
|
// end::restore-snapshot-request-include-global-state
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-include-aliases
|
||||||
|
request.includeAliases(false); // <1>
|
||||||
|
// end::restore-snapshot-request-include-aliases
|
||||||
|
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-indices
|
||||||
|
request.indices("test_index");
|
||||||
|
// end::restore-snapshot-request-indices
|
||||||
|
|
||||||
|
String restoredIndexName = "restored_index";
|
||||||
|
// tag::restore-snapshot-request-rename
|
||||||
|
request.renamePattern("test_(.+)"); // <1>
|
||||||
|
request.renameReplacement("restored_$1"); // <2>
|
||||||
|
// end::restore-snapshot-request-rename
|
||||||
|
|
||||||
|
// tag::restore-snapshot-request-index-settings
|
||||||
|
request.indexSettings( // <1>
|
||||||
|
Settings.builder()
|
||||||
|
.put("index.number_of_replicas", 0)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
request.ignoreIndexSettings("index.refresh_interval", "index.search.idle.after"); // <2>
|
||||||
|
request.indicesOptions(new IndicesOptions( // <3>
|
||||||
|
EnumSet.of(IndicesOptions.Option.IGNORE_UNAVAILABLE),
|
||||||
|
EnumSet.of(IndicesOptions.WildcardStates.OPEN)));
|
||||||
|
// end::restore-snapshot-request-index-settings
|
||||||
|
|
||||||
|
// tag::restore-snapshot-execute
|
||||||
|
RestoreSnapshotResponse response = client.snapshot().restore(request, RequestOptions.DEFAULT);
|
||||||
|
// end::restore-snapshot-execute
|
||||||
|
|
||||||
|
// tag::restore-snapshot-response
|
||||||
|
RestoreInfo restoreInfo = response.getRestoreInfo();
|
||||||
|
List<String> indices = restoreInfo.indices(); // <1>
|
||||||
|
// end::restore-snapshot-response
|
||||||
|
assertEquals(Collections.singletonList(restoredIndexName), indices);
|
||||||
|
assertEquals(0, restoreInfo.failedShards());
|
||||||
|
assertTrue(restoreInfo.successfulShards() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRestoreSnapshotAsync() throws InterruptedException {
|
||||||
|
RestHighLevelClient client = highLevelClient();
|
||||||
|
{
|
||||||
|
RestoreSnapshotRequest request = new RestoreSnapshotRequest();
|
||||||
|
|
||||||
|
// tag::restore-snapshot-execute-listener
|
||||||
|
ActionListener<RestoreSnapshotResponse> listener =
|
||||||
|
new ActionListener<RestoreSnapshotResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(RestoreSnapshotResponse restoreSnapshotResponse) {
|
||||||
|
// <1>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Exception e) {
|
||||||
|
// <2>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// end::restore-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::restore-snapshot-execute-async
|
||||||
|
client.snapshot().restoreAsync(request, RequestOptions.DEFAULT, listener); // <1>
|
||||||
|
// end::restore-snapshot-execute-async
|
||||||
|
|
||||||
|
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testSnapshotDeleteRepository() throws IOException {
|
public void testSnapshotDeleteRepository() throws IOException {
|
||||||
RestHighLevelClient client = highLevelClient();
|
RestHighLevelClient client = highLevelClient();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
[[java-rest-high-snapshot-restore-snapshot]]
|
||||||
|
=== Restore Snapshot API
|
||||||
|
|
||||||
|
The Restore Snapshot API allows to restore a snapshot.
|
||||||
|
|
||||||
|
[[java-rest-high-snapshot-restore-snapshot-request]]
|
||||||
|
==== Restore Snapshot Request
|
||||||
|
|
||||||
|
A `RestoreSnapshotRequest`:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request]
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
==== Limiting Indices to Restore
|
||||||
|
|
||||||
|
By default all indices are restored. With the `indices` property you can
|
||||||
|
provide a list of indices that should be restored:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-indices]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Request that Elasticsearch only restores "test_index".
|
||||||
|
|
||||||
|
==== Renaming Indices
|
||||||
|
|
||||||
|
You can rename indices using regular expressions when restoring a snapshot:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-rename]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> A regular expression matching the indices that should be renamed.
|
||||||
|
<2> A replacement pattern that references the group from the regular
|
||||||
|
expression as `$1`. "test_index" from the snapshot is restored as
|
||||||
|
"restored_index" in this example.
|
||||||
|
|
||||||
|
==== Index Settings and Options
|
||||||
|
|
||||||
|
You can also customize index settings and options when restoring:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-index-settings]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Use `#indexSettings()` to set any specific index setting for the indices
|
||||||
|
that are restored.
|
||||||
|
<2> Use `#ignoreIndexSettings()` to provide index settings that should be
|
||||||
|
ignored from the original indices.
|
||||||
|
<3> Set `IndicesOptions.Option.IGNORE_UNAVAILABLE` in `#indicesOptions()` to
|
||||||
|
have the restore succeed even if indices are missing in the snapshot.
|
||||||
|
|
||||||
|
==== Further Arguments
|
||||||
|
|
||||||
|
The following arguments can optionally be provided:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-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[restore-snapshot-request-waitForCompletion]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Boolean indicating whether to wait until the snapshot has been restored.
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-partial]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Boolean indicating whether the entire snapshot should succeed although one
|
||||||
|
or more indices participating in the snapshot don’t have all primary
|
||||||
|
shards available.
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-include-global-state]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Boolean indicating whether restored templates that don’t currently exist
|
||||||
|
in the cluster are added and existing templates with the same name are
|
||||||
|
replaced by the restored templates. The restored persistent settings are
|
||||||
|
added to the existing persistent settings.
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-request-include-aliases]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Boolean to control whether aliases should be restored. Set to `false` to
|
||||||
|
prevent aliases from being restored together with associated indices.
|
||||||
|
|
||||||
|
[[java-rest-high-snapshot-restore-snapshot-sync]]
|
||||||
|
==== Synchronous Execution
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-execute]
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
[[java-rest-high-snapshot-restore-snapshot-async]]
|
||||||
|
==== Asynchronous Execution
|
||||||
|
|
||||||
|
The asynchronous execution of a restore snapshot request requires both the
|
||||||
|
`RestoreSnapshotRequest` instance and an `ActionListener` instance to be
|
||||||
|
passed to the asynchronous method:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-execute-async]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> The `RestoreSnapshotRequest` 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 `RestoreSnapshotResponse` looks like:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-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-cluster-restore-snapshot-response]]
|
||||||
|
==== Restore Snapshot Response
|
||||||
|
|
||||||
|
The returned `RestoreSnapshotResponse` allows to retrieve information about the
|
||||||
|
executed operation as follows:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[restore-snapshot-response]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> The `RestoreInfo` contains details about the restored snapshot like the indices or
|
||||||
|
the number of successfully restored and failed shards.
|
|
@ -27,14 +27,17 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||||
import static org.elasticsearch.common.settings.Settings.readSettingsFromStream;
|
import static org.elasticsearch.common.settings.Settings.readSettingsFromStream;
|
||||||
|
@ -45,7 +48,7 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBo
|
||||||
/**
|
/**
|
||||||
* Restore snapshot request
|
* Restore snapshot request
|
||||||
*/
|
*/
|
||||||
public class RestoreSnapshotRequest extends MasterNodeRequest<RestoreSnapshotRequest> {
|
public class RestoreSnapshotRequest extends MasterNodeRequest<RestoreSnapshotRequest> implements ToXContentObject {
|
||||||
|
|
||||||
private String snapshot;
|
private String snapshot;
|
||||||
private String repository;
|
private String repository;
|
||||||
|
@ -563,6 +566,49 @@ public class RestoreSnapshotRequest extends MasterNodeRequest<RestoreSnapshotReq
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startObject();
|
||||||
|
builder.startArray("indices");
|
||||||
|
for (String index : indices) {
|
||||||
|
builder.value(index);
|
||||||
|
}
|
||||||
|
builder.endArray();
|
||||||
|
if (indicesOptions != null) {
|
||||||
|
indicesOptions.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
if (renamePattern != null) {
|
||||||
|
builder.field("rename_pattern", renamePattern);
|
||||||
|
}
|
||||||
|
if (renameReplacement != null) {
|
||||||
|
builder.field("rename_replacement", renameReplacement);
|
||||||
|
}
|
||||||
|
builder.field("include_global_state", includeGlobalState);
|
||||||
|
builder.field("partial", partial);
|
||||||
|
builder.field("include_aliases", includeAliases);
|
||||||
|
if (settings != null) {
|
||||||
|
builder.startObject("settings");
|
||||||
|
if (settings.isEmpty() == false) {
|
||||||
|
settings.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
if (indexSettings != null) {
|
||||||
|
builder.startObject("index_settings");
|
||||||
|
if (indexSettings.isEmpty() == false) {
|
||||||
|
indexSettings.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
builder.startArray("ignore_index_settings");
|
||||||
|
for (String ignoreIndexSetting : ignoreIndexSettings) {
|
||||||
|
builder.value(ignoreIndexSetting);
|
||||||
|
}
|
||||||
|
builder.endArray();
|
||||||
|
builder.endObject();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
||||||
|
@ -573,4 +619,37 @@ public class RestoreSnapshotRequest extends MasterNodeRequest<RestoreSnapshotReq
|
||||||
return "snapshot [" + repository + ":" + snapshot + "]";
|
return "snapshot [" + repository + ":" + snapshot + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
RestoreSnapshotRequest that = (RestoreSnapshotRequest) o;
|
||||||
|
return waitForCompletion == that.waitForCompletion &&
|
||||||
|
includeGlobalState == that.includeGlobalState &&
|
||||||
|
partial == that.partial &&
|
||||||
|
includeAliases == that.includeAliases &&
|
||||||
|
Objects.equals(snapshot, that.snapshot) &&
|
||||||
|
Objects.equals(repository, that.repository) &&
|
||||||
|
Arrays.equals(indices, that.indices) &&
|
||||||
|
Objects.equals(indicesOptions, that.indicesOptions) &&
|
||||||
|
Objects.equals(renamePattern, that.renamePattern) &&
|
||||||
|
Objects.equals(renameReplacement, that.renameReplacement) &&
|
||||||
|
Objects.equals(settings, that.settings) &&
|
||||||
|
Objects.equals(indexSettings, that.indexSettings) &&
|
||||||
|
Arrays.equals(ignoreIndexSettings, that.ignoreIndexSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = Objects.hash(snapshot, repository, indicesOptions, renamePattern, renameReplacement, waitForCompletion,
|
||||||
|
includeGlobalState, partial, includeAliases, settings, indexSettings);
|
||||||
|
result = 31 * result + Arrays.hashCode(indices);
|
||||||
|
result = 31 * result + Arrays.hashCode(ignoreIndexSettings);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Strings.toString(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,21 @@ package org.elasticsearch.action.admin.cluster.snapshots.restore;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.snapshots.RestoreInfo;
|
import org.elasticsearch.snapshots.RestoreInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains information about restores snapshot
|
* Contains information about restores snapshot
|
||||||
|
@ -86,4 +92,42 @@ public class RestoreSnapshotResponse extends ActionResponse implements ToXConten
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final ConstructingObjectParser<RestoreSnapshotResponse, Void> PARSER = new ConstructingObjectParser<>(
|
||||||
|
"restore_snapshot", true, v -> {
|
||||||
|
RestoreInfo restoreInfo = (RestoreInfo) v[0];
|
||||||
|
Boolean accepted = (Boolean) v[1];
|
||||||
|
assert (accepted == null && restoreInfo != null) ||
|
||||||
|
(accepted != null && accepted && restoreInfo == null) :
|
||||||
|
"accepted: [" + accepted + "], restoreInfo: [" + restoreInfo + "]";
|
||||||
|
return new RestoreSnapshotResponse(restoreInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
static {
|
||||||
|
PARSER.declareObject(optionalConstructorArg(), (parser, context) -> RestoreInfo.fromXContent(parser), new ParseField("snapshot"));
|
||||||
|
PARSER.declareBoolean(optionalConstructorArg(), new ParseField("accepted"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static RestoreSnapshotResponse 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;
|
||||||
|
RestoreSnapshotResponse that = (RestoreSnapshotResponse) o;
|
||||||
|
return Objects.equals(restoreInfo, that.restoreInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(restoreInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RestoreSnapshotResponse{" + "restoreInfo=" + restoreInfo + '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,22 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.snapshots;
|
package org.elasticsearch.snapshots;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Streamable;
|
import org.elasticsearch.common.io.stream.Streamable;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent.Params;
|
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about successfully completed restore operation.
|
* Information about successfully completed restore operation.
|
||||||
|
@ -120,9 +124,6 @@ public class RestoreInfo implements ToXContentObject, Streamable {
|
||||||
static final String SUCCESSFUL = "successful";
|
static final String SUCCESSFUL = "successful";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
@ -141,9 +142,23 @@ public class RestoreInfo implements ToXContentObject, Streamable {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static final ObjectParser<RestoreInfo, Void> PARSER = new ObjectParser<>(RestoreInfo.class.getName(), true, RestoreInfo::new);
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
static {
|
||||||
|
ObjectParser<RestoreInfo, Void> shardsParser = new ObjectParser<>("shards", true, null);
|
||||||
|
shardsParser.declareInt((r, s) -> r.totalShards = s, new ParseField(Fields.TOTAL));
|
||||||
|
shardsParser.declareInt((r, s) -> { /* only consume, don't set */ }, new ParseField(Fields.FAILED));
|
||||||
|
shardsParser.declareInt((r, s) -> r.successfulShards = s, new ParseField(Fields.SUCCESSFUL));
|
||||||
|
|
||||||
|
PARSER.declareString((r, n) -> r.name = n, new ParseField(Fields.SNAPSHOT));
|
||||||
|
PARSER.declareStringArray((r, i) -> r.indices = i, new ParseField(Fields.INDICES));
|
||||||
|
PARSER.declareField(shardsParser::parse, new ParseField(Fields.SHARDS), ObjectParser.ValueType.OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RestoreInfo fromXContent(XContentParser parser) throws IOException {
|
||||||
|
return PARSER.parse(parser, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
name = in.readString();
|
name = in.readString();
|
||||||
|
@ -157,9 +172,6 @@ public class RestoreInfo implements ToXContentObject, Streamable {
|
||||||
successfulShards = in.readVInt();
|
successfulShards = in.readVInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
out.writeString(name);
|
out.writeString(name);
|
||||||
|
@ -193,4 +205,24 @@ public class RestoreInfo implements ToXContentObject, Streamable {
|
||||||
return in.readOptionalStreamable(RestoreInfo::new);
|
return in.readOptionalStreamable(RestoreInfo::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
RestoreInfo that = (RestoreInfo) o;
|
||||||
|
return totalShards == that.totalShards &&
|
||||||
|
successfulShards == that.successfulShards &&
|
||||||
|
Objects.equals(name, that.name) &&
|
||||||
|
Objects.equals(indices, that.indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, indices, totalShards, successfulShards);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Strings.toString(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* 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.restore;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
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.AbstractWireSerializingTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class RestoreSnapshotRequestTests extends AbstractWireSerializingTestCase<RestoreSnapshotRequest> {
|
||||||
|
private RestoreSnapshotRequest randomState(RestoreSnapshotRequest instance) {
|
||||||
|
if (randomBoolean()) {
|
||||||
|
List<String> indices = new ArrayList<>();
|
||||||
|
int count = randomInt(3) + 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
indices.add(randomAlphaOfLength(randomInt(3) + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.indices(indices);
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
instance.renamePattern(randomUnicodeOfLengthBetween(1, 100));
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
instance.renameReplacement(randomUnicodeOfLengthBetween(1, 100));
|
||||||
|
}
|
||||||
|
instance.partial(randomBoolean());
|
||||||
|
instance.includeAliases(randomBoolean());
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
Map<String, Object> settings = new HashMap<>();
|
||||||
|
int count = randomInt(3) + 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
settings.put(randomAlphaOfLengthBetween(2, 5), randomAlphaOfLengthBetween(2, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.settings(settings);
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
Map<String, Object> indexSettings = new HashMap<>();
|
||||||
|
int count = randomInt(3) + 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
indexSettings.put(randomAlphaOfLengthBetween(2, 5), randomAlphaOfLengthBetween(2, 5));;
|
||||||
|
}
|
||||||
|
instance.indexSettings(indexSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.includeGlobalState(randomBoolean());
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
Collection<IndicesOptions.WildcardStates> wildcardStates = randomSubsetOf(
|
||||||
|
Arrays.asList(IndicesOptions.WildcardStates.values()));
|
||||||
|
Collection<IndicesOptions.Option> options = randomSubsetOf(
|
||||||
|
Arrays.asList(IndicesOptions.Option.ALLOW_NO_INDICES, IndicesOptions.Option.IGNORE_UNAVAILABLE));
|
||||||
|
|
||||||
|
instance.indicesOptions(new IndicesOptions(
|
||||||
|
options.isEmpty() ? IndicesOptions.Option.NONE : EnumSet.copyOf(options),
|
||||||
|
wildcardStates.isEmpty() ? IndicesOptions.WildcardStates.NONE : EnumSet.copyOf(wildcardStates)));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.waitForCompletion(randomBoolean());
|
||||||
|
|
||||||
|
if (randomBoolean()) {
|
||||||
|
instance.masterNodeTimeout(randomTimeValue());
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RestoreSnapshotRequest createTestInstance() {
|
||||||
|
return randomState(new RestoreSnapshotRequest(randomAlphaOfLength(5), randomAlphaOfLength(10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Writeable.Reader<RestoreSnapshotRequest> instanceReader() {
|
||||||
|
return RestoreSnapshotRequest::new;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RestoreSnapshotRequest mutateInstance(RestoreSnapshotRequest instance) throws IOException {
|
||||||
|
RestoreSnapshotRequest copy = copyInstance(instance);
|
||||||
|
// ensure that at least one property is different
|
||||||
|
copy.repository("copied-" + instance.repository());
|
||||||
|
return randomState(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSource() throws IOException {
|
||||||
|
RestoreSnapshotRequest original = createTestInstance();
|
||||||
|
XContentBuilder builder = original.toXContent(XContentFactory.jsonBuilder(), new ToXContent.MapParams(Collections.emptyMap()));
|
||||||
|
XContentParser parser = XContentType.JSON.xContent().createParser(
|
||||||
|
NamedXContentRegistry.EMPTY, null, BytesReference.bytes(builder).streamInput());
|
||||||
|
Map<String, Object> map = parser.mapOrdered();
|
||||||
|
|
||||||
|
// we will only restore properties from the map that are contained in the request body. All other
|
||||||
|
// properties are restored from the original (in the actual REST action this is restored from the
|
||||||
|
// REST path and request parameters).
|
||||||
|
RestoreSnapshotRequest processed = new RestoreSnapshotRequest(original.repository(), original.snapshot());
|
||||||
|
processed.masterNodeTimeout(original.masterNodeTimeout());
|
||||||
|
processed.waitForCompletion(original.waitForCompletion());
|
||||||
|
|
||||||
|
processed.source(map);
|
||||||
|
|
||||||
|
assertEquals(original, processed);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.restore;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.snapshots.RestoreInfo;
|
||||||
|
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RestoreSnapshotResponseTests extends AbstractXContentTestCase<RestoreSnapshotResponse> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RestoreSnapshotResponse createTestInstance() {
|
||||||
|
if (randomBoolean()) {
|
||||||
|
String name = randomRealisticUnicodeOfCodepointLengthBetween(1, 30);
|
||||||
|
List<String> indices = new ArrayList<>();
|
||||||
|
indices.add("test0");
|
||||||
|
indices.add("test1");
|
||||||
|
int totalShards = randomIntBetween(1, 1000);
|
||||||
|
int successfulShards = randomIntBetween(0, totalShards);
|
||||||
|
return new RestoreSnapshotResponse(new RestoreInfo(name, indices, totalShards, successfulShards));
|
||||||
|
} else {
|
||||||
|
return new RestoreSnapshotResponse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RestoreSnapshotResponse doParseInstance(XContentParser parser) throws IOException {
|
||||||
|
return RestoreSnapshotResponse.fromXContent(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsUnknownFields() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -536,6 +536,11 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
client().performRequest(request);
|
client().performRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void deleteIndex(String name) throws IOException {
|
||||||
|
Request request = new Request("DELETE", "/" + name);
|
||||||
|
client().performRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
protected static void updateIndexSettings(String index, Settings.Builder settings) throws IOException {
|
protected static void updateIndexSettings(String index, Settings.Builder settings) throws IOException {
|
||||||
updateIndexSettings(index, settings.build());
|
updateIndexSettings(index, settings.build());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue