From 80be19ab787b8e43639ec9d8095ef81ae5040322 Mon Sep 17 00:00:00 2001
From: olcbean <26058559+olcbean@users.noreply.github.com>
Date: Thu, 7 Dec 2017 18:16:03 +0100
Subject: [PATCH] Add Open Index API to the high level REST client (#27574)
Add _open to the high level REST client
Relates to #27205
---
.../elasticsearch/client/IndicesClient.java | 27 ++++++-
.../org/elasticsearch/client/Request.java | 14 ++++
.../client/RestHighLevelClient.java | 4 +-
.../elasticsearch/client/IndicesClientIT.java | 74 +++++++++++++++++--
.../elasticsearch/client/RequestTests.java | 36 +++++++--
.../admin/indices/open/OpenIndexResponse.java | 34 ++++++++-
.../indices/open/OpenIndexResponseTests.java | 63 ++++++++++++++++
7 files changed, 238 insertions(+), 14 deletions(-)
create mode 100644 core/src/test/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponseTests.java
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java
index c876731839984..57dafbba50994 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java
@@ -25,6 +25,8 @@
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
+import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
+import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import java.io.IOException;
import java.util.Collections;
@@ -72,7 +74,7 @@ public void deleteIndexAsync(DeleteIndexRequest deleteIndexRequest, ActionListen
*/
public CreateIndexResponse createIndex(CreateIndexRequest createIndexRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
- Collections.emptySet(), headers);
+ Collections.emptySet(), headers);
}
/**
@@ -86,4 +88,27 @@ public void createIndexAsync(CreateIndexRequest createIndexRequest, ActionListen
restHighLevelClient.performRequestAsyncAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
}
+
+ /**
+ * Opens an index using the Open Index API
+ *
+ * See
+ * Open Index API on elastic.co
+ */
+ public OpenIndexResponse openIndex(OpenIndexRequest openIndexRequest, Header... headers) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
+ Collections.emptySet(), headers);
+ }
+
+ /**
+ * Asynchronously opens an index using the Open Index API
+ *
+ * See
+ * Open Index API on elastic.co
+ */
+ public void openIndexAsync(OpenIndexRequest openIndexRequest, ActionListener listener, Header... headers) {
+ restHighLevelClient.performRequestAsyncAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
+ listener, Collections.emptySet(), headers);
+ }
+
}
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
index a3544ddb89b77..dd08179cf6297 100755
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
@@ -31,6 +31,7 @@
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
+import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
@@ -138,6 +139,19 @@ static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
return new Request(HttpDelete.METHOD_NAME, endpoint, parameters.getParams(), null);
}
+ static Request openIndex(OpenIndexRequest openIndexRequest) {
+ String endpoint = endpoint(openIndexRequest.indices(), Strings.EMPTY_ARRAY, "_open");
+
+ Params parameters = Params.builder();
+
+ parameters.withTimeout(openIndexRequest.timeout());
+ parameters.withMasterTimeout(openIndexRequest.masterNodeTimeout());
+ parameters.withWaitForActiveShards(openIndexRequest.waitForActiveShards());
+ parameters.withIndicesOptions(openIndexRequest.indicesOptions());
+
+ return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null);
+ }
+
static Request createIndex(CreateIndexRequest createIndexRequest) throws IOException {
String endpoint = endpoint(createIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
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 29ab7f90ff5c8..ca244eee88c62 100755
--- 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.indices.open.OpenIndexRequest;
+import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
@@ -283,7 +285,7 @@ public final GetResponse get(GetRequest getRequest, Header... headers) throws IO
*
* See Get API on elastic.co
*/
- public void getAsync(GetRequest getRequest, ActionListener listener, Header... headers) {
+ public final void getAsync(GetRequest getRequest, ActionListener listener, Header... headers) {
performRequestAsyncAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, listener, singleton(404), headers);
}
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java
index 0d6430b591294..5f356c4c29f5e 100755
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java
@@ -25,14 +25,21 @@
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
+import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
+import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.rest.RestStatus;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import static org.hamcrest.Matchers.equalTo;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
-import org.elasticsearch.rest.RestStatus;
-import java.io.IOException;
import java.util.Map;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
@@ -128,16 +135,73 @@ public void testDeleteIndex() throws IOException {
}
}
+ public void testOpenExistingIndex() throws IOException {
+ String[] indices = randomIndices(1, 5);
+ for (String index : indices) {
+ createIndex(index);
+ closeIndex(index);
+ ResponseException exception = expectThrows(ResponseException.class, () -> client().performRequest("GET", index + "/_search"));
+ assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(RestStatus.BAD_REQUEST.getStatus()));
+ assertThat(exception.getMessage().contains(index), equalTo(true));
+ }
+
+ OpenIndexRequest openIndexRequest = new OpenIndexRequest(indices);
+ OpenIndexResponse openIndexResponse = execute(openIndexRequest, highLevelClient().indices()::openIndex,
+ highLevelClient().indices()::openIndexAsync);
+ assertTrue(openIndexResponse.isAcknowledged());
+
+ for (String index : indices) {
+ Response response = client().performRequest("GET", index + "/_search");
+ assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+ }
+ }
+
+ public void testOpenNonExistentIndex() throws IOException {
+ String[] nonExistentIndices = randomIndices(1, 5);
+ for (String nonExistentIndex : nonExistentIndices) {
+ assertFalse(indexExists(nonExistentIndex));
+ }
+
+ OpenIndexRequest openIndexRequest = new OpenIndexRequest(nonExistentIndices);
+ ElasticsearchException exception = expectThrows(ElasticsearchException.class,
+ () -> execute(openIndexRequest, highLevelClient().indices()::openIndex, highLevelClient().indices()::openIndexAsync));
+ assertEquals(RestStatus.NOT_FOUND, exception.status());
+
+ OpenIndexRequest lenientOpenIndexRequest = new OpenIndexRequest(nonExistentIndices);
+ lenientOpenIndexRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
+ OpenIndexResponse lenientOpenIndexResponse = execute(lenientOpenIndexRequest, highLevelClient().indices()::openIndex,
+ highLevelClient().indices()::openIndexAsync);
+ assertThat(lenientOpenIndexResponse.isAcknowledged(), equalTo(true));
+
+ OpenIndexRequest strictOpenIndexRequest = new OpenIndexRequest(nonExistentIndices);
+ strictOpenIndexRequest.indicesOptions(IndicesOptions.strictExpandOpen());
+ ElasticsearchException strictException = expectThrows(ElasticsearchException.class,
+ () -> execute(openIndexRequest, highLevelClient().indices()::openIndex, highLevelClient().indices()::openIndexAsync));
+ assertEquals(RestStatus.NOT_FOUND, strictException.status());
+ }
+
+ private static String[] randomIndices(int minIndicesNum, int maxIndicesNum) {
+ int numIndices = randomIntBetween(minIndicesNum, maxIndicesNum);
+ String[] indices = new String[numIndices];
+ for (int i = 0; i < numIndices; i++) {
+ indices[i] = "index-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
+ }
+ return indices;
+ }
+
private static void createIndex(String index) throws IOException {
Response response = client().performRequest("PUT", index);
-
- assertEquals(200, response.getStatusLine().getStatusCode());
+ assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
}
private static boolean indexExists(String index) throws IOException {
Response response = client().performRequest("HEAD", index);
+ return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
+ }
- return response.getStatusLine().getStatusCode() == 200;
+ private static void closeIndex(String index) throws IOException {
+ Response response = client().performRequest("POST", index + "/_close");
+ assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
}
@SuppressWarnings("unchecked")
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
index 182de30fd1585..f39a7c77b80a4 100755
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
@@ -27,6 +27,7 @@
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
+import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
import org.elasticsearch.action.delete.DeleteRequest;
@@ -37,7 +38,6 @@
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.search.SearchType;
-import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
@@ -83,7 +83,6 @@
import java.util.Locale;
import java.util.Map;
import java.util.StringJoiner;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -93,10 +92,12 @@
import static org.elasticsearch.client.Request.enforceSameContentType;
import static org.elasticsearch.search.RandomSearchRequestGenerator.randomSearchRequest;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
public class RequestTests extends ESTestCase {
- public void testConstructor() throws Exception {
+ public void testConstructor() {
final String method = randomFrom("GET", "PUT", "POST", "HEAD", "DELETE");
final String endpoint = randomAlphaOfLengthBetween(1, 10);
final Map parameters = singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5));
@@ -122,7 +123,7 @@ public void testConstructor() throws Exception {
assertTrue("Request constructor is not public", Modifier.isPublic(constructors[0].getModifiers()));
}
- public void testClassVisibility() throws Exception {
+ public void testClassVisibility() {
assertTrue("Request class is not public", Modifier.isPublic(Request.class.getModifiers()));
}
@@ -146,7 +147,7 @@ public void testGet() {
getAndExistsTest(Request::get, "GET");
}
- public void testDelete() throws IOException {
+ public void testDelete() {
String index = randomAlphaOfLengthBetween(3, 10);
String type = randomAlphaOfLengthBetween(3, 10);
String id = randomAlphaOfLengthBetween(3, 10);
@@ -283,7 +284,7 @@ public void testCreateIndex() throws IOException {
assertToXContentBody(createIndexRequest, request.getEntity());
}
- public void testDeleteIndex() throws IOException {
+ public void testDeleteIndex() {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest();
int numIndices = randomIntBetween(0, 5);
@@ -307,6 +308,29 @@ public void testDeleteIndex() throws IOException {
assertNull(request.getEntity());
}
+ public void testOpenIndex() {
+ OpenIndexRequest openIndexRequest = new OpenIndexRequest();
+ int numIndices = randomIntBetween(1, 5);
+ String[] indices = new String[numIndices];
+ for (int i = 0; i < numIndices; i++) {
+ indices[i] = "index-" + randomAlphaOfLengthBetween(2, 5);
+ }
+ openIndexRequest.indices(indices);
+
+ Map expectedParams = new HashMap<>();
+ setRandomTimeout(openIndexRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
+ setRandomMasterTimeout(openIndexRequest, expectedParams);
+ setRandomIndicesOptions(openIndexRequest::indicesOptions, openIndexRequest::indicesOptions, expectedParams);
+ setRandomWaitForActiveShards(openIndexRequest::waitForActiveShards, expectedParams);
+
+ Request request = Request.openIndex(openIndexRequest);
+ StringJoiner endpoint = new StringJoiner("/", "/", "").add(String.join(",", indices)).add("_open");
+ assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
+ assertThat(expectedParams, equalTo(request.getParameters()));
+ assertThat(request.getMethod(), equalTo("POST"));
+ assertThat(request.getEntity(), nullValue());
+ }
+
public void testIndex() throws IOException {
String index = randomAlphaOfLengthBetween(3, 10);
String type = randomAlphaOfLengthBetween(3, 10);
diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponse.java b/core/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponse.java
index fe9343f363ff3..95fef9fc65344 100644
--- a/core/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponse.java
+++ b/core/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponse.java
@@ -21,15 +21,34 @@
import org.elasticsearch.Version;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.xcontent.ConstructingObjectParser;
+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 static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
+
/**
* A response for a open index action.
*/
-public class OpenIndexResponse extends AcknowledgedResponse {
+public class OpenIndexResponse extends AcknowledgedResponse implements ToXContentObject {
+ private static final String SHARDS_ACKNOWLEDGED = "shards_acknowledged";
+ private static final ParseField SHARDS_ACKNOWLEDGED_PARSER = new ParseField(SHARDS_ACKNOWLEDGED);
+
+ private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("open_index", true,
+ args -> new OpenIndexResponse((boolean) args[0], (boolean) args[1]));
+
+ static {
+ declareAcknowledgedField(PARSER);
+ PARSER.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), SHARDS_ACKNOWLEDGED_PARSER,
+ ObjectParser.ValueType.BOOLEAN);
+ }
private boolean shardsAcknowledged;
@@ -68,4 +87,17 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeBoolean(shardsAcknowledged);
}
}
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ addAcknowledgedField(builder);
+ builder.field(SHARDS_ACKNOWLEDGED, isShardsAcknowledged());
+ builder.endObject();
+ return builder;
+ }
+
+ public static OpenIndexResponse fromXContent(XContentParser parser) throws IOException {
+ return PARSER.apply(parser, null);
+ }
}
diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponseTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponseTests.java
new file mode 100644
index 0000000000000..09ceb7960347b
--- /dev/null
+++ b/core/src/test/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponseTests.java
@@ -0,0 +1,63 @@
+/*
+ * 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.indices.open;
+
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.test.ESTestCase;
+
+import java.io.IOException;
+
+import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
+import static org.hamcrest.CoreMatchers.equalTo;
+
+public class OpenIndexResponseTests extends ESTestCase {
+
+ public void testFromToXContent() throws IOException {
+ final OpenIndexResponse openIndexResponse = createTestItem();
+
+ boolean humanReadable = randomBoolean();
+ final XContentType xContentType = randomFrom(XContentType.values());
+ BytesReference originalBytes = toShuffledXContent(openIndexResponse, xContentType, ToXContent.EMPTY_PARAMS, humanReadable);
+ BytesReference mutated;
+ if (randomBoolean()) {
+ mutated = insertRandomFields(xContentType, originalBytes, null, random());
+ } else {
+ mutated = originalBytes;
+ }
+
+ OpenIndexResponse parsedOpenIndexResponse;
+ try (XContentParser parser = createParser(xContentType.xContent(), mutated)) {
+ parsedOpenIndexResponse = OpenIndexResponse.fromXContent(parser);
+ assertNull(parser.nextToken());
+ }
+
+ assertThat(parsedOpenIndexResponse.isShardsAcknowledged(), equalTo(openIndexResponse.isShardsAcknowledged()));
+ assertThat(parsedOpenIndexResponse.isAcknowledged(), equalTo(openIndexResponse.isAcknowledged()));
+ }
+
+ private static OpenIndexResponse createTestItem() {
+ boolean acknowledged = randomBoolean();
+ boolean shardsAcked = acknowledged && randomBoolean();
+ return new OpenIndexResponse(acknowledged, shardsAcked);
+ }
+}