Skip to content

Commit fd66c94

Browse files
authored
REST high-level client: add support for exists alias (elastic#28332)
Relates to elastic#27205
1 parent 45e1fe8 commit fd66c94

File tree

8 files changed

+278
-43
lines changed

8 files changed

+278
-43
lines changed

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

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.apache.http.Header;
2323
import org.elasticsearch.action.ActionListener;
24+
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
2425
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
2526
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
2627
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
@@ -35,7 +36,8 @@
3536
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
3637

3738
import java.io.IOException;
38-
import java.util.Collections;
39+
40+
import static java.util.Collections.emptySet;
3941

4042
/**
4143
* A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Indices API.
@@ -57,7 +59,7 @@ public final class IndicesClient {
5759
*/
5860
public DeleteIndexResponse delete(DeleteIndexRequest deleteIndexRequest, Header... headers) throws IOException {
5961
return restHighLevelClient.performRequestAndParseEntity(deleteIndexRequest, Request::deleteIndex, DeleteIndexResponse::fromXContent,
60-
Collections.emptySet(), headers);
62+
emptySet(), headers);
6163
}
6264

6365
/**
@@ -68,7 +70,7 @@ public DeleteIndexResponse delete(DeleteIndexRequest deleteIndexRequest, Header.
6870
*/
6971
public void deleteAsync(DeleteIndexRequest deleteIndexRequest, ActionListener<DeleteIndexResponse> listener, Header... headers) {
7072
restHighLevelClient.performRequestAsyncAndParseEntity(deleteIndexRequest, Request::deleteIndex, DeleteIndexResponse::fromXContent,
71-
listener, Collections.emptySet(), headers);
73+
listener, emptySet(), headers);
7274
}
7375

7476
/**
@@ -79,7 +81,7 @@ public void deleteAsync(DeleteIndexRequest deleteIndexRequest, ActionListener<De
7981
*/
8082
public CreateIndexResponse create(CreateIndexRequest createIndexRequest, Header... headers) throws IOException {
8183
return restHighLevelClient.performRequestAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
82-
Collections.emptySet(), headers);
84+
emptySet(), headers);
8385
}
8486

8587
/**
@@ -90,7 +92,7 @@ public CreateIndexResponse create(CreateIndexRequest createIndexRequest, Header.
9092
*/
9193
public void createAsync(CreateIndexRequest createIndexRequest, ActionListener<CreateIndexResponse> listener, Header... headers) {
9294
restHighLevelClient.performRequestAsyncAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
93-
listener, Collections.emptySet(), headers);
95+
listener, emptySet(), headers);
9496
}
9597

9698
/**
@@ -101,7 +103,7 @@ public void createAsync(CreateIndexRequest createIndexRequest, ActionListener<Cr
101103
*/
102104
public PutMappingResponse putMapping(PutMappingRequest putMappingRequest, Header... headers) throws IOException {
103105
return restHighLevelClient.performRequestAndParseEntity(putMappingRequest, Request::putMapping, PutMappingResponse::fromXContent,
104-
Collections.emptySet(), headers);
106+
emptySet(), headers);
105107
}
106108

107109
/**
@@ -113,7 +115,7 @@ public PutMappingResponse putMapping(PutMappingRequest putMappingRequest, Header
113115
public void putMappingAsync(PutMappingRequest putMappingRequest, ActionListener<PutMappingResponse> listener,
114116
Header... headers) {
115117
restHighLevelClient.performRequestAsyncAndParseEntity(putMappingRequest, Request::putMapping, PutMappingResponse::fromXContent,
116-
listener, Collections.emptySet(), headers);
118+
listener, emptySet(), headers);
117119
}
118120

119121
/**
@@ -125,7 +127,7 @@ public void putMappingAsync(PutMappingRequest putMappingRequest, ActionListener<
125127
*/
126128
public IndicesAliasesResponse updateAliases(IndicesAliasesRequest indicesAliasesRequest, Header... headers) throws IOException {
127129
return restHighLevelClient.performRequestAndParseEntity(indicesAliasesRequest, Request::updateAliases,
128-
IndicesAliasesResponse::fromXContent, Collections.emptySet(), headers);
130+
IndicesAliasesResponse::fromXContent, emptySet(), headers);
129131
}
130132

131133
/**
@@ -138,7 +140,7 @@ public IndicesAliasesResponse updateAliases(IndicesAliasesRequest indicesAliases
138140
public void updateAliasesAsync(IndicesAliasesRequest indicesAliasesRequestRequest, ActionListener<IndicesAliasesResponse> listener,
139141
Header... headers) {
140142
restHighLevelClient.performRequestAsyncAndParseEntity(indicesAliasesRequestRequest, Request::updateAliases,
141-
IndicesAliasesResponse::fromXContent, listener, Collections.emptySet(), headers);
143+
IndicesAliasesResponse::fromXContent, listener, emptySet(), headers);
142144
}
143145

144146
/**
@@ -149,7 +151,7 @@ public void updateAliasesAsync(IndicesAliasesRequest indicesAliasesRequestReques
149151
*/
150152
public OpenIndexResponse open(OpenIndexRequest openIndexRequest, Header... headers) throws IOException {
151153
return restHighLevelClient.performRequestAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
152-
Collections.emptySet(), headers);
154+
emptySet(), headers);
153155
}
154156

155157
/**
@@ -160,7 +162,7 @@ public OpenIndexResponse open(OpenIndexRequest openIndexRequest, Header... heade
160162
*/
161163
public void openAsync(OpenIndexRequest openIndexRequest, ActionListener<OpenIndexResponse> listener, Header... headers) {
162164
restHighLevelClient.performRequestAsyncAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
163-
listener, Collections.emptySet(), headers);
165+
listener, emptySet(), headers);
164166
}
165167

166168
/**
@@ -171,7 +173,7 @@ public void openAsync(OpenIndexRequest openIndexRequest, ActionListener<OpenInde
171173
*/
172174
public CloseIndexResponse close(CloseIndexRequest closeIndexRequest, Header... headers) throws IOException {
173175
return restHighLevelClient.performRequestAndParseEntity(closeIndexRequest, Request::closeIndex, CloseIndexResponse::fromXContent,
174-
Collections.emptySet(), headers);
176+
emptySet(), headers);
175177
}
176178

177179
/**
@@ -182,6 +184,28 @@ public CloseIndexResponse close(CloseIndexRequest closeIndexRequest, Header... h
182184
*/
183185
public void closeAsync(CloseIndexRequest closeIndexRequest, ActionListener<CloseIndexResponse> listener, Header... headers) {
184186
restHighLevelClient.performRequestAsyncAndParseEntity(closeIndexRequest, Request::closeIndex, CloseIndexResponse::fromXContent,
185-
listener, Collections.emptySet(), headers);
187+
listener, emptySet(), headers);
188+
}
189+
190+
/**
191+
* Checks if one or more aliases exist using the Aliases Exist API
192+
* <p>
193+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
194+
* Indices Aliases API on elastic.co</a>
195+
*/
196+
public boolean existsAlias(GetAliasesRequest getAliasesRequest, Header... headers) throws IOException {
197+
return restHighLevelClient.performRequest(getAliasesRequest, Request::existsAlias, RestHighLevelClient::convertExistsResponse,
198+
emptySet(), headers);
199+
}
200+
201+
/**
202+
* Asynchronously checks if one or more aliases exist using the Aliases Exist API
203+
* <p>
204+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
205+
* Indices Aliases API on elastic.co</a>
206+
*/
207+
public void existsAliasAsync(GetAliasesRequest getAliasesRequest, ActionListener<Boolean> listener, Header... headers) {
208+
restHighLevelClient.performRequestAsync(getAliasesRequest, Request::existsAlias, RestHighLevelClient::convertExistsResponse,
209+
listener, emptySet(), headers);
186210
}
187211
}

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

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.http.entity.ContentType;
3030
import org.apache.lucene.util.BytesRef;
3131
import org.elasticsearch.action.DocWriteRequest;
32+
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
3233
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
3334
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3435
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
@@ -133,7 +134,7 @@ static Request delete(DeleteRequest deleteRequest) {
133134
}
134135

135136
static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
136-
String endpoint = endpoint(deleteIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
137+
String endpoint = endpoint(deleteIndexRequest.indices());
137138

138139
Params parameters = Params.builder();
139140
parameters.withTimeout(deleteIndexRequest.timeout());
@@ -144,7 +145,7 @@ static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
144145
}
145146

146147
static Request openIndex(OpenIndexRequest openIndexRequest) {
147-
String endpoint = endpoint(openIndexRequest.indices(), Strings.EMPTY_ARRAY, "_open");
148+
String endpoint = endpoint(openIndexRequest.indices(), "_open");
148149

149150
Params parameters = Params.builder();
150151

@@ -157,7 +158,7 @@ static Request openIndex(OpenIndexRequest openIndexRequest) {
157158
}
158159

159160
static Request closeIndex(CloseIndexRequest closeIndexRequest) {
160-
String endpoint = endpoint(closeIndexRequest.indices(), Strings.EMPTY_ARRAY, "_close");
161+
String endpoint = endpoint(closeIndexRequest.indices(), "_close");
161162

162163
Params parameters = Params.builder();
163164

@@ -169,7 +170,7 @@ static Request closeIndex(CloseIndexRequest closeIndexRequest) {
169170
}
170171

171172
static Request createIndex(CreateIndexRequest createIndexRequest) throws IOException {
172-
String endpoint = endpoint(createIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
173+
String endpoint = endpoint(createIndexRequest.indices());
173174

174175
Params parameters = Params.builder();
175176
parameters.withTimeout(createIndexRequest.timeout());
@@ -472,23 +473,54 @@ static Request multiSearch(MultiSearchRequest multiSearchRequest) throws IOExcep
472473
return new Request(HttpPost.METHOD_NAME, "/_msearch", params.getParams(), entity);
473474
}
474475

476+
static Request existsAlias(GetAliasesRequest getAliasesRequest) {
477+
Params params = Params.builder();
478+
params.withIndicesOptions(getAliasesRequest.indicesOptions());
479+
params.withLocal(getAliasesRequest.local());
480+
if (getAliasesRequest.indices().length == 0 && getAliasesRequest.aliases().length == 0) {
481+
throw new IllegalArgumentException("existsAlias requires at least an alias or an index");
482+
}
483+
String endpoint = endpoint(getAliasesRequest.indices(), "_alias", getAliasesRequest.aliases());
484+
return new Request("HEAD", endpoint, params.getParams(), null);
485+
}
486+
475487
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
476488
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
477489
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
478490
}
479491

492+
static String endpoint(String index, String type, String id) {
493+
return buildEndpoint(index, type, id);
494+
}
495+
496+
static String endpoint(String index, String type, String id, String endpoint) {
497+
return buildEndpoint(index, type, id, endpoint);
498+
}
499+
500+
static String endpoint(String[] indices) {
501+
return buildEndpoint(String.join(",", indices));
502+
}
503+
504+
static String endpoint(String[] indices, String endpoint) {
505+
return buildEndpoint(String.join(",", indices), endpoint);
506+
}
507+
480508
static String endpoint(String[] indices, String[] types, String endpoint) {
481-
return endpoint(String.join(",", indices), String.join(",", types), endpoint);
509+
return buildEndpoint(String.join(",", indices), String.join(",", types), endpoint);
510+
}
511+
512+
static String endpoint(String[] indices, String endpoint, String[] suffixes) {
513+
return buildEndpoint(String.join(",", indices), endpoint, String.join(",", suffixes));
482514
}
483515

484516
static String endpoint(String[] indices, String endpoint, String type) {
485517
return endpoint(String.join(",", indices), endpoint, type);
486518
}
487519

488520
/**
489-
* Utility method to build request's endpoint.
521+
* Utility method to build request's endpoint given its parts as strings
490522
*/
491-
static String endpoint(String... parts) {
523+
static String buildEndpoint(String... parts) {
492524
StringJoiner joiner = new StringJoiner("/", "/", "");
493525
for (String part : parts) {
494526
if (Strings.hasLength(part)) {
@@ -656,6 +688,11 @@ Params withIndicesOptions(IndicesOptions indicesOptions) {
656688
return this;
657689
}
658690

691+
Params withLocal(boolean local) {
692+
putParam("local", Boolean.toString(local));
693+
return this;
694+
}
695+
659696
Map<String, String> getParams() {
660697
return Collections.unmodifiableMap(params);
661698
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.ElasticsearchException;
2323
import org.elasticsearch.ElasticsearchStatusException;
2424
import org.elasticsearch.action.admin.indices.alias.Alias;
25+
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
2526
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
2627
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
2728
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
@@ -353,6 +354,22 @@ private static boolean aliasExists(String index, String alias) throws IOExceptio
353354
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
354355
}
355356

357+
public void testExistsAlias() throws IOException {
358+
GetAliasesRequest getAliasesRequest = new GetAliasesRequest("alias");
359+
assertFalse(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
360+
361+
createIndex("index");
362+
client().performRequest("PUT", "/index/_alias/alias");
363+
assertTrue(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
364+
365+
GetAliasesRequest getAliasesRequest2 = new GetAliasesRequest();
366+
getAliasesRequest2.aliases("alias");
367+
getAliasesRequest2.indices("index");
368+
assertTrue(execute(getAliasesRequest2, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
369+
getAliasesRequest2.indices("does_not_exist");
370+
assertFalse(execute(getAliasesRequest2, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
371+
}
372+
356373
@SuppressWarnings("unchecked")
357374
private Map<String, Object> getIndexMetadata(String index) throws IOException {
358375
Response response = client().performRequest("GET", index);

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

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.http.entity.StringEntity;
3131
import org.apache.http.util.EntityUtils;
3232
import org.elasticsearch.action.DocWriteRequest;
33+
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
3334
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
3435
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3536
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
@@ -983,6 +984,44 @@ public void testClearScroll() throws IOException {
983984
assertEquals(REQUEST_BODY_CONTENT_TYPE.mediaTypeWithoutParameters(), request.getEntity().getContentType().getValue());
984985
}
985986

987+
public void testExistsAlias() {
988+
GetAliasesRequest getAliasesRequest = new GetAliasesRequest();
989+
String[] indices = randomIndicesNames(0, 5);
990+
getAliasesRequest.indices(indices);
991+
//the HEAD endpoint requires at least an alias or an index
992+
String[] aliases = randomIndicesNames(indices.length == 0 ? 1 : 0, 5);
993+
getAliasesRequest.aliases(aliases);
994+
Map<String, String> expectedParams = new HashMap<>();
995+
if (randomBoolean()) {
996+
boolean local = randomBoolean();
997+
getAliasesRequest.local(local);
998+
}
999+
expectedParams.put("local", Boolean.toString(getAliasesRequest.local()));
1000+
1001+
setRandomIndicesOptions(getAliasesRequest::indicesOptions, getAliasesRequest::indicesOptions, expectedParams);
1002+
1003+
Request request = Request.existsAlias(getAliasesRequest);
1004+
StringJoiner expectedEndpoint = new StringJoiner("/", "/", "");
1005+
String index = String.join(",", indices);
1006+
if (Strings.hasLength(index)) {
1007+
expectedEndpoint.add(index);
1008+
}
1009+
expectedEndpoint.add("_alias");
1010+
String alias = String.join(",", aliases);
1011+
if (Strings.hasLength(alias)) {
1012+
expectedEndpoint.add(alias);
1013+
}
1014+
assertEquals(expectedEndpoint.toString(), request.getEndpoint());
1015+
assertEquals(expectedParams, request.getParameters());
1016+
assertNull(request.getEntity());
1017+
}
1018+
1019+
public void testExistsAliasNoAliasNoIndex() {
1020+
GetAliasesRequest getAliasesRequest = new GetAliasesRequest();
1021+
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.existsAlias(getAliasesRequest));
1022+
assertEquals("existsAlias requires at least an alias or an index", iae.getMessage());
1023+
}
1024+
9861025
private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
9871026
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
9881027
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());
@@ -1017,14 +1056,25 @@ public void testParamsNoDuplicates() {
10171056
assertEquals("1", requestParams.values().iterator().next());
10181057
}
10191058

1059+
public void testBuildEndpoint() {
1060+
assertEquals("/", Request.buildEndpoint());
1061+
assertEquals("/", Request.buildEndpoint(Strings.EMPTY_ARRAY));
1062+
assertEquals("/", Request.buildEndpoint(""));
1063+
assertEquals("/a/b", Request.buildEndpoint("a", "b"));
1064+
assertEquals("/a/b/_create", Request.buildEndpoint("a", "b", "_create"));
1065+
assertEquals("/a/b/c/_create", Request.buildEndpoint("a", "b", "c", "_create"));
1066+
assertEquals("/a/_create", Request.buildEndpoint("a", null, null, "_create"));
1067+
}
1068+
10201069
public void testEndpoint() {
1021-
assertEquals("/", Request.endpoint());
1022-
assertEquals("/", Request.endpoint(Strings.EMPTY_ARRAY));
1023-
assertEquals("/", Request.endpoint(""));
1024-
assertEquals("/a/b", Request.endpoint("a", "b"));
1025-
assertEquals("/a/b/_create", Request.endpoint("a", "b", "_create"));
1026-
assertEquals("/a/b/c/_create", Request.endpoint("a", "b", "c", "_create"));
1027-
assertEquals("/a/_create", Request.endpoint("a", null, null, "_create"));
1070+
assertEquals("/index/type/id", Request.endpoint("index", "type", "id"));
1071+
assertEquals("/index/type/id/_endpoint", Request.endpoint("index", "type", "id", "_endpoint"));
1072+
assertEquals("/index1,index2", Request.endpoint(new String[]{"index1", "index2"}));
1073+
assertEquals("/index1,index2/_endpoint", Request.endpoint(new String[]{"index1", "index2"}, "_endpoint"));
1074+
assertEquals("/index1,index2/type1,type2/_endpoint", Request.endpoint(new String[]{"index1", "index2"},
1075+
new String[]{"type1", "type2"}, "_endpoint"));
1076+
assertEquals("/index1,index2/_endpoint/suffix1,suffix2", Request.endpoint(new String[]{"index1", "index2"},
1077+
"_endpoint", new String[]{"suffix1", "suffix2"}));
10281078
}
10291079

10301080
public void testCreateContentType() {

0 commit comments

Comments
 (0)