Adds snapshot clone REST tests and HLRC support for the API.
This commit is contained in:
parent
1287df4074
commit
1880bcdc09
|
@ -28,6 +28,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.repositories.verify.VerifyRepositoryResponse;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.clone.CloneSnapshotRequest;
|
||||
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;
|
||||
|
@ -236,6 +237,32 @@ public final class SnapshotClient {
|
|||
CreateSnapshotResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones 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 AcknowledgedResponse clone(CloneSnapshotRequest cloneSnapshotRequest, RequestOptions options)
|
||||
throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(cloneSnapshotRequest, SnapshotRequestConverters::cloneSnapshot, options,
|
||||
AcknowledgedResponse::fromXContent, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously clones 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>
|
||||
* @return cancellable that may be used to cancel the request
|
||||
*/
|
||||
public Cancellable cloneAsync(CloneSnapshotRequest cloneSnapshotRequest, RequestOptions options,
|
||||
ActionListener<AcknowledgedResponse> listener) {
|
||||
return restHighLevelClient.performRequestAsyncAndParseEntity(cloneSnapshotRequest,
|
||||
SnapshotRequestConverters::cloneSnapshot, options,
|
||||
AcknowledgedResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get snapshots.
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteReposito
|
|||
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest;
|
||||
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.clone.CloneSnapshotRequest;
|
||||
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.get.GetSnapshotsRequest;
|
||||
|
@ -123,6 +124,21 @@ final class SnapshotRequestConverters {
|
|||
return request;
|
||||
}
|
||||
|
||||
static Request cloneSnapshot(CloneSnapshotRequest cloneSnapshotRequest) throws IOException {
|
||||
String endpoint = new RequestConverters.EndpointBuilder().addPathPart("_snapshot")
|
||||
.addPathPart(cloneSnapshotRequest.repository())
|
||||
.addPathPart(cloneSnapshotRequest.source())
|
||||
.addPathPart("_clone")
|
||||
.addPathPart(cloneSnapshotRequest.target())
|
||||
.build();
|
||||
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
|
||||
RequestConverters.Params params = new RequestConverters.Params();
|
||||
params.withMasterTimeout(cloneSnapshotRequest.masterNodeTimeout());
|
||||
request.addParameters(params.asMap());
|
||||
request.setEntity(RequestConverters.createEntity(cloneSnapshotRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE));
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request getSnapshots(GetSnapshotsRequest getSnapshotsRequest) {
|
||||
RequestConverters.EndpointBuilder endpointBuilder = new RequestConverters.EndpointBuilder().addPathPartAsIs("_snapshot")
|
||||
.addPathPart(getSnapshotsRequest.repository());
|
||||
|
|
|
@ -28,6 +28,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.repositories.verify.VerifyRepositoryResponse;
|
||||
import org.elasticsearch.action.admin.cluster.snapshots.clone.CloneSnapshotRequest;
|
||||
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;
|
||||
|
@ -351,6 +352,30 @@ public class SnapshotIT extends ESRestHighLevelClientTestCase {
|
|||
assertTrue(response.isAcknowledged());
|
||||
}
|
||||
|
||||
public void testCloneSnapshot() throws IOException {
|
||||
String repository = "test_repository";
|
||||
String snapshot = "source_snapshot";
|
||||
String targetSnapshot = "target_snapshot";
|
||||
final String testIndex = "test_idx";
|
||||
|
||||
createIndex(testIndex, Settings.EMPTY);
|
||||
assertTrue("index [" + testIndex + "] should have been created", indexExists(testIndex));
|
||||
|
||||
AcknowledgedResponse putRepositoryResponse = createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}");
|
||||
assertTrue(putRepositoryResponse.isAcknowledged());
|
||||
|
||||
CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest(repository, snapshot);
|
||||
createSnapshotRequest.waitForCompletion(true);
|
||||
|
||||
CreateSnapshotResponse createSnapshotResponse = createTestSnapshot(createSnapshotRequest);
|
||||
assertEquals(RestStatus.OK, createSnapshotResponse.status());
|
||||
|
||||
CloneSnapshotRequest request = new CloneSnapshotRequest(repository, snapshot, targetSnapshot, new String[]{testIndex});
|
||||
AcknowledgedResponse response = execute(request, highLevelClient().snapshot()::clone, highLevelClient().snapshot()::cloneAsync);
|
||||
|
||||
assertTrue(response.isAcknowledged());
|
||||
}
|
||||
|
||||
private static Map<String, Object> randomUserMetadata() {
|
||||
if (randomBoolean()) {
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"snapshot.clone":{
|
||||
"documentation":{
|
||||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-snapshots.html",
|
||||
"description":"Clones indices from one snapshot into another snapshot in the same repository."
|
||||
},
|
||||
"stability":"stable",
|
||||
"url":{
|
||||
"paths":[
|
||||
{
|
||||
"path":"/_snapshot/{repository}/{snapshot}/_clone/{target_snapshot}",
|
||||
"methods":[
|
||||
"PUT"
|
||||
],
|
||||
"parts":{
|
||||
"repository":{
|
||||
"type":"string",
|
||||
"description":"A repository name"
|
||||
},
|
||||
"snapshot":{
|
||||
"type":"string",
|
||||
"description":"The name of the snapshot to clone from"
|
||||
},
|
||||
"target_snapshot":{
|
||||
"type":"string",
|
||||
"description":"The name of the cloned snapshot to create"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"params":{
|
||||
"master_timeout":{
|
||||
"type":"time",
|
||||
"description":"Explicit operation timeout for connection to master node"
|
||||
}
|
||||
},
|
||||
"body":{
|
||||
"description":"The snapshot clone definition",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
setup:
|
||||
|
||||
- do:
|
||||
snapshot.create_repository:
|
||||
repository: test_repo_create_1
|
||||
body:
|
||||
type: fs
|
||||
settings:
|
||||
location: "test_repo_create_1_loc"
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_index_1
|
||||
body:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 1
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_index_2
|
||||
body:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 1
|
||||
|
||||
- do:
|
||||
snapshot.create:
|
||||
repository: test_repo_create_1
|
||||
snapshot: test_snapshot
|
||||
wait_for_completion: true
|
||||
|
||||
---
|
||||
"Clone a snapshot":
|
||||
- skip:
|
||||
version: " - 7.9.99"
|
||||
reason: "Clone snapshot functionality was introduced in 7.10"
|
||||
- do:
|
||||
snapshot.clone:
|
||||
repository: test_repo_create_1
|
||||
snapshot: test_snapshot
|
||||
target_snapshot: target_snapshot_1
|
||||
body:
|
||||
"indices": test_index_2
|
||||
|
||||
- match: { acknowledged: true }
|
||||
|
||||
- do:
|
||||
snapshot.delete:
|
||||
repository: test_repo_create_1
|
||||
snapshot: target_snapshot_1
|
||||
|
||||
- match: { acknowledged: true }
|
|
@ -23,14 +23,17 @@ import org.elasticsearch.action.ActionRequestValidationException;
|
|||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.support.master.MasterNodeRequest;
|
||||
import org.elasticsearch.common.Strings;
|
||||
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 java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class CloneSnapshotRequest extends MasterNodeRequest<CloneSnapshotRequest> implements IndicesRequest.Replaceable{
|
||||
public class CloneSnapshotRequest extends MasterNodeRequest<CloneSnapshotRequest> implements IndicesRequest.Replaceable, ToXContentObject {
|
||||
|
||||
private final String repository;
|
||||
|
||||
|
@ -139,4 +142,29 @@ public class CloneSnapshotRequest extends MasterNodeRequest<CloneSnapshotRequest
|
|||
public String source() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field("repository", repository);
|
||||
builder.field("source", source);
|
||||
builder.field("target", target);
|
||||
if (indices != null) {
|
||||
builder.startArray("indices");
|
||||
for (String index : indices) {
|
||||
builder.value(index);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
if (indicesOptions != null) {
|
||||
indicesOptions.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Strings.toString(this);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue