From 83f8327e1efe29349fca205f8545e3343e2c63eb Mon Sep 17 00:00:00 2001 From: Michael Basnight Date: Wed, 9 May 2018 07:25:23 -0500 Subject: [PATCH] Add GET Repository High Level REST API (#30362) This commit adds the Snapshot Client with a first API call within it, the get repositories call in snapshot/restore module. This also creates a snapshot namespace for the docs, as well as get repositories docs. Relates #27205 --- .../client/RequestConverters.java | 12 ++ .../client/RestHighLevelClient.java | 12 ++ .../elasticsearch/client/SnapshotClient.java | 70 +++++++++ .../client/RequestConvertersTests.java | 21 +++ .../org/elasticsearch/client/SnapshotIT.java | 82 +++++++++++ .../SnapshotClientDocumentationIT.java | 135 ++++++++++++++++++ .../snapshot/get_repository.asciidoc | 86 +++++++++++ .../high-level/supported-apis.asciidoc | 8 ++ .../get/GetRepositoriesResponse.java | 9 ++ 9 files changed, 435 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java create mode 100644 docs/java-rest/high-level/snapshot/get_repository.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index ceff6afdf8cee..103e7cd6784d4 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -29,6 +29,7 @@ import org.apache.http.entity.ContentType; import org.apache.lucene.util.BytesRef; import org.elasticsearch.action.DocWriteRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; 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; @@ -626,6 +627,17 @@ static Request indexPutSettings(UpdateSettingsRequest updateSettingsRequest) thr return request; } + static Request getRepositories(GetRepositoriesRequest getRepositoriesRequest) { + String[] repositories = getRepositoriesRequest.repositories() == null ? Strings.EMPTY_ARRAY : getRepositoriesRequest.repositories(); + String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot").addCommaSeparatedPathParts(repositories).build(); + Request request = new Request(HttpGet.METHOD_NAME, endpoint); + + Params parameters = new Params(request); + parameters.withMasterTimeout(getRepositoriesRequest.masterNodeTimeout()); + parameters.withLocal(getRepositoriesRequest.local()); + 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); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java index 9f28cd4c28489..4d5609e01d152 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java @@ -26,6 +26,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; @@ -187,6 +189,7 @@ public class RestHighLevelClient implements Closeable { private final IndicesClient indicesClient = new IndicesClient(this); private final ClusterClient clusterClient = new ClusterClient(this); + private final SnapshotClient snapshotClient = new SnapshotClient(this); /** * Creates a {@link RestHighLevelClient} given the low level {@link RestClientBuilder} that allows to build the @@ -250,6 +253,15 @@ public final ClusterClient cluster() { return clusterClient; } + /** + * Provides a {@link SnapshotClient} which can be used to access the Snapshot API. + * + * See Snapshot API on elastic.co + */ + public final SnapshotClient snapshot() { + return snapshotClient; + } + /** * Executes a bulk request using the Bulk API * diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java new file mode 100644 index 0000000000000..e526fbe7164f9 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java @@ -0,0 +1,70 @@ +/* + * 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.client; + +import org.apache.http.Header; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse; + +import java.io.IOException; + +import static java.util.Collections.emptySet; + +/** + * A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Snapshot API. + *

+ * See Snapshot API on elastic.co + */ +public final class SnapshotClient { + private final RestHighLevelClient restHighLevelClient; + + SnapshotClient(RestHighLevelClient restHighLevelClient) { + this.restHighLevelClient = restHighLevelClient; + } + + /** + * Gets a list of snapshot repositories. If the list of repositories is empty or it contains a single element "_all", all + * registered repositories are returned. + *

+ * See Snapshot and Restore + * API on elastic.co + */ + public GetRepositoriesResponse getRepositories(GetRepositoriesRequest getRepositoriesRequest, Header... headers) + throws IOException { + return restHighLevelClient.performRequestAndParseEntity(getRepositoriesRequest, RequestConverters::getRepositories, + GetRepositoriesResponse::fromXContent, emptySet(), headers); + } + + /** + * Asynchronously gets a list of snapshot repositories. If the list of repositories is empty or it contains a single element "_all", all + * registered repositories are returned. + *

+ * See Snapshot and Restore + * API on elastic.co + */ + public void getRepositoriesAsync(GetRepositoriesRequest getRepositoriesRequest, + ActionListener listener, Header... headers) { + restHighLevelClient.performRequestAsyncAndParseEntity(getRepositoriesRequest, RequestConverters::getRepositories, + GetRepositoriesResponse::fromXContent, listener, emptySet(), headers); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index 2d56c15d57246..5e6e6da7ece96 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -29,6 +29,7 @@ import org.apache.http.util.EntityUtils; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.DocWriteRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; @@ -1367,6 +1368,26 @@ public void testIndexPutSettings() throws IOException { assertEquals(expectedParams, request.getParameters()); } + public void testGetRepositories() { + Map expectedParams = new HashMap<>(); + StringBuilder endpoint = new StringBuilder("/_snapshot"); + + GetRepositoriesRequest getRepositoriesRequest = new GetRepositoriesRequest(); + setRandomMasterTimeout(getRepositoriesRequest, expectedParams); + setRandomLocal(getRepositoriesRequest, expectedParams); + + if (randomBoolean()) { + String[] entries = new String[] {"a", "b", "c"}; + getRepositoriesRequest.repositories(entries); + endpoint.append("/" + String.join(",", entries)); + } + + Request request = RequestConverters.getRepositories(getRepositoriesRequest); + assertThat(endpoint.toString(), equalTo(request.getEndpoint())); + assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod())); + assertThat(expectedParams, equalTo(request.getParameters())); + } + public void testPutTemplateRequest() throws Exception { Map names = new HashMap<>(); names.put("log", "log"); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java new file mode 100644 index 0000000000000..ab2c632bfeb58 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java @@ -0,0 +1,82 @@ +/* + * 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.client; + +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse; +import org.elasticsearch.rest.RestStatus; + +import java.io.IOException; +import java.util.Collections; + +import static org.hamcrest.Matchers.equalTo; + +public class SnapshotIT extends ESRestHighLevelClientTestCase { + + public void testModulesGetRepositoriesUsingParams() 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)); + + highLevelClient().getLowLevelClient().performRequest("put", "_snapshot/" + repository + "_other", Collections.emptyMap(), + new StringEntity(repositorySettings, ContentType.APPLICATION_JSON)); + + { + GetRepositoriesRequest request = new GetRepositoriesRequest(); + request.repositories(new String[]{repository}); + GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepositories, + highLevelClient().snapshot()::getRepositoriesAsync); + assertThat(1, equalTo(response.repositories().size())); + } + { + GetRepositoriesRequest request = new GetRepositoriesRequest(); + GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepositories, + highLevelClient().snapshot()::getRepositoriesAsync); + assertThat(2, equalTo(response.repositories().size())); + } + } + + public void testModulesGetDefaultRepositories() throws IOException { + String repositorySettings = "{\"type\":\"fs\", \"settings\":{\"location\": \".\"}}"; + GetRepositoriesRequest request = new GetRepositoriesRequest(); + + highLevelClient().getLowLevelClient().performRequest("put", "_snapshot/test", Collections.emptyMap(), + new StringEntity(repositorySettings, ContentType.APPLICATION_JSON)); + + GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepositories, + highLevelClient().snapshot()::getRepositoriesAsync); + assertThat(1, equalTo(response.repositories().size())); + } + + public void testModulesGetRepositoriesNonExistent() throws IOException { + String repository = "doesnotexist"; + GetRepositoriesRequest request = new GetRepositoriesRequest(new String[]{repository}); + ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(request, + highLevelClient().snapshot()::getRepositories, highLevelClient().snapshot()::getRepositoriesAsync)); + + assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(exception.getMessage(), equalTo( + "Elasticsearch exception [type=repository_missing_exception, reason=[" + repository + "] missing]")); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java new file mode 100644 index 0000000000000..1044cc9da3332 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -0,0 +1,135 @@ +/* + * 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.client.documentation; + +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.LatchedActionListener; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse; +import org.elasticsearch.client.ESRestHighLevelClientTestCase; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.cluster.metadata.RepositoryMetaData; +import org.elasticsearch.common.unit.TimeValue; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.Matchers.equalTo; + +/** + * This class is used to generate the Java Cluster API documentation. + * You need to wrap your code between two tags like: + * // tag::example + * // end::example + * + * Where example is your tag name. + * + * Then in the documentation, you can extract what is between tag and end tags with + * ["source","java",subs="attributes,callouts,macros"] + * -------------------------------------------------- + * include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[example] + * -------------------------------------------------- + * + * The column width of the code block is 84. If the code contains a line longer + * than 84, the line will be cut and a horizontal scroll bar will be displayed. + * (the code indentation of the tag is not included in the width) + */ +public class SnapshotClientDocumentationIT extends ESRestHighLevelClientTestCase { + + private static final String testRepository = "test_repository"; + + public void testSnapshotGetRepository() throws IOException { + RestHighLevelClient client = highLevelClient(); + + createTestRepositories(); + + // tag::get-repository-request + GetRepositoriesRequest request = new GetRepositoriesRequest(); + // end::get-repository-request + + // tag::get-repository-request-repositories + String [] repositories = new String[] { testRepository }; + request.repositories(repositories); // <1> + // end::get-repository-request-repositories + // tag::get-repository-request-local + request.local(true); // <1> + // end::get-repository-request-local + // tag::get-repository-request-masterTimeout + request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> + request.masterNodeTimeout("1m"); // <2> + // end::get-repository-request-masterTimeout + + // tag::get-repository-execute + GetRepositoriesResponse response = client.snapshot().getRepositories(request); + // end::get-repository-execute + + // tag::get-repository-response + List repositoryMetaDataResponse = response.repositories(); + // end::get-repository-response + assertThat(1, equalTo(repositoryMetaDataResponse.size())); + assertThat(testRepository, equalTo(repositoryMetaDataResponse.get(0).name())); + } + + public void testSnapshotGetRepositoryAsync() throws InterruptedException { + RestHighLevelClient client = highLevelClient(); + { + GetRepositoriesRequest request = new GetRepositoriesRequest(); + + // tag::get-repository-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse(GetRepositoriesResponse getRepositoriesResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::get-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::get-repository-execute-async + client.snapshot().getRepositoriesAsync(request, listener); // <1> + // end::get-repository-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + + } + + private void createTestRepositories() throws IOException { + RestHighLevelClient client = highLevelClient(); + String repositorySettings = "{\"type\":\"fs\", \"settings\":{\"location\": \".\"}}"; + highLevelClient().getLowLevelClient().performRequest("put", "_snapshot/" + testRepository, Collections.emptyMap(), + new StringEntity(repositorySettings, ContentType.APPLICATION_JSON)); + + } +} diff --git a/docs/java-rest/high-level/snapshot/get_repository.asciidoc b/docs/java-rest/high-level/snapshot/get_repository.asciidoc new file mode 100644 index 0000000000000..af006c66ab087 --- /dev/null +++ b/docs/java-rest/high-level/snapshot/get_repository.asciidoc @@ -0,0 +1,86 @@ +[[java-rest-high-snapshot-get-repository]] +=== Snapshot Get Repository API + +The Snapshot Get Repository API allows to retrieve information about a registered repository. + +[[java-rest-high-snapshot-get-repository-request]] +==== Snapshot Get Repository Request + +A `GetRepositoriesRequest`: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-request] +-------------------------------------------------- + +==== Optional Arguments +The following arguments can optionally be provided: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-request-repositories] +-------------------------------------------------- +<1> Sets the repositories to retrieve + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-request-local] +-------------------------------------------------- +<1> The `local` flag (defaults to `false`) controls whether the repositories need +to be looked up in the local cluster state or in the cluster state held by +the elected master node + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-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-get-repository-sync]] +==== Synchronous Execution + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-execute] +-------------------------------------------------- + +[[java-rest-high-snapshot-get-repository-async]] +==== Asynchronous Execution + +The asynchronous execution of a snapshot get repository requires both the +`GetRepositoriesRequest` instance and an `ActionListener` instance to be +passed to the asynchronous method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-execute-async] +-------------------------------------------------- +<1> The `GetRepositoriesRequest` 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 `GetRepositoriesResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-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-get-repository-response]] +==== Snapshot Get Repository Response + +The returned `GetRepositoriesResponse` allows to retrieve information about the +executed operation as follows: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[get-repository-response] +-------------------------------------------------- diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 68f2405e55671..c3988d8b0027e 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -100,3 +100,11 @@ The Java High Level REST Client supports the following Cluster APIs: * <> include::cluster/put_settings.asciidoc[] + +== Snapshot APIs + +The Java High Level REST Client supports the following Snapshot APIs: + +* <> + +include::snapshot/get_repository.asciidoc[] \ No newline at end of file diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java index a71f9fd8fd7cc..c1d1420eef8c8 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.repositories.get; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.RepositoriesMetaData; import org.elasticsearch.cluster.metadata.RepositoryMetaData; @@ -26,12 +27,15 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; import java.util.Collections; import java.util.Iterator; import java.util.List; +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + /** * Get repositories response */ @@ -74,4 +78,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } + + public static GetRepositoriesResponse fromXContent(XContentParser parser) throws IOException { + ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); + return new GetRepositoriesResponse(RepositoriesMetaData.fromXContent(parser)); + } }