-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Get Aliases API to the high-level REST client #28799
Changes from 5 commits
6c01eeb
1571cb3
a33ea0f
a919d73
baed505
f74d0b5
7720b71
7238098
e2ffdab
9a2079f
df3b2fb
0e3ad61
519992b
11811ef
474238b
a59a026
b210f49
5b3096b
8660d43
f21b3ca
fa9d4e1
939ae4d
035d823
be1daf7
5da9ed6
5bcc1ce
2e2217a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; | ||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; | ||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; | ||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; | ||
import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest; | ||
import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse; | ||
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; | ||
|
@@ -72,6 +73,8 @@ | |
import static org.hamcrest.CoreMatchers.hasItem; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.hamcrest.Matchers.not; | ||
import static org.hamcrest.Matchers.notNullValue; | ||
import static org.hamcrest.Matchers.nullValue; | ||
|
||
public class IndicesClientIT extends ESRestHighLevelClientTestCase { | ||
|
||
|
@@ -609,4 +612,170 @@ public void testRollover() throws IOException { | |
assertEquals("test_new", rolloverResponse.getNewIndex()); | ||
} | ||
} | ||
|
||
public void testGetAlias() throws IOException { | ||
{ | ||
createIndex("index1", Settings.EMPTY); | ||
client().performRequest(HttpPut.METHOD_NAME, "/index1/_alias/alias1"); | ||
|
||
createIndex("index2", Settings.EMPTY); | ||
client().performRequest(HttpPut.METHOD_NAME, "/index2/_alias/alias2"); | ||
|
||
createIndex("index3", Settings.EMPTY); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("alias1"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).getFilter(), nullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).getIndexRouting(), nullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).getSearchRouting(), nullValue()); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("alias*"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(2)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("_all"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(2)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("*"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(2)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices("_all"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(3)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices("ind*"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(3)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(3)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index1").get(0).alias(), equalTo("alias1")); | ||
assertThat(getAliasesResponse.getAliases().get("index2").size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get("index2").get(0).alias(), equalTo("alias2")); | ||
assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); | ||
} | ||
} | ||
|
||
public void testGetAliasesNonExistentIndexOrAlias() throws IOException { | ||
|
||
String alias = "alias"; | ||
String index = "index"; | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices(index); | ||
ElasticsearchException exception = expectThrows(ElasticsearchException.class, | ||
() -> execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); | ||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); | ||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest(alias); | ||
ElasticsearchException exception = expectThrows(ElasticsearchException.class, | ||
() -> execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); | ||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); | ||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=exception, reason=alias [" + alias + "] missing]")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am somehow stuck with this response in case of an error. I do not see an option which "makes sense". A request with non existent alias results in :
For now I decided to map it to an exception. Basically if there are no aliases found then throw. If at least one alias is found, a response will be returned and its status must be checked ( to verify if all aliases have been found : OK , or if this is a "partial" response : NOT_FOUND) Another option is to throw only if any of the indices do not exist. And for the aliases always to return a response ( even if none of the specified aliases exist ). Yet another option is to never throw... ( which is not is sync with the rest of the apis ... ) Ideas how to proceed ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a weird response. I think there isn't a perfect solution. I initially was going for your solution, only throw an error when no aliases are returned. But that way that there is a 404 that's ignored and a 404 that leads to an exception being thrown, which is confusing. Also, it makes the code messy as we end up having to ignore 404 in the client, yet we need to throw in some specific case exception in fromXContent. I would then go for never throwing. It is always possible to retrieve the returned status and error message, so there is no missing info. And I will open an issue to discuss how we can fix this response as a follow-up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The get alias response is really confusing ;) To be honest, I went with the least disruption for the users I could come up with : parse the response if there are any aliases returned ( even if the response contains only 'partial' results and use the additional info such as error message and status if need be ). Confusing and hard to maintain on the server side, but easier for the users ;) If 404 is ignored and no exception is thrown, then both an error message and an ES exception will need to be stored in the response object ;) and the users will need to first check the status and if it is 404, then check if there is an ES exception or a string exception with partial results. @javanna shall I give this approach a try or should we wait for some directions from #30536 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no let's not wait, I would get this one in, for now let's never throw exception, users can read errors if they wish. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @javanna one more thing: if ES exception is added to the response, should it be serialized on the transport layer ? Maybe it would be better not to serialize it on the transport layer, but then the response tests could get tricky and maybe they will need to be split ( something similar to what has been done in #28892 ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure. At the moment we only have a string and a status, are you going for recreating an exception based on that info? |
||
} | ||
createIndex(index, Settings.EMPTY); | ||
client().performRequest(HttpPut.METHOD_NAME, index + "/_alias/" + alias); | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices(index, "non_existent_index"); | ||
ElasticsearchException exception = expectThrows(ElasticsearchException.class, | ||
() -> execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); | ||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); | ||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); | ||
} | ||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices(index, "non_existent_index").aliases(alias); | ||
ElasticsearchException exception = expectThrows(ElasticsearchException.class, | ||
() -> execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); | ||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); | ||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed that when a wildcard expressions is provided for the indices, and no indices match, we return 200 and an empty json object. Can we test that too?
|
||
{ | ||
GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices(index).aliases(alias, "non_existent_alias"); | ||
GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, | ||
highLevelClient().indices()::getAliasAsync); | ||
assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); | ||
|
||
assertThat(getAliasesResponse.getAliases().size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get(index).size(), equalTo(1)); | ||
assertThat(getAliasesResponse.getAliases().get(index).get(0), notNullValue()); | ||
assertThat(getAliasesResponse.getAliases().get(index).get(0).alias(), equalTo(alias)); | ||
|
||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leftover or intentional? If intentional is probably fine but it is worth formatting and leaving a little explanatory comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. intentional, I will add a comment |
||
{ | ||
"error": "alias [something] missing", | ||
"status": 404, | ||
"index": { | ||
"aliases": { | ||
"alias": {} | ||
} | ||
} | ||
} | ||
*/ | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is worth leaving a comment that we are so thorough here because it is the only way we can check that we haven't slid out of sync with the server because the server renders the xcontent in a spot that is difficult for us to access in a unit test.