Skip to content

Commit

Permalink
Add Verify Repository High Level REST API (#30934)
Browse files Browse the repository at this point in the history
This commit adds Verify Repository, the associated docs and tests for
the high level REST API client. A few small changes to the Verify
Repository Response went into the commit as well.

Relates #27205
  • Loading branch information
hub-cap committed May 30, 2018
1 parent 5148f3b commit a57c0fc
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest;
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.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
Expand Down Expand Up @@ -758,6 +759,19 @@ static Request deleteRepository(DeleteRepositoryRequest deleteRepositoryRequest)
return request;
}

static Request verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest) {
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
.addPathPart(verifyRepositoryRequest.name())
.addPathPartAsIs("_verify")
.build();
Request request = new Request(HttpPost.METHOD_NAME, endpoint);

Params parameters = new Params(request);
parameters.withMasterTimeout(verifyRepositoryRequest.masterNodeTimeout());
parameters.withTimeout(verifyRepositoryRequest.timeout());
return request;
}

static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) throws IOException {
String endpoint = new EndpointBuilder().addPathPartAsIs("_template").addPathPart(putIndexTemplateRequest.name()).build();
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
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 java.io.IOException;

Expand Down Expand Up @@ -116,4 +118,28 @@ public void deleteRepositoryAsync(DeleteRepositoryRequest deleteRepositoryReques
restHighLevelClient.performRequestAsyncAndParseEntity(deleteRepositoryRequest, RequestConverters::deleteRepository,
DeleteRepositoryResponse::fromXContent, listener, emptySet(), headers);
}

/**
* Verifies a snapshot repository.
* <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 VerifyRepositoryResponse verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest, Header... headers)
throws IOException {
return restHighLevelClient.performRequestAndParseEntity(verifyRepositoryRequest, RequestConverters::verifyRepository,
VerifyRepositoryResponse::fromXContent, emptySet(), headers);
}

/**
* Asynchronously verifies a snapshot repository.
* <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 verifyRepositoryAsync(VerifyRepositoryRequest verifyRepositoryRequest,
ActionListener<VerifyRepositoryResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(verifyRepositoryRequest, RequestConverters::verifyRepository,
VerifyRepositoryResponse::fromXContent, listener, emptySet(), headers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest;
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.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
Expand Down Expand Up @@ -1665,6 +1666,21 @@ public void testDeleteRepository() {
assertNull(request.getEntity());
}

public void testVerifyRepository() {
Map<String, String> expectedParams = new HashMap<>();
String repository = randomIndicesNames(1, 1)[0];
String endpoint = "/_snapshot/" + repository + "/_verify";

VerifyRepositoryRequest verifyRepositoryRequest = new VerifyRepositoryRequest(repository);
setRandomMasterTimeout(verifyRepositoryRequest, expectedParams);
setRandomTimeout(verifyRepositoryRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);

Request request = RequestConverters.verifyRepository(verifyRepositoryRequest);
assertThat(endpoint, equalTo(request.getEndpoint()));
assertThat(HttpPost.METHOD_NAME, equalTo(request.getMethod()));
assertThat(expectedParams, equalTo(request.getParameters()));
}

public void testPutTemplateRequest() throws Exception {
Map<String, String> names = new HashMap<>();
names.put("log", "log");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
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.common.xcontent.XContentType;
import org.elasticsearch.repositories.fs.FsRepository;
import org.elasticsearch.rest.RestStatus;
Expand Down Expand Up @@ -86,10 +88,7 @@ public void testSnapshotGetRepositoriesNonExistent() {

public void testSnapshotDeleteRepository() throws IOException {
String repository = "test";
String repositorySettings = "{\"type\":\"fs\", \"settings\":{\"location\": \".\"}}";

highLevelClient().getLowLevelClient().performRequest("put", "_snapshot/" + repository,
Collections.emptyMap(), new StringEntity(repositorySettings, ContentType.APPLICATION_JSON));
assertTrue(createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged());

GetRepositoriesRequest request = new GetRepositoriesRequest();
GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepositories,
Expand All @@ -102,4 +101,14 @@ public void testSnapshotDeleteRepository() throws IOException {

assertTrue(deleteResponse.isAcknowledged());
}

public void testVerifyRepository() throws IOException {
PutRepositoryResponse putRepositoryResponse = createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}");
assertTrue(putRepositoryResponse.isAcknowledged());

VerifyRepositoryRequest request = new VerifyRepositoryRequest("test");
VerifyRepositoryResponse response = execute(request, highLevelClient().snapshot()::verifyRepository,
highLevelClient().snapshot()::verifyRepositoryAsync);
assertThat(response.getNodes().size(), equalTo(1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
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.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
Expand Down Expand Up @@ -297,6 +299,66 @@ public void onFailure(Exception e) {
}
}

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

// tag::verify-repository-request
VerifyRepositoryRequest request = new VerifyRepositoryRequest(repositoryName);
// end::verify-repository-request

// tag::verify-repository-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.masterNodeTimeout("1m"); // <2>
// end::verify-repository-request-masterTimeout
// tag::verify-repository-request-timeout
request.timeout(TimeValue.timeValueMinutes(1)); // <1>
request.timeout("1m"); // <2>
// end::verify-repository-request-timeout

// tag::verify-repository-execute
VerifyRepositoryResponse response = client.snapshot().verifyRepository(request);
// end::verify-repository-execute

// tag::verify-repository-response
List<VerifyRepositoryResponse.NodeView> repositoryMetaDataResponse = response.getNodes();
// end::verify-repository-response
assertThat(1, equalTo(repositoryMetaDataResponse.size()));
assertThat("node-0", equalTo(repositoryMetaDataResponse.get(0).getName()));
}

public void testSnapshotVerifyRepositoryAsync() throws InterruptedException {
RestHighLevelClient client = highLevelClient();
{
VerifyRepositoryRequest request = new VerifyRepositoryRequest(repositoryName);

// tag::verify-repository-execute-listener
ActionListener<VerifyRepositoryResponse> listener =
new ActionListener<VerifyRepositoryResponse>() {
@Override
public void onResponse(VerifyRepositoryResponse verifyRepositoryRestResponse) {
// <1>
}

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

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

// tag::verify-repository-execute-async
client.snapshot().verifyRepositoryAsync(request, listener); // <1>
// end::verify-repository-execute-async

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

private void createTestRepositories() throws IOException {
PutRepositoryRequest request = new PutRepositoryRequest(repositoryName);
request.type(FsRepository.TYPE);
Expand Down
81 changes: 81 additions & 0 deletions docs/java-rest/high-level/snapshot/verify_repository.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
[[java-rest-high-snapshot-verify-repository]]
=== Snapshot Verify Repository API

The Snapshot Verify Repository API allows to verify a registered repository.

[[java-rest-high-snapshot-verify-repository-request]]
==== Snapshot Verify Repository Request

A `VerifyRepositoryRequest`:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-request]
--------------------------------------------------

==== Optional Arguments
The following arguments can optionally be provided:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-timeout]
--------------------------------------------------
<1> Timeout to wait for the all the nodes to acknowledge the settings were applied
as a `TimeValue`
<2> Timeout to wait for the all the nodes to acknowledge the settings were applied
as a `String`

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-request-masterTimeout]
--------------------------------------------------
<1> Timeout to connect to the master node as a `TimeValue`
<2> Timeout to connect to the master node as a `String`

[[java-rest-high-snapshot-verify-repository-sync]]
==== Synchronous Execution

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-execute]
--------------------------------------------------

[[java-rest-high-snapshot-verify-repository-async]]
==== Asynchronous Execution

The asynchronous execution of a snapshot verify repository requires both the
`VerifyRepositoryRequest` instance and an `ActionListener` instance to be
passed to the asynchronous method:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-execute-async]
--------------------------------------------------
<1> The `VerifyRepositoryRequest` 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 `VerifyRepositoryResponse` looks like:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-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-verify-repository-response]]
==== Snapshot Verify Repository Response

The returned `VerifyRepositoryResponse` allows to retrieve information about the
executed operation as follows:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-response]
--------------------------------------------------
2 changes: 2 additions & 0 deletions docs/java-rest/high-level/supported-apis.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,12 @@ The Java High Level REST Client supports the following Snapshot APIs:
* <<java-rest-high-snapshot-get-repository>>
* <<java-rest-high-snapshot-create-repository>>
* <<java-rest-high-snapshot-delete-repository>>
* <<java-rest-high-snapshot-verify-repository>>

include::snapshot/get_repository.asciidoc[]
include::snapshot/create_repository.asciidoc[]
include::snapshot/delete_repository.asciidoc[]
include::snapshot/verify_repository.asciidoc[]

== Tasks APIs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.Arrays;
Expand Down Expand Up @@ -129,6 +130,12 @@ public int hashCode() {
private ClusterName clusterName;


private static final ObjectParser<VerifyRepositoryResponse, Void> PARSER =
new ObjectParser<>(VerifyRepositoryResponse.class.getName(), VerifyRepositoryResponse::new);
static {
PARSER.declareNamedObjects(VerifyRepositoryResponse::setNodes, NodeView.PARSER, new ParseField("nodes"));
}

VerifyRepositoryResponse() {
}

Expand Down Expand Up @@ -167,6 +174,10 @@ public ClusterName getClusterName() {
return clusterName;
}

protected void setNodes(List<NodeView> nodes) {
this.nodes = nodes.stream().map(n -> n.convertToDiscoveryNode()).collect(Collectors.toList());
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
Expand All @@ -187,8 +198,29 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
return builder;
}

public static VerifyRepositoryResponse fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}

@Override
public String toString() {
return Strings.toString(this);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VerifyRepositoryResponse other = (VerifyRepositoryResponse) obj;
return nodes.equals(other.nodes);
}

@Override
public int hashCode() {
return nodes.hashCode();
}
}
Loading

0 comments on commit a57c0fc

Please sign in to comment.