Skip to content

Commit b716b08

Browse files
authored
Add Verify Repository High Level REST API (#30934)
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
1 parent 96b4dae commit b716b08

File tree

9 files changed

+293
-4
lines changed

9 files changed

+293
-4
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest;
3434
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest;
3535
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
36+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
3637
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
3738
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3839
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
@@ -747,6 +748,19 @@ static Request deleteRepository(DeleteRepositoryRequest deleteRepositoryRequest)
747748
return request;
748749
}
749750

751+
static Request verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest) {
752+
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
753+
.addPathPart(verifyRepositoryRequest.name())
754+
.addPathPartAsIs("_verify")
755+
.build();
756+
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
757+
758+
Params parameters = new Params(request);
759+
parameters.withMasterTimeout(verifyRepositoryRequest.masterNodeTimeout());
760+
parameters.withTimeout(verifyRepositoryRequest.timeout());
761+
return request;
762+
}
763+
750764
static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) throws IOException {
751765
String endpoint = new EndpointBuilder().addPathPartAsIs("_template").addPathPart(putIndexTemplateRequest.name()).build();
752766
Request request = new Request(HttpPut.METHOD_NAME, endpoint);

client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
2828
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
2929
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse;
30+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
31+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
3032

3133
import java.io.IOException;
3234

@@ -116,4 +118,28 @@ public void deleteRepositoryAsync(DeleteRepositoryRequest deleteRepositoryReques
116118
restHighLevelClient.performRequestAsyncAndParseEntity(deleteRepositoryRequest, RequestConverters::deleteRepository,
117119
DeleteRepositoryResponse::fromXContent, listener, emptySet(), headers);
118120
}
121+
122+
/**
123+
* Verifies a snapshot repository.
124+
* <p>
125+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
126+
* API on elastic.co</a>
127+
*/
128+
public VerifyRepositoryResponse verifyRepository(VerifyRepositoryRequest verifyRepositoryRequest, Header... headers)
129+
throws IOException {
130+
return restHighLevelClient.performRequestAndParseEntity(verifyRepositoryRequest, RequestConverters::verifyRepository,
131+
VerifyRepositoryResponse::fromXContent, emptySet(), headers);
132+
}
133+
134+
/**
135+
* Asynchronously verifies a snapshot repository.
136+
* <p>
137+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
138+
* API on elastic.co</a>
139+
*/
140+
public void verifyRepositoryAsync(VerifyRepositoryRequest verifyRepositoryRequest,
141+
ActionListener<VerifyRepositoryResponse> listener, Header... headers) {
142+
restHighLevelClient.performRequestAsyncAndParseEntity(verifyRepositoryRequest, RequestConverters::verifyRepository,
143+
VerifyRepositoryResponse::fromXContent, listener, emptySet(), headers);
144+
}
119145
}

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest;
3434
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest;
3535
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
36+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
3637
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
3738
import org.elasticsearch.action.admin.indices.alias.Alias;
3839
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
@@ -1632,6 +1633,21 @@ public void testDeleteRepository() {
16321633
assertNull(request.getEntity());
16331634
}
16341635

1636+
public void testVerifyRepository() {
1637+
Map<String, String> expectedParams = new HashMap<>();
1638+
String repository = randomIndicesNames(1, 1)[0];
1639+
String endpoint = "/_snapshot/" + repository + "/_verify";
1640+
1641+
VerifyRepositoryRequest verifyRepositoryRequest = new VerifyRepositoryRequest(repository);
1642+
setRandomMasterTimeout(verifyRepositoryRequest, expectedParams);
1643+
setRandomTimeout(verifyRepositoryRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
1644+
1645+
Request request = RequestConverters.verifyRepository(verifyRepositoryRequest);
1646+
assertThat(endpoint, equalTo(request.getEndpoint()));
1647+
assertThat(HttpPost.METHOD_NAME, equalTo(request.getMethod()));
1648+
assertThat(expectedParams, equalTo(request.getParameters()));
1649+
}
1650+
16351651
public void testPutTemplateRequest() throws Exception {
16361652
Map<String, String> names = new HashMap<>();
16371653
names.put("log", "log");

client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
2929
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
3030
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse;
31+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
32+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
3133
import org.elasticsearch.common.xcontent.XContentType;
3234
import org.elasticsearch.repositories.fs.FsRepository;
3335
import org.elasticsearch.rest.RestStatus;
@@ -86,10 +88,7 @@ public void testSnapshotGetRepositoriesNonExistent() {
8688

8789
public void testSnapshotDeleteRepository() throws IOException {
8890
String repository = "test";
89-
String repositorySettings = "{\"type\":\"fs\", \"settings\":{\"location\": \".\"}}";
90-
91-
highLevelClient().getLowLevelClient().performRequest("put", "_snapshot/" + repository,
92-
Collections.emptyMap(), new StringEntity(repositorySettings, ContentType.APPLICATION_JSON));
91+
assertTrue(createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged());
9392

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

103102
assertTrue(deleteResponse.isAcknowledged());
104103
}
104+
105+
public void testVerifyRepository() throws IOException {
106+
PutRepositoryResponse putRepositoryResponse = createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}");
107+
assertTrue(putRepositoryResponse.isAcknowledged());
108+
109+
VerifyRepositoryRequest request = new VerifyRepositoryRequest("test");
110+
VerifyRepositoryResponse response = execute(request, highLevelClient().snapshot()::verifyRepository,
111+
highLevelClient().snapshot()::verifyRepositoryAsync);
112+
assertThat(response.getNodes().size(), equalTo(1));
113+
}
105114
}

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
2828
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
2929
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse;
30+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
31+
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
3032
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
3133
import org.elasticsearch.client.RestHighLevelClient;
3234
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
@@ -297,6 +299,66 @@ public void onFailure(Exception e) {
297299
}
298300
}
299301

302+
public void testSnapshotVerifyRepository() throws IOException {
303+
RestHighLevelClient client = highLevelClient();
304+
createTestRepositories();
305+
306+
// tag::verify-repository-request
307+
VerifyRepositoryRequest request = new VerifyRepositoryRequest(repositoryName);
308+
// end::verify-repository-request
309+
310+
// tag::verify-repository-request-masterTimeout
311+
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
312+
request.masterNodeTimeout("1m"); // <2>
313+
// end::verify-repository-request-masterTimeout
314+
// tag::verify-repository-request-timeout
315+
request.timeout(TimeValue.timeValueMinutes(1)); // <1>
316+
request.timeout("1m"); // <2>
317+
// end::verify-repository-request-timeout
318+
319+
// tag::verify-repository-execute
320+
VerifyRepositoryResponse response = client.snapshot().verifyRepository(request);
321+
// end::verify-repository-execute
322+
323+
// tag::verify-repository-response
324+
List<VerifyRepositoryResponse.NodeView> repositoryMetaDataResponse = response.getNodes();
325+
// end::verify-repository-response
326+
assertThat(1, equalTo(repositoryMetaDataResponse.size()));
327+
assertThat("node-0", equalTo(repositoryMetaDataResponse.get(0).getName()));
328+
}
329+
330+
public void testSnapshotVerifyRepositoryAsync() throws InterruptedException {
331+
RestHighLevelClient client = highLevelClient();
332+
{
333+
VerifyRepositoryRequest request = new VerifyRepositoryRequest(repositoryName);
334+
335+
// tag::verify-repository-execute-listener
336+
ActionListener<VerifyRepositoryResponse> listener =
337+
new ActionListener<VerifyRepositoryResponse>() {
338+
@Override
339+
public void onResponse(VerifyRepositoryResponse verifyRepositoryRestResponse) {
340+
// <1>
341+
}
342+
343+
@Override
344+
public void onFailure(Exception e) {
345+
// <2>
346+
}
347+
};
348+
// end::verify-repository-execute-listener
349+
350+
// Replace the empty listener by a blocking listener in test
351+
final CountDownLatch latch = new CountDownLatch(1);
352+
listener = new LatchedActionListener<>(listener, latch);
353+
354+
// tag::verify-repository-execute-async
355+
client.snapshot().verifyRepositoryAsync(request, listener); // <1>
356+
// end::verify-repository-execute-async
357+
358+
assertTrue(latch.await(30L, TimeUnit.SECONDS));
359+
}
360+
}
361+
300362
private void createTestRepositories() throws IOException {
301363
PutRepositoryRequest request = new PutRepositoryRequest(repositoryName);
302364
request.type(FsRepository.TYPE);
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
[[java-rest-high-snapshot-verify-repository]]
2+
=== Snapshot Verify Repository API
3+
4+
The Snapshot Verify Repository API allows to verify a registered repository.
5+
6+
[[java-rest-high-snapshot-verify-repository-request]]
7+
==== Snapshot Verify Repository Request
8+
9+
A `VerifyRepositoryRequest`:
10+
11+
["source","java",subs="attributes,callouts,macros"]
12+
--------------------------------------------------
13+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-request]
14+
--------------------------------------------------
15+
16+
==== Optional Arguments
17+
The following arguments can optionally be provided:
18+
19+
["source","java",subs="attributes,callouts,macros"]
20+
--------------------------------------------------
21+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[create-repository-request-timeout]
22+
--------------------------------------------------
23+
<1> Timeout to wait for the all the nodes to acknowledge the settings were applied
24+
as a `TimeValue`
25+
<2> Timeout to wait for the all the nodes to acknowledge the settings were applied
26+
as a `String`
27+
28+
["source","java",subs="attributes,callouts,macros"]
29+
--------------------------------------------------
30+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-request-masterTimeout]
31+
--------------------------------------------------
32+
<1> Timeout to connect to the master node as a `TimeValue`
33+
<2> Timeout to connect to the master node as a `String`
34+
35+
[[java-rest-high-snapshot-verify-repository-sync]]
36+
==== Synchronous Execution
37+
38+
["source","java",subs="attributes,callouts,macros"]
39+
--------------------------------------------------
40+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-execute]
41+
--------------------------------------------------
42+
43+
[[java-rest-high-snapshot-verify-repository-async]]
44+
==== Asynchronous Execution
45+
46+
The asynchronous execution of a snapshot verify repository requires both the
47+
`VerifyRepositoryRequest` instance and an `ActionListener` instance to be
48+
passed to the asynchronous method:
49+
50+
["source","java",subs="attributes,callouts,macros"]
51+
--------------------------------------------------
52+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-execute-async]
53+
--------------------------------------------------
54+
<1> The `VerifyRepositoryRequest` to execute and the `ActionListener`
55+
to use when the execution completes
56+
57+
The asynchronous method does not block and returns immediately. Once it is
58+
completed the `ActionListener` is called back using the `onResponse` method
59+
if the execution successfully completed or using the `onFailure` method if
60+
it failed.
61+
62+
A typical listener for `VerifyRepositoryResponse` looks like:
63+
64+
["source","java",subs="attributes,callouts,macros"]
65+
--------------------------------------------------
66+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-execute-listener]
67+
--------------------------------------------------
68+
<1> Called when the execution is successfully completed. The response is
69+
provided as an argument
70+
<2> Called in case of a failure. The raised exception is provided as an argument
71+
72+
[[java-rest-high-cluster-verify-repository-response]]
73+
==== Snapshot Verify Repository Response
74+
75+
The returned `VerifyRepositoryResponse` allows to retrieve information about the
76+
executed operation as follows:
77+
78+
["source","java",subs="attributes,callouts,macros"]
79+
--------------------------------------------------
80+
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[verify-repository-response]
81+
--------------------------------------------------

docs/java-rest/high-level/supported-apis.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,12 @@ The Java High Level REST Client supports the following Snapshot APIs:
118118
* <<java-rest-high-snapshot-get-repository>>
119119
* <<java-rest-high-snapshot-create-repository>>
120120
* <<java-rest-high-snapshot-delete-repository>>
121+
* <<java-rest-high-snapshot-verify-repository>>
121122

122123
include::snapshot/get_repository.asciidoc[]
123124
include::snapshot/create_repository.asciidoc[]
124125
include::snapshot/delete_repository.asciidoc[]
126+
include::snapshot/verify_repository.asciidoc[]
125127

126128
== Tasks APIs
127129

server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryResponse.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.elasticsearch.common.xcontent.ObjectParser;
3333
import org.elasticsearch.common.xcontent.ToXContentObject;
3434
import org.elasticsearch.common.xcontent.XContentBuilder;
35+
import org.elasticsearch.common.xcontent.XContentParser;
3536

3637
import java.io.IOException;
3738
import java.util.Arrays;
@@ -129,6 +130,12 @@ public int hashCode() {
129130
private ClusterName clusterName;
130131

131132

133+
private static final ObjectParser<VerifyRepositoryResponse, Void> PARSER =
134+
new ObjectParser<>(VerifyRepositoryResponse.class.getName(), VerifyRepositoryResponse::new);
135+
static {
136+
PARSER.declareNamedObjects(VerifyRepositoryResponse::setNodes, NodeView.PARSER, new ParseField("nodes"));
137+
}
138+
132139
VerifyRepositoryResponse() {
133140
}
134141

@@ -167,6 +174,10 @@ public ClusterName getClusterName() {
167174
return clusterName;
168175
}
169176

177+
protected void setNodes(List<NodeView> nodes) {
178+
this.nodes = nodes.stream().map(n -> n.convertToDiscoveryNode()).collect(Collectors.toList());
179+
}
180+
170181
@Override
171182
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
172183
builder.startObject();
@@ -187,8 +198,29 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
187198
return builder;
188199
}
189200

201+
public static VerifyRepositoryResponse fromXContent(XContentParser parser) {
202+
return PARSER.apply(parser, null);
203+
}
204+
190205
@Override
191206
public String toString() {
192207
return Strings.toString(this);
193208
}
209+
210+
@Override
211+
public boolean equals(Object obj) {
212+
if (obj == null) {
213+
return false;
214+
}
215+
if (getClass() != obj.getClass()) {
216+
return false;
217+
}
218+
VerifyRepositoryResponse other = (VerifyRepositoryResponse) obj;
219+
return nodes.equals(other.nodes);
220+
}
221+
222+
@Override
223+
public int hashCode() {
224+
return nodes.hashCode();
225+
}
194226
}

0 commit comments

Comments
 (0)