Skip to content

Commit 80be19a

Browse files
olcbeanjavanna
authored andcommitted
Add Open Index API to the high level REST client (#27574)
Add _open to the high level REST client Relates to #27205
1 parent c20cbe5 commit 80be19a

File tree

7 files changed

+238
-14
lines changed

7 files changed

+238
-14
lines changed

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
2626
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
2727
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
28+
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
29+
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
2830

2931
import java.io.IOException;
3032
import java.util.Collections;
@@ -72,7 +74,7 @@ public void deleteIndexAsync(DeleteIndexRequest deleteIndexRequest, ActionListen
7274
*/
7375
public CreateIndexResponse createIndex(CreateIndexRequest createIndexRequest, Header... headers) throws IOException {
7476
return restHighLevelClient.performRequestAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
75-
Collections.emptySet(), headers);
77+
Collections.emptySet(), headers);
7678
}
7779

7880
/**
@@ -86,4 +88,27 @@ public void createIndexAsync(CreateIndexRequest createIndexRequest, ActionListen
8688
restHighLevelClient.performRequestAsyncAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
8789
listener, Collections.emptySet(), headers);
8890
}
91+
92+
/**
93+
* Opens an index using the Open Index API
94+
* <p>
95+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html">
96+
* Open Index API on elastic.co</a>
97+
*/
98+
public OpenIndexResponse openIndex(OpenIndexRequest openIndexRequest, Header... headers) throws IOException {
99+
return restHighLevelClient.performRequestAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
100+
Collections.emptySet(), headers);
101+
}
102+
103+
/**
104+
* Asynchronously opens an index using the Open Index API
105+
* <p>
106+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html">
107+
* Open Index API on elastic.co</a>
108+
*/
109+
public void openIndexAsync(OpenIndexRequest openIndexRequest, ActionListener<OpenIndexResponse> listener, Header... headers) {
110+
restHighLevelClient.performRequestAsyncAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
111+
listener, Collections.emptySet(), headers);
112+
}
113+
89114
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.action.DocWriteRequest;
3232
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
3333
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
34+
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
3435
import org.elasticsearch.action.bulk.BulkRequest;
3536
import org.elasticsearch.action.delete.DeleteRequest;
3637
import org.elasticsearch.action.get.GetRequest;
@@ -138,6 +139,19 @@ static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
138139
return new Request(HttpDelete.METHOD_NAME, endpoint, parameters.getParams(), null);
139140
}
140141

142+
static Request openIndex(OpenIndexRequest openIndexRequest) {
143+
String endpoint = endpoint(openIndexRequest.indices(), Strings.EMPTY_ARRAY, "_open");
144+
145+
Params parameters = Params.builder();
146+
147+
parameters.withTimeout(openIndexRequest.timeout());
148+
parameters.withMasterTimeout(openIndexRequest.masterNodeTimeout());
149+
parameters.withWaitForActiveShards(openIndexRequest.waitForActiveShards());
150+
parameters.withIndicesOptions(openIndexRequest.indicesOptions());
151+
152+
return new Request(HttpPost.METHOD_NAME, endpoint, parameters.getParams(), null);
153+
}
154+
141155
static Request createIndex(CreateIndexRequest createIndexRequest) throws IOException {
142156
String endpoint = endpoint(createIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
143157

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.elasticsearch.action.ActionListener;
2727
import org.elasticsearch.action.ActionRequest;
2828
import org.elasticsearch.action.ActionRequestValidationException;
29+
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
30+
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
2931
import org.elasticsearch.action.bulk.BulkRequest;
3032
import org.elasticsearch.action.bulk.BulkResponse;
3133
import org.elasticsearch.action.delete.DeleteRequest;
@@ -283,7 +285,7 @@ public final GetResponse get(GetRequest getRequest, Header... headers) throws IO
283285
*
284286
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html">Get API on elastic.co</a>
285287
*/
286-
public void getAsync(GetRequest getRequest, ActionListener<GetResponse> listener, Header... headers) {
288+
public final void getAsync(GetRequest getRequest, ActionListener<GetResponse> listener, Header... headers) {
287289
performRequestAsyncAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, listener, singleton(404), headers);
288290
}
289291

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

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@
2525
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
2626
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
2727
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
28+
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
29+
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
30+
import org.elasticsearch.action.support.IndicesOptions;
31+
import org.elasticsearch.rest.RestStatus;
32+
33+
import java.io.IOException;
34+
import java.util.Locale;
35+
36+
import static org.hamcrest.Matchers.equalTo;
2837
import org.elasticsearch.common.settings.Settings;
2938
import org.elasticsearch.common.xcontent.XContentBuilder;
3039
import org.elasticsearch.common.xcontent.XContentHelper;
3140
import org.elasticsearch.common.xcontent.XContentType;
3241
import org.elasticsearch.common.xcontent.json.JsonXContent;
33-
import org.elasticsearch.rest.RestStatus;
3442

35-
import java.io.IOException;
3643
import java.util.Map;
3744

3845
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
@@ -128,16 +135,73 @@ public void testDeleteIndex() throws IOException {
128135
}
129136
}
130137

138+
public void testOpenExistingIndex() throws IOException {
139+
String[] indices = randomIndices(1, 5);
140+
for (String index : indices) {
141+
createIndex(index);
142+
closeIndex(index);
143+
ResponseException exception = expectThrows(ResponseException.class, () -> client().performRequest("GET", index + "/_search"));
144+
assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(RestStatus.BAD_REQUEST.getStatus()));
145+
assertThat(exception.getMessage().contains(index), equalTo(true));
146+
}
147+
148+
OpenIndexRequest openIndexRequest = new OpenIndexRequest(indices);
149+
OpenIndexResponse openIndexResponse = execute(openIndexRequest, highLevelClient().indices()::openIndex,
150+
highLevelClient().indices()::openIndexAsync);
151+
assertTrue(openIndexResponse.isAcknowledged());
152+
153+
for (String index : indices) {
154+
Response response = client().performRequest("GET", index + "/_search");
155+
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
156+
}
157+
}
158+
159+
public void testOpenNonExistentIndex() throws IOException {
160+
String[] nonExistentIndices = randomIndices(1, 5);
161+
for (String nonExistentIndex : nonExistentIndices) {
162+
assertFalse(indexExists(nonExistentIndex));
163+
}
164+
165+
OpenIndexRequest openIndexRequest = new OpenIndexRequest(nonExistentIndices);
166+
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
167+
() -> execute(openIndexRequest, highLevelClient().indices()::openIndex, highLevelClient().indices()::openIndexAsync));
168+
assertEquals(RestStatus.NOT_FOUND, exception.status());
169+
170+
OpenIndexRequest lenientOpenIndexRequest = new OpenIndexRequest(nonExistentIndices);
171+
lenientOpenIndexRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
172+
OpenIndexResponse lenientOpenIndexResponse = execute(lenientOpenIndexRequest, highLevelClient().indices()::openIndex,
173+
highLevelClient().indices()::openIndexAsync);
174+
assertThat(lenientOpenIndexResponse.isAcknowledged(), equalTo(true));
175+
176+
OpenIndexRequest strictOpenIndexRequest = new OpenIndexRequest(nonExistentIndices);
177+
strictOpenIndexRequest.indicesOptions(IndicesOptions.strictExpandOpen());
178+
ElasticsearchException strictException = expectThrows(ElasticsearchException.class,
179+
() -> execute(openIndexRequest, highLevelClient().indices()::openIndex, highLevelClient().indices()::openIndexAsync));
180+
assertEquals(RestStatus.NOT_FOUND, strictException.status());
181+
}
182+
183+
private static String[] randomIndices(int minIndicesNum, int maxIndicesNum) {
184+
int numIndices = randomIntBetween(minIndicesNum, maxIndicesNum);
185+
String[] indices = new String[numIndices];
186+
for (int i = 0; i < numIndices; i++) {
187+
indices[i] = "index-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
188+
}
189+
return indices;
190+
}
191+
131192
private static void createIndex(String index) throws IOException {
132193
Response response = client().performRequest("PUT", index);
133-
134-
assertEquals(200, response.getStatusLine().getStatusCode());
194+
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
135195
}
136196

137197
private static boolean indexExists(String index) throws IOException {
138198
Response response = client().performRequest("HEAD", index);
199+
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
200+
}
139201

140-
return response.getStatusLine().getStatusCode() == 200;
202+
private static void closeIndex(String index) throws IOException {
203+
Response response = client().performRequest("POST", index + "/_close");
204+
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
141205
}
142206

143207
@SuppressWarnings("unchecked")

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.action.DocWriteRequest;
2828
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
2929
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
30+
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
3031
import org.elasticsearch.action.bulk.BulkRequest;
3132
import org.elasticsearch.action.bulk.BulkShardRequest;
3233
import org.elasticsearch.action.delete.DeleteRequest;
@@ -37,7 +38,6 @@
3738
import org.elasticsearch.action.search.SearchRequest;
3839
import org.elasticsearch.action.search.SearchScrollRequest;
3940
import org.elasticsearch.action.search.SearchType;
40-
import org.elasticsearch.action.support.ActiveShardCount;
4141
import org.elasticsearch.action.support.IndicesOptions;
4242
import org.elasticsearch.action.support.WriteRequest;
4343
import org.elasticsearch.action.support.master.AcknowledgedRequest;
@@ -83,7 +83,6 @@
8383
import java.util.Locale;
8484
import java.util.Map;
8585
import java.util.StringJoiner;
86-
import java.util.function.BiConsumer;
8786
import java.util.function.Consumer;
8887
import java.util.function.Function;
8988
import java.util.function.Supplier;
@@ -93,10 +92,12 @@
9392
import static org.elasticsearch.client.Request.enforceSameContentType;
9493
import static org.elasticsearch.search.RandomSearchRequestGenerator.randomSearchRequest;
9594
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
95+
import static org.hamcrest.CoreMatchers.equalTo;
96+
import static org.hamcrest.Matchers.nullValue;
9697

9798
public class RequestTests extends ESTestCase {
9899

99-
public void testConstructor() throws Exception {
100+
public void testConstructor() {
100101
final String method = randomFrom("GET", "PUT", "POST", "HEAD", "DELETE");
101102
final String endpoint = randomAlphaOfLengthBetween(1, 10);
102103
final Map<String, String> parameters = singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5));
@@ -122,7 +123,7 @@ public void testConstructor() throws Exception {
122123
assertTrue("Request constructor is not public", Modifier.isPublic(constructors[0].getModifiers()));
123124
}
124125

125-
public void testClassVisibility() throws Exception {
126+
public void testClassVisibility() {
126127
assertTrue("Request class is not public", Modifier.isPublic(Request.class.getModifiers()));
127128
}
128129

@@ -146,7 +147,7 @@ public void testGet() {
146147
getAndExistsTest(Request::get, "GET");
147148
}
148149

149-
public void testDelete() throws IOException {
150+
public void testDelete() {
150151
String index = randomAlphaOfLengthBetween(3, 10);
151152
String type = randomAlphaOfLengthBetween(3, 10);
152153
String id = randomAlphaOfLengthBetween(3, 10);
@@ -283,7 +284,7 @@ public void testCreateIndex() throws IOException {
283284
assertToXContentBody(createIndexRequest, request.getEntity());
284285
}
285286

286-
public void testDeleteIndex() throws IOException {
287+
public void testDeleteIndex() {
287288
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest();
288289

289290
int numIndices = randomIntBetween(0, 5);
@@ -307,6 +308,29 @@ public void testDeleteIndex() throws IOException {
307308
assertNull(request.getEntity());
308309
}
309310

311+
public void testOpenIndex() {
312+
OpenIndexRequest openIndexRequest = new OpenIndexRequest();
313+
int numIndices = randomIntBetween(1, 5);
314+
String[] indices = new String[numIndices];
315+
for (int i = 0; i < numIndices; i++) {
316+
indices[i] = "index-" + randomAlphaOfLengthBetween(2, 5);
317+
}
318+
openIndexRequest.indices(indices);
319+
320+
Map<String, String> expectedParams = new HashMap<>();
321+
setRandomTimeout(openIndexRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
322+
setRandomMasterTimeout(openIndexRequest, expectedParams);
323+
setRandomIndicesOptions(openIndexRequest::indicesOptions, openIndexRequest::indicesOptions, expectedParams);
324+
setRandomWaitForActiveShards(openIndexRequest::waitForActiveShards, expectedParams);
325+
326+
Request request = Request.openIndex(openIndexRequest);
327+
StringJoiner endpoint = new StringJoiner("/", "/", "").add(String.join(",", indices)).add("_open");
328+
assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
329+
assertThat(expectedParams, equalTo(request.getParameters()));
330+
assertThat(request.getMethod(), equalTo("POST"));
331+
assertThat(request.getEntity(), nullValue());
332+
}
333+
310334
public void testIndex() throws IOException {
311335
String index = randomAlphaOfLengthBetween(3, 10);
312336
String type = randomAlphaOfLengthBetween(3, 10);

core/src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexResponse.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,34 @@
2121

2222
import org.elasticsearch.Version;
2323
import org.elasticsearch.action.support.master.AcknowledgedResponse;
24+
import org.elasticsearch.common.ParseField;
2425
import org.elasticsearch.common.io.stream.StreamInput;
2526
import org.elasticsearch.common.io.stream.StreamOutput;
27+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
28+
import org.elasticsearch.common.xcontent.ObjectParser;
29+
import org.elasticsearch.common.xcontent.ToXContentObject;
30+
import org.elasticsearch.common.xcontent.XContentBuilder;
31+
import org.elasticsearch.common.xcontent.XContentParser;
2632

2733
import java.io.IOException;
2834

35+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
36+
2937
/**
3038
* A response for a open index action.
3139
*/
32-
public class OpenIndexResponse extends AcknowledgedResponse {
40+
public class OpenIndexResponse extends AcknowledgedResponse implements ToXContentObject {
41+
private static final String SHARDS_ACKNOWLEDGED = "shards_acknowledged";
42+
private static final ParseField SHARDS_ACKNOWLEDGED_PARSER = new ParseField(SHARDS_ACKNOWLEDGED);
43+
44+
private static final ConstructingObjectParser<OpenIndexResponse, Void> PARSER = new ConstructingObjectParser<>("open_index", true,
45+
args -> new OpenIndexResponse((boolean) args[0], (boolean) args[1]));
46+
47+
static {
48+
declareAcknowledgedField(PARSER);
49+
PARSER.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), SHARDS_ACKNOWLEDGED_PARSER,
50+
ObjectParser.ValueType.BOOLEAN);
51+
}
3352

3453
private boolean shardsAcknowledged;
3554

@@ -68,4 +87,17 @@ public void writeTo(StreamOutput out) throws IOException {
6887
out.writeBoolean(shardsAcknowledged);
6988
}
7089
}
90+
91+
@Override
92+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
93+
builder.startObject();
94+
addAcknowledgedField(builder);
95+
builder.field(SHARDS_ACKNOWLEDGED, isShardsAcknowledged());
96+
builder.endObject();
97+
return builder;
98+
}
99+
100+
public static OpenIndexResponse fromXContent(XContentParser parser) throws IOException {
101+
return PARSER.apply(parser, null);
102+
}
71103
}

0 commit comments

Comments
 (0)