Skip to content

Commit

Permalink
REST high-level client: add support for exists alias (#28332)
Browse files Browse the repository at this point in the history
Relates to #27205
  • Loading branch information
javanna committed Jan 25, 2018
1 parent 70c6945 commit 37dfa50
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.apache.http.Header;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
Expand All @@ -35,7 +36,8 @@
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;

import java.io.IOException;
import java.util.Collections;

import static java.util.Collections.emptySet;

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

/**
Expand All @@ -68,7 +70,7 @@ public DeleteIndexResponse delete(DeleteIndexRequest deleteIndexRequest, Header.
*/
public void deleteAsync(DeleteIndexRequest deleteIndexRequest, ActionListener<DeleteIndexResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(deleteIndexRequest, Request::deleteIndex, DeleteIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
listener, emptySet(), headers);
}

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

/**
Expand All @@ -90,7 +92,7 @@ public CreateIndexResponse create(CreateIndexRequest createIndexRequest, Header.
*/
public void createAsync(CreateIndexRequest createIndexRequest, ActionListener<CreateIndexResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
listener, emptySet(), headers);
}

/**
Expand All @@ -101,7 +103,7 @@ public void createAsync(CreateIndexRequest createIndexRequest, ActionListener<Cr
*/
public PutMappingResponse putMapping(PutMappingRequest putMappingRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(putMappingRequest, Request::putMapping, PutMappingResponse::fromXContent,
Collections.emptySet(), headers);
emptySet(), headers);
}

/**
Expand All @@ -113,7 +115,7 @@ public PutMappingResponse putMapping(PutMappingRequest putMappingRequest, Header
public void putMappingAsync(PutMappingRequest putMappingRequest, ActionListener<PutMappingResponse> listener,
Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(putMappingRequest, Request::putMapping, PutMappingResponse::fromXContent,
listener, Collections.emptySet(), headers);
listener, emptySet(), headers);
}

/**
Expand All @@ -125,7 +127,7 @@ public void putMappingAsync(PutMappingRequest putMappingRequest, ActionListener<
*/
public IndicesAliasesResponse updateAliases(IndicesAliasesRequest indicesAliasesRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(indicesAliasesRequest, Request::updateAliases,
IndicesAliasesResponse::fromXContent, Collections.emptySet(), headers);
IndicesAliasesResponse::fromXContent, emptySet(), headers);
}

/**
Expand All @@ -138,7 +140,7 @@ public IndicesAliasesResponse updateAliases(IndicesAliasesRequest indicesAliases
public void updateAliasesAsync(IndicesAliasesRequest indicesAliasesRequestRequest, ActionListener<IndicesAliasesResponse> listener,
Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(indicesAliasesRequestRequest, Request::updateAliases,
IndicesAliasesResponse::fromXContent, listener, Collections.emptySet(), headers);
IndicesAliasesResponse::fromXContent, listener, emptySet(), headers);
}

/**
Expand All @@ -149,7 +151,7 @@ public void updateAliasesAsync(IndicesAliasesRequest indicesAliasesRequestReques
*/
public OpenIndexResponse open(OpenIndexRequest openIndexRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
Collections.emptySet(), headers);
emptySet(), headers);
}

/**
Expand All @@ -160,7 +162,7 @@ public OpenIndexResponse open(OpenIndexRequest openIndexRequest, Header... heade
*/
public void openAsync(OpenIndexRequest openIndexRequest, ActionListener<OpenIndexResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(openIndexRequest, Request::openIndex, OpenIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
listener, emptySet(), headers);
}

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

/**
Expand All @@ -182,6 +184,28 @@ public CloseIndexResponse close(CloseIndexRequest closeIndexRequest, Header... h
*/
public void closeAsync(CloseIndexRequest closeIndexRequest, ActionListener<CloseIndexResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(closeIndexRequest, Request::closeIndex, CloseIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
listener, emptySet(), headers);
}

/**
* Checks if one or more aliases exist using the Aliases Exist API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
* Indices Aliases API on elastic.co</a>
*/
public boolean existsAlias(GetAliasesRequest getAliasesRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequest(getAliasesRequest, Request::existsAlias, RestHighLevelClient::convertExistsResponse,
emptySet(), headers);
}

/**
* Asynchronously checks if one or more aliases exist using the Aliases Exist API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
* Indices Aliases API on elastic.co</a>
*/
public void existsAliasAsync(GetAliasesRequest getAliasesRequest, ActionListener<Boolean> listener, Header... headers) {
restHighLevelClient.performRequestAsync(getAliasesRequest, Request::existsAlias, RestHighLevelClient::convertExistsResponse,
listener, emptySet(), headers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
Expand Down Expand Up @@ -133,7 +134,7 @@ static Request delete(DeleteRequest deleteRequest) {
}

static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
String endpoint = endpoint(deleteIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
String endpoint = endpoint(deleteIndexRequest.indices());

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

static Request openIndex(OpenIndexRequest openIndexRequest) {
String endpoint = endpoint(openIndexRequest.indices(), Strings.EMPTY_ARRAY, "_open");
String endpoint = endpoint(openIndexRequest.indices(), "_open");

Params parameters = Params.builder();

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

static Request closeIndex(CloseIndexRequest closeIndexRequest) {
String endpoint = endpoint(closeIndexRequest.indices(), Strings.EMPTY_ARRAY, "_close");
String endpoint = endpoint(closeIndexRequest.indices(), "_close");

Params parameters = Params.builder();

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

static Request createIndex(CreateIndexRequest createIndexRequest) throws IOException {
String endpoint = endpoint(createIndexRequest.indices(), Strings.EMPTY_ARRAY, "");
String endpoint = endpoint(createIndexRequest.indices());

Params parameters = Params.builder();
parameters.withTimeout(createIndexRequest.timeout());
Expand Down Expand Up @@ -474,23 +475,54 @@ static Request multiSearch(MultiSearchRequest multiSearchRequest) throws IOExcep
return new Request(HttpPost.METHOD_NAME, "/_msearch", params.getParams(), entity);
}

static Request existsAlias(GetAliasesRequest getAliasesRequest) {
Params params = Params.builder();
params.withIndicesOptions(getAliasesRequest.indicesOptions());
params.withLocal(getAliasesRequest.local());
if (getAliasesRequest.indices().length == 0 && getAliasesRequest.aliases().length == 0) {
throw new IllegalArgumentException("existsAlias requires at least an alias or an index");
}
String endpoint = endpoint(getAliasesRequest.indices(), "_alias", getAliasesRequest.aliases());
return new Request("HEAD", endpoint, params.getParams(), null);
}

private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
}

static String endpoint(String index, String type, String id) {
return buildEndpoint(index, type, id);
}

static String endpoint(String index, String type, String id, String endpoint) {
return buildEndpoint(index, type, id, endpoint);
}

static String endpoint(String[] indices) {
return buildEndpoint(String.join(",", indices));
}

static String endpoint(String[] indices, String endpoint) {
return buildEndpoint(String.join(",", indices), endpoint);
}

static String endpoint(String[] indices, String[] types, String endpoint) {
return endpoint(String.join(",", indices), String.join(",", types), endpoint);
return buildEndpoint(String.join(",", indices), String.join(",", types), endpoint);
}

static String endpoint(String[] indices, String endpoint, String[] suffixes) {
return buildEndpoint(String.join(",", indices), endpoint, String.join(",", suffixes));
}

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

/**
* Utility method to build request's endpoint.
* Utility method to build request's endpoint given its parts as strings
*/
static String endpoint(String... parts) {
static String buildEndpoint(String... parts) {
StringJoiner joiner = new StringJoiner("/", "/", "");
for (String part : parts) {
if (Strings.hasLength(part)) {
Expand Down Expand Up @@ -665,6 +697,11 @@ Params withIndicesOptions(IndicesOptions indicesOptions) {
return this;
}

Params withLocal(boolean local) {
putParam("local", Boolean.toString(local));
return this;
}

Map<String, String> getParams() {
return Collections.unmodifiableMap(params);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
Expand Down Expand Up @@ -355,6 +356,22 @@ private static boolean aliasExists(String index, String alias) throws IOExceptio
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}

public void testExistsAlias() throws IOException {
GetAliasesRequest getAliasesRequest = new GetAliasesRequest("alias");
assertFalse(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));

createIndex("index");
client().performRequest("PUT", "/index/_alias/alias");
assertTrue(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));

GetAliasesRequest getAliasesRequest2 = new GetAliasesRequest();
getAliasesRequest2.aliases("alias");
getAliasesRequest2.indices("index");
assertTrue(execute(getAliasesRequest2, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
getAliasesRequest2.indices("does_not_exist");
assertFalse(execute(getAliasesRequest2, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
}

@SuppressWarnings("unchecked")
private Map<String, Object> getIndexMetadata(String index) throws IOException {
Response response = client().performRequest("GET", index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
Expand Down Expand Up @@ -985,6 +986,44 @@ public void testClearScroll() throws IOException {
assertEquals(REQUEST_BODY_CONTENT_TYPE.mediaTypeWithoutParameters(), request.getEntity().getContentType().getValue());
}

public void testExistsAlias() {
GetAliasesRequest getAliasesRequest = new GetAliasesRequest();
String[] indices = randomIndicesNames(0, 5);
getAliasesRequest.indices(indices);
//the HEAD endpoint requires at least an alias or an index
String[] aliases = randomIndicesNames(indices.length == 0 ? 1 : 0, 5);
getAliasesRequest.aliases(aliases);
Map<String, String> expectedParams = new HashMap<>();
if (randomBoolean()) {
boolean local = randomBoolean();
getAliasesRequest.local(local);
}
expectedParams.put("local", Boolean.toString(getAliasesRequest.local()));

setRandomIndicesOptions(getAliasesRequest::indicesOptions, getAliasesRequest::indicesOptions, expectedParams);

Request request = Request.existsAlias(getAliasesRequest);
StringJoiner expectedEndpoint = new StringJoiner("/", "/", "");
String index = String.join(",", indices);
if (Strings.hasLength(index)) {
expectedEndpoint.add(index);
}
expectedEndpoint.add("_alias");
String alias = String.join(",", aliases);
if (Strings.hasLength(alias)) {
expectedEndpoint.add(alias);
}
assertEquals(expectedEndpoint.toString(), request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertNull(request.getEntity());
}

public void testExistsAliasNoAliasNoIndex() {
GetAliasesRequest getAliasesRequest = new GetAliasesRequest();
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.existsAlias(getAliasesRequest));
assertEquals("existsAlias requires at least an alias or an index", iae.getMessage());
}

private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());
Expand Down Expand Up @@ -1019,14 +1058,25 @@ public void testParamsNoDuplicates() {
assertEquals("1", requestParams.values().iterator().next());
}

public void testBuildEndpoint() {
assertEquals("/", Request.buildEndpoint());
assertEquals("/", Request.buildEndpoint(Strings.EMPTY_ARRAY));
assertEquals("/", Request.buildEndpoint(""));
assertEquals("/a/b", Request.buildEndpoint("a", "b"));
assertEquals("/a/b/_create", Request.buildEndpoint("a", "b", "_create"));
assertEquals("/a/b/c/_create", Request.buildEndpoint("a", "b", "c", "_create"));
assertEquals("/a/_create", Request.buildEndpoint("a", null, null, "_create"));
}

public void testEndpoint() {
assertEquals("/", Request.endpoint());
assertEquals("/", Request.endpoint(Strings.EMPTY_ARRAY));
assertEquals("/", Request.endpoint(""));
assertEquals("/a/b", Request.endpoint("a", "b"));
assertEquals("/a/b/_create", Request.endpoint("a", "b", "_create"));
assertEquals("/a/b/c/_create", Request.endpoint("a", "b", "c", "_create"));
assertEquals("/a/_create", Request.endpoint("a", null, null, "_create"));
assertEquals("/index/type/id", Request.endpoint("index", "type", "id"));
assertEquals("/index/type/id/_endpoint", Request.endpoint("index", "type", "id", "_endpoint"));
assertEquals("/index1,index2", Request.endpoint(new String[]{"index1", "index2"}));
assertEquals("/index1,index2/_endpoint", Request.endpoint(new String[]{"index1", "index2"}, "_endpoint"));
assertEquals("/index1,index2/type1,type2/_endpoint", Request.endpoint(new String[]{"index1", "index2"},
new String[]{"type1", "type2"}, "_endpoint"));
assertEquals("/index1,index2/_endpoint/suffix1,suffix2", Request.endpoint(new String[]{"index1", "index2"},
"_endpoint", new String[]{"suffix1", "suffix2"}));
}

public void testCreateContentType() {
Expand Down
Loading

0 comments on commit 37dfa50

Please sign in to comment.