From 6c01eeb6dcf86df5858875ee482174ba7af54c08 Mon Sep 17 00:00:00 2001 From: olcbean Date: Thu, 22 Feb 2018 14:49:34 +0100 Subject: [PATCH 01/17] Add Get Aliases API to the high-level RESR client --- .../indices/alias/get/GetAliasesResponse.java | 185 +++++++++++++++++- .../cluster/metadata/AliasMetaData.java | 14 +- .../admin/indices/RestGetAliasesAction.java | 106 +--------- .../indices/RestGetAllAliasesAction.java | 4 +- .../alias/GetAliasesResponseTests.java | 138 +++++++++++++ 5 files changed, 339 insertions(+), 108 deletions(-) create mode 100644 server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index 5a63ce8d86916..a572e90782a1c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -20,20 +20,40 @@ package org.elasticsearch.action.admin.indices.alias.get; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; + import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.util.set.Sets; +import org.elasticsearch.common.xcontent.StatusToXContentObject; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Set; +import java.util.SortedSet; +import java.util.stream.Collectors; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; -public class GetAliasesResponse extends ActionResponse { +public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); + private RestStatus status; public GetAliasesResponse(ImmutableOpenMap> aliases) { this.aliases = aliases; @@ -42,11 +62,20 @@ public GetAliasesResponse(ImmutableOpenMap> aliases) GetAliasesResponse() { } + @Override + public RestStatus status() { + return status; + } public ImmutableOpenMap> getAliases() { return aliases; } + @Override + public String toString() { + return Strings.toString(this, true, true); + } + @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); @@ -76,4 +105,158 @@ public void writeTo(StreamOutput out) throws IOException { } } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GetAliasesResponse that = (GetAliasesResponse) o; + return Objects.equals(fromListAliasesToSet(aliases), fromListAliasesToSet(that.aliases)); + } + + @Override + public int hashCode() { + return Objects.hash(fromListAliasesToSet(aliases)); + } + + private ImmutableOpenMap> fromListAliasesToSet(ImmutableOpenMap> list) { + ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); + list.forEach(e -> builder.put(e.key, new HashSet<>(e.value))); + return builder.build(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + + final boolean namesProvided = (params.param("name") != null); + String[] aliasesNames = Strings.EMPTY_ARRAY; + final ImmutableOpenMap> aliasMap = this.aliases; + + if (params.param("name") != null) { + String[] result = Strings.splitStringByCommaToArray(params.param("name")); + if (false == Strings.isAllOrWildcard(result)) { + aliasesNames = result; + } + } + + final Set aliasNames = new HashSet<>(); + final Set indicesToDisplay = new HashSet<>(); + for (final ObjectObjectCursor> cursor : aliasMap) { + for (final AliasMetaData aliasMetaData : cursor.value) { + aliasNames.add(aliasMetaData.alias()); + if (namesProvided) { + indicesToDisplay.add(cursor.key); + } + } + } + + // first remove requested aliases that are exact matches + final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliasesNames).collect(Collectors.toSet()), aliasNames); + + // now remove requested aliases that contain wildcards that are simple matches + final List matches = new ArrayList<>(); + outer: + for (final String pattern : difference) { + if (pattern.contains("*")) { + for (final String aliasName : aliasNames) { + if (Regex.simpleMatch(pattern, aliasName)) { + matches.add(pattern); + continue outer; + } + } + } + } + difference.removeAll(matches); + + builder.startObject(); + { + if (difference.isEmpty()) { + status = RestStatus.OK; + } else { + status = RestStatus.NOT_FOUND; + final String message; + if (difference.size() == 1) { + message = String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next())); + } else { + message = String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0]))); + } + builder.field("error", message); + builder.field("status", status.getStatus()); + } + + for (final ObjectObjectCursor> entry : aliases) { + if (namesProvided == false || (namesProvided && indicesToDisplay.contains(entry.key))) { + builder.startObject(entry.key); + { + builder.startObject("aliases"); + { + for (final AliasMetaData alias : entry.value) { + AliasMetaData.Builder.toXContent(alias, builder, ToXContent.EMPTY_PARAMS); + } + } + builder.endObject(); + } + builder.endObject(); + } + } + } + builder.endObject(); + return builder; + } + + private static String toNamesString(final String... names) { + if (names == null || names.length == 0) { + return ""; + } else if (names.length == 1) { + return names[0]; + } else { + return Arrays.stream(names).collect(Collectors.joining(",")); + } + } + + public static GetAliasesResponse fromXContent(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { // fresh parser? move to the first token + parser.nextToken(); + } + ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); + ImmutableOpenMap.Builder> aliasesBuilder = ImmutableOpenMap.builder(); + + while ((parser.nextToken()) != Token.END_OBJECT) { + if (parser.currentToken() == Token.FIELD_NAME) { + String indexName = parser.currentName(); + if (parser.nextToken() == Token.START_OBJECT) { + List parseInside = parseAliases(parser); + aliasesBuilder.put(indexName, parseInside); + } + } + } + GetAliasesResponse getAliasesResponse = new GetAliasesResponse(aliasesBuilder.build()); + return getAliasesResponse; + } + + private static List parseAliases(XContentParser parser) throws IOException { + List aliases = new ArrayList<>(); + Token token; + String currentFieldName = null; + while ((token = parser.nextToken()) != Token.END_OBJECT) { + if (token == Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == Token.START_OBJECT) { + if ("aliases".equals(currentFieldName)) { + while (parser.nextToken() != Token.END_OBJECT) { + AliasMetaData fromXContent = AliasMetaData.Builder.fromXContent(parser); + aliases.add(fromXContent); + } + } else { + parser.skipChildren(); + } + } + } + return aliases; + } + } diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java index c0262a6d01d0b..559eb97404e2d 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java @@ -41,7 +41,7 @@ import static java.util.Collections.emptySet; -public class AliasMetaData extends AbstractDiffable { +public class AliasMetaData extends AbstractDiffable implements ToXContent{ private final String alias; @@ -198,6 +198,17 @@ public static Diff readDiffFrom(StreamInput in) throws IOExceptio return readDiffFrom(AliasMetaData::new, in); } + @Override + public String toString() { + return Strings.toString(this, true, true); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + AliasMetaData.Builder.toXContent(this, builder, params); + return builder; + } + public static class Builder { private final String alias; @@ -335,5 +346,4 @@ public static AliasMetaData fromXContent(XContentParser parser) throws IOExcepti return builder.build(); } } - } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java index e5442c9a2f43f..74c07362582cc 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java @@ -19,37 +19,18 @@ package org.elasticsearch.rest.action.admin.indices; -import com.carrotsearch.hppc.cursors.ObjectObjectCursor; - import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.node.NodeClient; -import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.RestResponse; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.rest.action.RestBuilderListener; +import org.elasticsearch.rest.action.RestStatusToXContentListener; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.SortedSet; -import java.util.stream.Collectors; import static org.elasticsearch.rest.RestRequest.Method.GET; import static org.elasticsearch.rest.RestRequest.Method.HEAD; @@ -76,7 +57,6 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - final boolean namesProvided = request.hasParam("name"); final String[] aliases = request.paramAsStringArrayOrEmptyIfAll("name"); final GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases); final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); @@ -84,88 +64,8 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions())); getAliasesRequest.local(request.paramAsBoolean("local", getAliasesRequest.local())); - return channel -> client.admin().indices().getAliases(getAliasesRequest, new RestBuilderListener(channel) { - @Override - public RestResponse buildResponse(GetAliasesResponse response, XContentBuilder builder) throws Exception { - final ImmutableOpenMap> aliasMap = response.getAliases(); - - final Set aliasNames = new HashSet<>(); - final Set indicesToDisplay = new HashSet<>(); - for (final ObjectObjectCursor> cursor : aliasMap) { - for (final AliasMetaData aliasMetaData : cursor.value) { - aliasNames.add(aliasMetaData.alias()); - if (namesProvided) { - indicesToDisplay.add(cursor.key); - } - } - } - - // first remove requested aliases that are exact matches - final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliases).collect(Collectors.toSet()), aliasNames); - - // now remove requested aliases that contain wildcards that are simple matches - final List matches = new ArrayList<>(); - outer: - for (final String pattern : difference) { - if (pattern.contains("*")) { - for (final String aliasName : aliasNames) { - if (Regex.simpleMatch(pattern, aliasName)) { - matches.add(pattern); - continue outer; - } - } - } - } - difference.removeAll(matches); - - final RestStatus status; - builder.startObject(); - { - if (difference.isEmpty()) { - status = RestStatus.OK; - } else { - status = RestStatus.NOT_FOUND; - final String message; - if (difference.size() == 1) { - message = String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next())); - } else { - message = String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0]))); - } - builder.field("error", message); - builder.field("status", status.getStatus()); - } - - for (final ObjectObjectCursor> entry : response.getAliases()) { - if (namesProvided == false || (namesProvided && indicesToDisplay.contains(entry.key))) { - builder.startObject(entry.key); - { - builder.startObject("aliases"); - { - for (final AliasMetaData alias : entry.value) { - AliasMetaData.Builder.toXContent(alias, builder, ToXContent.EMPTY_PARAMS); - } - } - builder.endObject(); - } - builder.endObject(); - } - } - } - builder.endObject(); - return new BytesRestResponse(status, builder); - } - - }); - } - - private static String toNamesString(final String... names) { - if (names == null || names.length == 0) { - return ""; - } else if (names.length == 1) { - return names[0]; - } else { - return Arrays.stream(names).collect(Collectors.joining(",")); - } + return channel -> client.admin().indices().getAliases(getAliasesRequest, + new RestStatusToXContentListener(channel)); } } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java index 0d10ac5800e76..a695598d7d7c7 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java @@ -89,8 +89,8 @@ public RestResponse buildResponse(final GetIndexResponse response, final XConten return new BytesRestResponse(OK, builder); } - private void writeAliases(final List aliases, final XContentBuilder builder, - final Params params) throws IOException { + private void writeAliases(final List aliases, final XContentBuilder builder, final Params params) + throws IOException { builder.startObject("aliases"); { if (aliases != null) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java new file mode 100644 index 0000000000000..c5c89713469cb --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -0,0 +1,138 @@ +/* + * 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.alias; + +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.AbstractStreamableXContentTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +public class GetAliasesResponseTests extends AbstractStreamableXContentTestCase { + + @Override + protected GetAliasesResponse doParseInstance(XContentParser parser) { + try { + return GetAliasesResponse.fromXContent(parser); + } catch (IOException e) { + fail(e.getMessage()); + return null; + } + } + + @Override + protected GetAliasesResponse createTestInstance() { + return createTestItem(); + } + + @Override + protected GetAliasesResponse createBlankInstance() { + return new GetAliasesResponse(null); + } + + @Override + protected GetAliasesResponse mutateInstance(GetAliasesResponse response) { + return new GetAliasesResponse(mutateAliases(response.getAliases())); + } + + private static ImmutableOpenMap> mutateAliases(ImmutableOpenMap> aliases) { + if (aliases.isEmpty()) { + return addIndices(1, 3).build(); + } + + if (randomBoolean()) { + ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(aliases); + ImmutableOpenMap> list = addIndices(1, 1).build(); + list.forEach(e -> builder.put(e.key, e.value)); + return builder.build(); + } + + Set indices = new HashSet<>(); + Iterator keys = aliases.keysIt(); + while (keys.hasNext()) { + indices.add(keys.next()); + } + + List indicesToBeModified = randomSubsetOf(randomIntBetween(1, indices.size()), indices); + ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); + + for (String index : indices) { + List list = new ArrayList<>(aliases.get(index)); + if (indicesToBeModified.contains(index)) { + list.add(createAliasMetaData()); + } + builder.put(index, list); + } + return builder.build(); + } + + @Override + protected Predicate getRandomFieldsExcludeFilter() { + return p -> p.equals("") // do not add new indices + || p.endsWith(".aliases") // do not add new alias + || p.contains(".aliases."); // we should not be testing the AlilasMetaData.fromContent + } + + private static GetAliasesResponse createTestItem() { + return new GetAliasesResponse(addIndices(0, 5).build()); + } + + private static ImmutableOpenMap.Builder> addIndices(int min, int max) { + ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); + int indicesNum = randomIntBetween(min, max); + for (int i = 0; i < indicesNum; i++) { + String index = randomAlphaOfLength(5); + List aliasMetaData = new ArrayList<>(); + int aliasesNum = randomIntBetween(0, 3); + for (int a = 0; a < aliasesNum; a++) { + aliasMetaData.add(createAliasMetaData()); + } + builder.put(index, aliasMetaData); + } + return builder; + } + + private static AliasMetaData createAliasMetaData() { + Builder builder = AliasMetaData.builder(randomAlphaOfLengthBetween(3, 10)); + if (randomBoolean()) { + builder.routing(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.searchRouting(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.indexRouting(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.filter("{\"term\":{\"year\":2016}}"); + } + return builder.build(); + } + +} From 1571cb32649faa8a83d51882acfd67ee46e3d9e7 Mon Sep 17 00:00:00 2001 From: olcbean Date: Mon, 19 Mar 2018 20:12:55 +0100 Subject: [PATCH 02/17] next iteration : still work needed in GetAliasesResponseTests --- .../elasticsearch/client/IndicesClient.java | 24 ++++ .../org/elasticsearch/client/Request.java | 35 +++++ .../elasticsearch/client/IndicesClientIT.java | 124 ++++++++++++++++++ .../elasticsearch/client/RequestTests.java | 40 ++++++ .../IndicesClientDocumentationIT.java | 79 +++++++++++ .../high-level/indices/get_alias.asciidoc | 93 +++++++++++++ .../high-level/supported-apis.asciidoc | 2 + .../indices/alias/get/GetAliasesRequest.java | 23 ++++ .../indices/alias/get/GetAliasesResponse.java | 2 + .../cluster/metadata/AliasMetaData.java | 3 +- .../admin/indices/RestGetAliasesAction.java | 8 +- 11 files changed, 429 insertions(+), 4 deletions(-) create mode 100644 docs/java-rest/high-level/indices/get_alias.asciidoc 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 6968839d1ee42..1981e8c4efd3f 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 @@ -24,6 +24,7 @@ import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; 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.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -313,4 +314,27 @@ public void rolloverAsync(RolloverRequest rolloverRequest, ActionListener + * See Indices Aliases API on + * elastic.co + */ + public GetAliasesResponse getAlias(GetAliasesRequest getAliasesRequest, Header... headers) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(getAliasesRequest, Request::getAlias, GetAliasesResponse::fromXContent, + emptySet(), headers); + } + + /** + * Asynchronously gets one or more aliases using the Get Index Aliases API + *

+ * See Indices Aliases API on + * elastic.co + */ + public void getAliasAsync(GetAliasesRequest getAliasesRequest, ActionListener listener, Header... headers) { + restHighLevelClient.performRequestAsyncAndParseEntity(getAliasesRequest, Request::getAlias, GetAliasesResponse::fromXContent, + listener, 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 fd849f5e47883..ac8523574621c 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 @@ -60,6 +60,7 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; @@ -555,6 +556,33 @@ static Request rollover(RolloverRequest rolloverRequest) throws IOException { return new Request(HttpPost.METHOD_NAME, endpoint, params.getParams(), entity); } + static Request getAlias(GetAliasesRequest getAliasesRequest) { + Params params = Params.builder(); + params.withIndicesOptions(getAliasesRequest.indicesOptions()); + params.withLocal(getAliasesRequest.local()); + if (false == CollectionUtils.isEmpty(getAliasesRequest.aliases())) { + params.withName(getAliasesRequest.aliases()); + } else { + params.withName(getAliasesRequest.name()); + } + String endpoint = endpoint(optional(getAliasesRequest.indices(), "_all"), "_alias"); + return new Request(HttpGet.METHOD_NAME, endpoint, params.getParams(), null); + } + + private static String[] optional(String[] params) { + return optional(params, null); + } + + private static String[] optional(String[] params, String defaultParam) { + if (CollectionUtils.isEmpty(params)) { + if (defaultParam != null) { + return new String[] {defaultParam}; + } + return Strings.EMPTY_ARRAY; + } + return params; + } + 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)); @@ -807,6 +835,13 @@ Params withIncludeDefaults(boolean includeDefaults) { return this; } + Params withName(String[] names) { + if (false == CollectionUtils.isEmpty(names)) { + return putParam("name", String.join(",", names)); + } + return this; + } + Map getParams() { return Collections.unmodifiableMap(params); } 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 fbc15b10a7488..d71ec274d91f0 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 @@ -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.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -63,6 +64,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 { @@ -495,4 +498,125 @@ 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 getAliasesRequest1 = new GetAliasesRequest().aliases("alias1"); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest1, 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 getAliasesRequest2 = new GetAliasesRequest().aliases("alias*"); + getAliasesResponse = execute(getAliasesRequest2, 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 getAliasesRequest3 = new GetAliasesRequest().indices("_all"); + getAliasesResponse = execute(getAliasesRequest3, 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 getAliasesRequest4 = new GetAliasesRequest(); + getAliasesResponse = execute(getAliasesRequest4, 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 getAliasesRequest5 = new GetAliasesRequest().indices("ind*"); + getAliasesResponse = execute(getAliasesRequest5, 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 getAliasesRequest1 = new GetAliasesRequest().indices(index); + ElasticsearchException exception = expectThrows(ElasticsearchException.class, + () -> execute(getAliasesRequest1, 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 getAliasesRequest2 = new GetAliasesRequest(alias); + exception = expectThrows(ElasticsearchException.class, + () -> execute(getAliasesRequest2, 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]")); + + createIndex(index, Settings.EMPTY); + client().performRequest(HttpPut.METHOD_NAME, index + "/_alias/" + alias); + + GetAliasesRequest getAliasesRequest3 = new GetAliasesRequest().indices(index, "non_existent_index"); + exception = expectThrows(ElasticsearchException.class, + () -> execute(getAliasesRequest3, 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 getAliasesRequest4 = new GetAliasesRequest().indices(index, "non_existent_index").aliases(alias); + exception = expectThrows(ElasticsearchException.class, + () -> execute(getAliasesRequest4, 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 getAliasesRequest5 = new GetAliasesRequest().indices(index).aliases(alias, "non_existent_alias"); + exception = expectThrows(ElasticsearchException.class, + () -> execute(getAliasesRequest5, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); + /* + { + "error": "alias [something] missing", + "status": 404, + "index": { + "aliases": { + "alias": {} + } + } + } + */ + } + } \ No newline at end of file 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 71724cab82ec7..8d9b2eb723087 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 @@ -70,6 +70,7 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; @@ -1182,6 +1183,45 @@ public void testRollover() throws IOException { assertEquals(expectedParams, request.getParameters()); } + public void testGetAlias() { + GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); + + Map expectedParams = new HashMap<>(); + setRandomLocal(getAliasesRequest, expectedParams); + setRandomIndicesOptions(getAliasesRequest::indicesOptions, getAliasesRequest::indicesOptions, expectedParams); + + String[] indices = randomBoolean() ? null : randomIndicesNames(0, 2); + String[] aliases = randomBoolean() ? null : randomIndicesNames(0, 2); + getAliasesRequest.indices(indices); + if (randomBoolean()) { + getAliasesRequest.aliases(aliases); + } else { + getAliasesRequest.name(aliases); + if (false == CollectionUtils.isEmpty(aliases)) { + expectedParams.put("name", String.join(",", aliases)); + } + } + + Request request = Request.getAlias(getAliasesRequest); + StringJoiner expectedEndpoint = new StringJoiner("/", "/", ""); + + if (CollectionUtils.isEmpty(indices)) { + expectedEndpoint.add("_all"); + } else { + expectedEndpoint.add(String.join(",", indices)); + } + expectedEndpoint.add("_alias"); + + if (false == CollectionUtils.isEmpty(aliases)) { + expectedParams.put("name", String.join(",", aliases)); + } + + assertEquals(HttpGet.METHOD_NAME, request.getMethod()); + assertEquals(expectedEndpoint.toString(), request.getEndpoint()); + assertEquals(expectedParams, request.getParameters()); + assertNull(request.getEntity()); + } + 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()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index 843c5c42fffa1..95129ddda515e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -27,6 +27,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.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -47,6 +48,8 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -59,10 +62,14 @@ import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + /** * This class is used to generate the Java Indices API documentation. * You need to wrap your code between two tags like: @@ -1055,4 +1062,76 @@ public void onFailure(Exception e) { assertTrue(latch.await(30L, TimeUnit.SECONDS)); } + + public void testGetAlias() throws Exception { + RestHighLevelClient client = highLevelClient(); + + { + CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("index").alias(new Alias("alias"))); + assertTrue(createIndexResponse.isAcknowledged()); + } + + { + // tag::get-alias-request + GetAliasesRequest request = new GetAliasesRequest(); + GetAliasesRequest requestWithAlias = new GetAliasesRequest("alias1"); + GetAliasesRequest requestWithAliases = + new GetAliasesRequest(new String[] {"alias1", "alias2"}); + // end::get-alias-request + + // tag::get-alias-request-alias + request.aliases("alias"); // <1> + // end::get-alias-request-alias + // tag::get-alias-request-indices + request.indices("index"); // <1> + // end::get-alias-request-indices + + // tag::get-alias-request-indicesOptions + request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1> + // end::get-alias-request-indicesOptions + + // tag::get-alias-request-local + request.local(true); // <1> + // end::get-alias-request-local + + // tag::get-alias-execute + GetAliasesResponse response = client.indices().getAlias(request); + // end::get-alias-execute + + // tag::get-alias-response + ImmutableOpenMap> aliases = + response.getAliases(); // <1> + // end::get-alias-response + + assertThat(response.getAliases().get("index").size(), equalTo(1)); + assertThat(response.getAliases().get("index").get(0).alias(), equalTo("alias")); + + // tag::get-alias-listener + ActionListener listener = + new ActionListener() { + + @Override + public void onResponse(GetAliasesResponse getAliasesResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::get-alias-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::get-alias-execute-async + client.indices().getAliasAsync(request, listener); // <1> + // end::get-alias-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } + } diff --git a/docs/java-rest/high-level/indices/get_alias.asciidoc b/docs/java-rest/high-level/indices/get_alias.asciidoc new file mode 100644 index 0000000000000..cee3f9045c4d0 --- /dev/null +++ b/docs/java-rest/high-level/indices/get_alias.asciidoc @@ -0,0 +1,93 @@ +[[java-rest-high-get-alias]] +=== Get Alias API + +[[java-rest-high-get-alias-request]] +==== Get Alias Request + +The Get Alias API uses `GetAliasesRequest` as its request object. +One or more aliases can be optionally provided either at construction +time or later on through the relevant setter method. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request] +-------------------------------------------------- + +==== Optional arguments +The following arguments can optionally be provided: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request-alias] +-------------------------------------------------- +<1> One or more aliases to retrieve + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request-indices] +-------------------------------------------------- +<1> The index or indices that the alias is associated with + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request-indicesOptions] +-------------------------------------------------- +<1> Setting `IndicesOptions` controls how unavailable indices are resolved and +how wildcard expressions are expanded + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request-local] +-------------------------------------------------- +<1> The `local` flag (defaults to `false`) controls whether the aliases need +to be looked up in the local cluster state or in the cluster state held by +the elected master node + +[[java-rest-high-get-alias-sync]] +==== Synchronous Execution + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-execute] +-------------------------------------------------- + +[[java-rest-high-get-alias-async]] +==== Asynchronous Execution + +The asynchronous execution of a get alias request requires both a `GetAliasesRequest` +instance and an `ActionListener` instance to be passed to the asynchronous +method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-execute-async] +-------------------------------------------------- +<1> The `GetAliasesRequest` to execute and the `ActionListener` to use when +the execution completes + +The asynchronous method does not block and returns immediately. Once it is +completed the `ActionListener` is called back using the `onResponse` method +if the execution successfully completed or using the `onFailure` method if +it failed. + +A typical listener for the `Boolean` response looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-listener] +-------------------------------------------------- +<1> Called when the execution is successfully completed. The response is +provided as an argument +<2> Called in case of failure. The raised exception is provided as an argument + +[[java-rest-high-get-alias-response]] +==== Get Alias Response + +The returned `GetAliasesResponse` allows to retrieve information about the +executed operation as follows: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-response] +-------------------------------------------------- +<1> Retrieves a map of indices and their aliases \ No newline at end of file diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 9269da0923a56..3b9fcd2803557 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -60,6 +60,7 @@ Mapping Management:: Alias Management:: * <> * <> +* <> include::indices/create_index.asciidoc[] include::indices/delete_index.asciidoc[] @@ -72,6 +73,7 @@ include::indices/rollover.asciidoc[] include::indices/put_mapping.asciidoc[] include::indices/update_aliases.asciidoc[] include::indices/exists_alias.asciidoc[] +include::indices/get_alias.asciidoc[] == Cluster APIs diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java index 04b0843e0ae8f..fee5d95d3f826 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java @@ -32,6 +32,7 @@ public class GetAliasesRequest extends MasterNodeReadRequest private String[] indices = Strings.EMPTY_ARRAY; private String[] aliases = Strings.EMPTY_ARRAY; + private String[] name = Strings.EMPTY_ARRAY; private IndicesOptions indicesOptions = IndicesOptions.strictExpand(); @@ -98,6 +99,28 @@ public IndicesOptions indicesOptions() { return indicesOptions; } + /** + * Sets the value of "name". + * Used only by the high-level REST client. + * + * @param name value of the aliases names. + * @return this request + */ + public GetAliasesRequest name(String[] name) { + this.name = name; + return this; + } + + /** + * Return the alias name. + * Used only by the high-level REST client. + * + * @return aliases names. + */ + public String[] name() { + return name; + } + @Override public ActionRequestValidationException validate() { return null; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index a572e90782a1c..aca4fece82258 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -254,6 +254,8 @@ private static List parseAliases(XContentParser parser) throws IO } else { parser.skipChildren(); } + } else if (token == Token.START_ARRAY) { + parser.skipChildren(); } } return aliases; diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java index 559eb97404e2d..2078326c3e05d 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; @@ -41,7 +42,7 @@ import static java.util.Collections.emptySet; -public class AliasMetaData extends AbstractDiffable implements ToXContent{ +public class AliasMetaData extends AbstractDiffable implements ToXContentFragment { private final String alias; diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java index 74c07362582cc..41c856701bf82 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java @@ -20,11 +20,11 @@ package org.elasticsearch.rest.action.admin.indices; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; -import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; @@ -59,13 +59,15 @@ public String getName() { public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { final String[] aliases = request.paramAsStringArrayOrEmptyIfAll("name"); final GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases); + if (false == CollectionUtils.isEmpty(aliases)) { + getAliasesRequest.name(aliases); + } final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); getAliasesRequest.indices(indices); getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions())); getAliasesRequest.local(request.paramAsBoolean("local", getAliasesRequest.local())); - return channel -> client.admin().indices().getAliases(getAliasesRequest, - new RestStatusToXContentListener(channel)); + return channel -> client.admin().indices().getAliases(getAliasesRequest, new RestStatusToXContentListener<>(channel)); } } From a33ea0f1c8404262f71ef47f49bd5983a7e1cff2 Mon Sep 17 00:00:00 2001 From: olcbean Date: Tue, 10 Apr 2018 17:09:01 +0200 Subject: [PATCH 03/17] addressing some comments implemented response/error handling --- .../elasticsearch/client/IndicesClient.java | 6 +- .../org/elasticsearch/client/Request.java | 31 +-- .../client/RestHighLevelClient.java | 16 +- .../elasticsearch/client/IndicesClientIT.java | 241 +++++++++++------- .../elasticsearch/client/RequestTests.java | 15 +- .../elasticsearch/ElasticsearchException.java | 2 +- .../indices/alias/get/GetAliasesRequest.java | 23 -- .../indices/alias/get/GetAliasesResponse.java | 163 ++++++------ .../alias/get/TransportGetAliasesAction.java | 76 +++++- .../admin/indices/RestGetAliasesAction.java | 4 - .../alias/GetAliasesResponseTests.java | 137 +++++++++- 11 files changed, 453 insertions(+), 261 deletions(-) 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 1981e8c4efd3f..630f5dc91a268 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 @@ -40,11 +40,13 @@ import org.elasticsearch.action.admin.indices.rollover.RolloverResponse; import org.elasticsearch.action.admin.indices.shrink.ResizeRequest; import org.elasticsearch.action.admin.indices.shrink.ResizeResponse; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.Collections; import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; /** * A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Indices API. @@ -323,7 +325,7 @@ public void rolloverAsync(RolloverRequest rolloverRequest, ActionListener listener, Header... headers) { restHighLevelClient.performRequestAsyncAndParseEntity(getAliasesRequest, Request::getAlias, GetAliasesResponse::fromXContent, - listener, emptySet(), headers); + listener, singleton(RestStatus.NOT_FOUND.getStatus()), 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 ac8523574621c..bc732642a1011 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 @@ -560,27 +560,11 @@ static Request getAlias(GetAliasesRequest getAliasesRequest) { Params params = Params.builder(); params.withIndicesOptions(getAliasesRequest.indicesOptions()); params.withLocal(getAliasesRequest.local()); - if (false == CollectionUtils.isEmpty(getAliasesRequest.aliases())) { - params.withName(getAliasesRequest.aliases()); - } else { - params.withName(getAliasesRequest.name()); - } - String endpoint = endpoint(optional(getAliasesRequest.indices(), "_all"), "_alias"); - return new Request(HttpGet.METHOD_NAME, endpoint, params.getParams(), null); - } - private static String[] optional(String[] params) { - return optional(params, null); - } - - private static String[] optional(String[] params, String defaultParam) { - if (CollectionUtils.isEmpty(params)) { - if (defaultParam != null) { - return new String[] {defaultParam}; - } - return Strings.EMPTY_ARRAY; - } - return params; + String[] indices = getAliasesRequest.indices() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.indices(); + String[] aliases = getAliasesRequest.aliases() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.aliases(); + String endpoint = endpoint(indices, "_alias", aliases); + return new Request(HttpGet.METHOD_NAME, endpoint, params.getParams(), null); } private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException { @@ -835,13 +819,6 @@ Params withIncludeDefaults(boolean includeDefaults) { return this; } - Params withName(String[] names) { - if (false == CollectionUtils.isEmpty(names)) { - return putParam("name", String.join(",", names)); - } - return this; - } - Map getParams() { return Collections.unmodifiableMap(params); } 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 bf80aa7720741..e4d0d07136d58 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 @@ -525,10 +525,10 @@ protected final Resp performRequest(Req reques try { return responseConverter.apply(e.getResponse()); } catch (Exception innerException) { - //the exception is ignored as we now try to parse the response as an error. - //this covers cases like get where 404 can either be a valid document not found response, - //or an error for which parsing is completely different. We try to consider the 404 response as a valid one - //first. If parsing of the response breaks, we fall back to parsing it as an error. + // the exception is ignored as we now try to parse the response as an error. + // this covers cases like get where 404 can either be a valid document not found response, + // or an error for which parsing is completely different. We try to consider the 404 response as a valid one + // first. If parsing of the response breaks, we fall back to parsing it as an error. throw parseResponseException(e); } } @@ -593,10 +593,10 @@ public void onFailure(Exception exception) { try { actionListener.onResponse(responseConverter.apply(response)); } catch (Exception innerException) { - //the exception is ignored as we now try to parse the response as an error. - //this covers cases like get where 404 can either be a valid document not found response, - //or an error for which parsing is completely different. We try to consider the 404 response as a valid one - //first. If parsing of the response breaks, we fall back to parsing it as an error. + // the exception is ignored as we now try to parse the response as an error. + // this covers cases like get where 404 can either be a valid document not found response, + // or an error for which parsing is completely different. We try to consider the 404 response as a valid one + // first. If parsing of the response breaks, we fall back to parsing it as an error. actionListener.onFailure(parseResponseException(responseException)); } } else { 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 d71ec274d91f0..42ac434295eff 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 @@ -509,114 +509,159 @@ public void testGetAlias() throws IOException { createIndex("index3", Settings.EMPTY); } - GetAliasesRequest getAliasesRequest1 = new GetAliasesRequest().aliases("alias1"); - GetAliasesResponse getAliasesResponse = execute(getAliasesRequest1, 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 getAliasesRequest2 = new GetAliasesRequest().aliases("alias*"); - getAliasesResponse = execute(getAliasesRequest2, 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 getAliasesRequest3 = new GetAliasesRequest().indices("_all"); - getAliasesResponse = execute(getAliasesRequest3, 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 getAliasesRequest4 = new GetAliasesRequest(); - getAliasesResponse = execute(getAliasesRequest4, 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 getAliasesRequest5 = new GetAliasesRequest().indices("ind*"); - getAliasesResponse = execute(getAliasesRequest5, 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().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 getAliasesRequest1 = new GetAliasesRequest().indices(index); - ElasticsearchException exception = expectThrows(ElasticsearchException.class, - () -> execute(getAliasesRequest1, 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 getAliasesRequest2 = new GetAliasesRequest(alias); - exception = expectThrows(ElasticsearchException.class, - () -> execute(getAliasesRequest2, 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]")); - + { + 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]")); + } createIndex(index, Settings.EMPTY); client().performRequest(HttpPut.METHOD_NAME, index + "/_alias/" + alias); - - GetAliasesRequest getAliasesRequest3 = new GetAliasesRequest().indices(index, "non_existent_index"); - exception = expectThrows(ElasticsearchException.class, - () -> execute(getAliasesRequest3, 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 getAliasesRequest4 = new GetAliasesRequest().indices(index, "non_existent_index").aliases(alias); - exception = expectThrows(ElasticsearchException.class, - () -> execute(getAliasesRequest4, 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 getAliasesRequest5 = new GetAliasesRequest().indices(index).aliases(alias, "non_existent_alias"); - exception = expectThrows(ElasticsearchException.class, - () -> execute(getAliasesRequest5, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync)); - /* { - "error": "alias [something] missing", - "status": 404, - "index": { - "aliases": { - "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]")); + } + { + 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)); + + /* + { + "error": "alias [something] missing", + "status": 404, + "index": { + "aliases": { + "alias": {} + } + } + } + */ } - */ } } \ No newline at end of file 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 8d9b2eb723087..fc946cdd49f7d 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 @@ -1193,27 +1193,18 @@ public void testGetAlias() { String[] indices = randomBoolean() ? null : randomIndicesNames(0, 2); String[] aliases = randomBoolean() ? null : randomIndicesNames(0, 2); getAliasesRequest.indices(indices); - if (randomBoolean()) { - getAliasesRequest.aliases(aliases); - } else { - getAliasesRequest.name(aliases); - if (false == CollectionUtils.isEmpty(aliases)) { - expectedParams.put("name", String.join(",", aliases)); - } - } + getAliasesRequest.aliases(aliases); Request request = Request.getAlias(getAliasesRequest); StringJoiner expectedEndpoint = new StringJoiner("/", "/", ""); - if (CollectionUtils.isEmpty(indices)) { - expectedEndpoint.add("_all"); - } else { + if (false == CollectionUtils.isEmpty(indices)) { expectedEndpoint.add(String.join(",", indices)); } expectedEndpoint.add("_alias"); if (false == CollectionUtils.isEmpty(aliases)) { - expectedParams.put("name", String.join(",", aliases)); + expectedEndpoint.add(String.join(",", aliases)); } assertEquals(HttpGet.METHOD_NAME, request.getMethod()); diff --git a/server/src/main/java/org/elasticsearch/ElasticsearchException.java b/server/src/main/java/org/elasticsearch/ElasticsearchException.java index ab50824f59a4f..672fea38127ae 100644 --- a/server/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/server/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -407,7 +407,7 @@ public static ElasticsearchException fromXContent(XContentParser parser) throws return innerFromXContent(parser, false); } - private static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException { + public static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException { XContentParser.Token token = parser.currentToken(); ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java index fee5d95d3f826..04b0843e0ae8f 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java @@ -32,7 +32,6 @@ public class GetAliasesRequest extends MasterNodeReadRequest private String[] indices = Strings.EMPTY_ARRAY; private String[] aliases = Strings.EMPTY_ARRAY; - private String[] name = Strings.EMPTY_ARRAY; private IndicesOptions indicesOptions = IndicesOptions.strictExpand(); @@ -99,28 +98,6 @@ public IndicesOptions indicesOptions() { return indicesOptions; } - /** - * Sets the value of "name". - * Used only by the high-level REST client. - * - * @param name value of the aliases names. - * @return this request - */ - public GetAliasesRequest name(String[] name) { - this.name = name; - return this; - } - - /** - * Return the alias name. - * Used only by the high-level REST client. - * - * @return aliases names. - */ - public String[] name() { - return name; - } - @Override public ActionRequestValidationException validate() { return null; diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index aca4fece82258..cea2a1ea3d510 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -21,14 +21,15 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.Version; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.regex.Regex; -import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.xcontent.StatusToXContentObject; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -38,25 +39,35 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Objects; import java.util.Set; -import java.util.SortedSet; -import java.util.stream.Collectors; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); - private RestStatus status; + private RestStatus status = RestStatus.OK; + private String errorMsg = ""; - public GetAliasesResponse(ImmutableOpenMap> aliases) { + public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMsg) { this.aliases = aliases; + if (status == null) { + this.status = RestStatus.OK; + } + this.status = status; + if (errorMsg == null) { + this.errorMsg = ""; + } else { + this.errorMsg = errorMsg; + } + } + + public GetAliasesResponse(ImmutableOpenMap> aliases) { + this(aliases, RestStatus.OK, ""); } GetAliasesResponse() { @@ -71,9 +82,13 @@ public ImmutableOpenMap> getAliases() { return aliases; } + public String errorMsg() { + return errorMsg; + } + @Override public String toString() { - return Strings.toString(this, true, true); + return Strings.toString(this, true, true) + ", status:" + status + ", errorMsg:\"" + errorMsg + "\""; } @Override @@ -91,6 +106,13 @@ public void readFrom(StreamInput in) throws IOException { aliasesBuilder.put(key, Collections.unmodifiableList(value)); } aliases = aliasesBuilder.build(); + if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { + // if (in.getVersion().onOrAfter(Version.V_6_3_0)) { + if (in.readBoolean()) { + status = RestStatus.fromCode(in.readInt()); + errorMsg = in.readString(); + } + } } @Override @@ -104,6 +126,16 @@ public void writeTo(StreamOutput out) throws IOException { aliasMetaData.writeTo(out); } } + if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { + // if (out.getVersion().onOrAfter(Version.V_6_3_0)) { + if (status != RestStatus.OK) { + out.writeBoolean(true); + out.writeInt(status.getStatus()); + out.writeString(errorMsg); + } else { + out.writeBoolean(false); + } + } } @Override @@ -115,12 +147,14 @@ public boolean equals(Object o) { return false; } GetAliasesResponse that = (GetAliasesResponse) o; - return Objects.equals(fromListAliasesToSet(aliases), fromListAliasesToSet(that.aliases)); + return Objects.equals(fromListAliasesToSet(aliases), fromListAliasesToSet(that.aliases)) + && Objects.equals(status, that.status) + && Objects.equals(errorMsg, that.errorMsg); } @Override public int hashCode() { - return Objects.hash(fromListAliasesToSet(aliases)); + return Objects.hash(fromListAliasesToSet(aliases), status, errorMsg); } private ImmutableOpenMap> fromListAliasesToSet(ImmutableOpenMap> list) { @@ -133,63 +167,27 @@ private ImmutableOpenMap> fromListAliasesToSet(Immuta public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { final boolean namesProvided = (params.param("name") != null); - String[] aliasesNames = Strings.EMPTY_ARRAY; final ImmutableOpenMap> aliasMap = this.aliases; - if (params.param("name") != null) { - String[] result = Strings.splitStringByCommaToArray(params.param("name")); - if (false == Strings.isAllOrWildcard(result)) { - aliasesNames = result; - } - } - - final Set aliasNames = new HashSet<>(); final Set indicesToDisplay = new HashSet<>(); - for (final ObjectObjectCursor> cursor : aliasMap) { - for (final AliasMetaData aliasMetaData : cursor.value) { - aliasNames.add(aliasMetaData.alias()); - if (namesProvided) { - indicesToDisplay.add(cursor.key); - } - } - } - - // first remove requested aliases that are exact matches - final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliasesNames).collect(Collectors.toSet()), aliasNames); - // now remove requested aliases that contain wildcards that are simple matches - final List matches = new ArrayList<>(); - outer: - for (final String pattern : difference) { - if (pattern.contains("*")) { - for (final String aliasName : aliasNames) { - if (Regex.simpleMatch(pattern, aliasName)) { - matches.add(pattern); - continue outer; - } + if (namesProvided) { + for (final ObjectObjectCursor> cursor : aliasMap) { + if (cursor.value != null && false == cursor.value.isEmpty()) { + indicesToDisplay.add(cursor.key); } } } - difference.removeAll(matches); - + builder.startObject(); { - if (difference.isEmpty()) { - status = RestStatus.OK; - } else { - status = RestStatus.NOT_FOUND; - final String message; - if (difference.size() == 1) { - message = String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next())); - } else { - message = String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0]))); - } - builder.field("error", message); + if (status != null && RestStatus.OK != status) { + builder.field("error", errorMsg); builder.field("status", status.getStatus()); } for (final ObjectObjectCursor> entry : aliases) { - if (namesProvided == false || (namesProvided && indicesToDisplay.contains(entry.key))) { + if (namesProvided == false || indicesToDisplay.contains(entry.key)) { builder.startObject(entry.key); { builder.startObject("aliases"); @@ -207,34 +205,55 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } - - private static String toNamesString(final String... names) { - if (names == null || names.length == 0) { - return ""; - } else if (names.length == 1) { - return names[0]; - } else { - return Arrays.stream(names).collect(Collectors.joining(",")); - } - } public static GetAliasesResponse fromXContent(XContentParser parser) throws IOException { - if (parser.currentToken() == null) { // fresh parser? move to the first token + if (parser.currentToken() == null) { parser.nextToken(); } ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); ImmutableOpenMap.Builder> aliasesBuilder = ImmutableOpenMap.builder(); - while ((parser.nextToken()) != Token.END_OBJECT) { + String currentFieldName; + Token token; + String exceptionMsg = null; + RestStatus status = RestStatus.OK; + ElasticsearchException exception = null; + + while ((token = parser.nextToken()) != Token.END_OBJECT) { if (parser.currentToken() == Token.FIELD_NAME) { - String indexName = parser.currentName(); - if (parser.nextToken() == Token.START_OBJECT) { - List parseInside = parseAliases(parser); - aliasesBuilder.put(indexName, parseInside); + currentFieldName = parser.currentName(); + + if ("status".equals(currentFieldName)) { + if ((token = parser.nextToken()) != Token.FIELD_NAME) { + ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation); + status = RestStatus.fromCode(parser.intValue()); + } + } else if ("error".equals(currentFieldName)) { + if ((token = parser.nextToken()) != Token.FIELD_NAME) { + if (token == Token.VALUE_STRING) { + exceptionMsg = parser.text(); + } else if (token == Token.START_OBJECT) { + token = parser.nextToken(); + exception = ElasticsearchException.innerFromXContent(parser, true); + } + } + } else { + String indexName = parser.currentName(); + if (parser.nextToken() == Token.START_OBJECT) { + List parseInside = parseAliases(parser); + aliasesBuilder.put(indexName, parseInside); + } } } } - GetAliasesResponse getAliasesResponse = new GetAliasesResponse(aliasesBuilder.build()); + if (exception != null) { + throw new ElasticsearchStatusException(exception.getMessage(), status, exception.getCause()); + } + if (RestStatus.OK != status && aliasesBuilder.isEmpty()) { + throw new ElasticsearchStatusException(exceptionMsg, status); + } + GetAliasesResponse getAliasesResponse = new GetAliasesResponse(aliasesBuilder.build(), status, exceptionMsg); + return getAliasesResponse; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index 6edc95f649d40..36135287324d7 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -18,6 +18,9 @@ */ package org.elasticsearch.action.admin.indices.alias.get; +import com.carrotsearch.hppc.cursors.ObjectObjectCursor; + +import org.apache.lucene.util.SetOnce; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; @@ -27,13 +30,24 @@ import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.set.Sets; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.SortedSet; +import java.util.stream.Collectors; public class TransportGetAliasesAction extends TransportMasterNodeReadAction { @@ -63,7 +77,67 @@ protected GetAliasesResponse newResponse() { protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener listener) { String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(state, request); ImmutableOpenMap> result = state.metaData().findAliases(request.aliases(), concreteIndices); - listener.onResponse(new GetAliasesResponse(result)); + + SetOnce message = new SetOnce<>(); + SetOnce status = new SetOnce<>(); + if (false == Strings.isAllOrWildcard(request.aliases())) { + String[] aliasesNames = Strings.EMPTY_ARRAY; + + if (false == Strings.isAllOrWildcard(request.aliases())) { + aliasesNames = request.aliases(); + } + + final Set aliasNames = new HashSet<>(); + for (final ObjectObjectCursor> cursor : result) { + for (final AliasMetaData aliasMetaData : cursor.value) { + aliasNames.add(aliasMetaData.alias()); + } + } + + // first remove requested aliases that are exact matches + final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliasesNames).collect(Collectors.toSet()), aliasNames); + + // now remove requested aliases that contain wildcards that are simple matches + final List matches = new ArrayList<>(); + outer: + for (final String pattern : difference) { + if (pattern.contains("*")) { + for (final String aliasName : aliasNames) { + if (Regex.simpleMatch(pattern, aliasName)) { + matches.add(pattern); + continue outer; + } + } + } + } + + difference.removeAll(matches); + if (false == difference.isEmpty()) { + status.set(RestStatus.NOT_FOUND); + if (difference.size() == 1) { + message.set(String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next()))); + } else { + message.set(String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0])))); + } + } + } + if (status.get() == null) { + status.set(RestStatus.OK); + } + if (message.get() == null) { + message.set(""); + } + listener.onResponse(new GetAliasesResponse(result, status.get(), message.get())); + } + + private static String toNamesString(final String... names) { + if (names == null || names.length == 0) { + return ""; + } else if (names.length == 1) { + return names[0]; + } else { + return Arrays.stream(names).collect(Collectors.joining(",")); + } } } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java index 41c856701bf82..3e5b2a4da9e3f 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java @@ -24,7 +24,6 @@ import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; @@ -59,9 +58,6 @@ public String getName() { public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { final String[] aliases = request.paramAsStringArrayOrEmptyIfAll("name"); final GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases); - if (false == CollectionUtils.isEmpty(aliases)) { - getAliasesRequest.name(aliases); - } final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); getAliasesRequest.indices(indices); getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions())); diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index c5c89713469cb..c803d38c0866f 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -19,11 +19,15 @@ package org.elasticsearch.action.admin.indices.alias; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.AbstractStreamableXContentTestCase; import java.io.IOException; @@ -34,15 +38,18 @@ import java.util.Set; import java.util.function.Predicate; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + public class GetAliasesResponseTests extends AbstractStreamableXContentTestCase { @Override - protected GetAliasesResponse doParseInstance(XContentParser parser) { + protected GetAliasesResponse doParseInstance(XContentParser parser) throws IOException { try { return GetAliasesResponse.fromXContent(parser); - } catch (IOException e) { - fail(e.getMessage()); - return null; + } catch (ElasticsearchStatusException e) { + ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); + return new GetAliasesResponse(builder.build(), e.status(), e.getMessage()); } } @@ -58,17 +65,32 @@ protected GetAliasesResponse createBlankInstance() { @Override protected GetAliasesResponse mutateInstance(GetAliasesResponse response) { - return new GetAliasesResponse(mutateAliases(response.getAliases())); + switch (randomInt(2)) { + case 0: + return new GetAliasesResponse(mutateAliases(response.getAliases()), response.status(), response.errorMsg()); + case 1: + return new GetAliasesResponse(response.getAliases(), + randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), response.errorMsg()); + case 2: + if (response.status() == RestStatus.OK) { + return new GetAliasesResponse(response.getAliases(), + randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), randomAlphaOfLengthBetween(0, 100)); + } + return new GetAliasesResponse(response.getAliases(), response.status(), randomAlphaOfLengthBetween(5, 100)); + default: + assert false; + return null; + } } private static ImmutableOpenMap> mutateAliases(ImmutableOpenMap> aliases) { if (aliases.isEmpty()) { - return addIndices(1, 3).build(); + return createIndicesAliasesMap(1, 3).build(); } if (randomBoolean()) { ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(aliases); - ImmutableOpenMap> list = addIndices(1, 1).build(); + ImmutableOpenMap> list = createIndicesAliasesMap(1, 2).build(); list.forEach(e -> builder.put(e.key, e.value)); return builder.build(); } @@ -85,7 +107,13 @@ private static ImmutableOpenMap> mutateAliases(Immut for (String index : indices) { List list = new ArrayList<>(aliases.get(index)); if (indicesToBeModified.contains(index)) { - list.add(createAliasMetaData()); + if (randomBoolean() || list.isEmpty()) { + list.add(createAliasMetaData()); + } else { + int aliasIndex = randomInt(list.size() - 1); + AliasMetaData aliasMetaData = list.get(aliasIndex); + list.add(aliasIndex, mutateAliasMetaData(aliasMetaData)); + } } builder.put(index, list); } @@ -94,23 +122,26 @@ private static ImmutableOpenMap> mutateAliases(Immut @Override protected Predicate getRandomFieldsExcludeFilter() { - return p -> p.equals("") // do not add new indices + return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new index || p.endsWith(".aliases") // do not add new alias - || p.contains(".aliases."); // we should not be testing the AlilasMetaData.fromContent + || p.contains(".aliases."); // do not be testing the AlilasMetaData.fromContent } private static GetAliasesResponse createTestItem() { - return new GetAliasesResponse(addIndices(0, 5).build()); + RestStatus status = randomFrom(RestStatus.values()); + // only if the status is not OK, then there is an error msg in the response body + String errorMsg = RestStatus.OK == status ? (randomBoolean() ? null : "") : randomAlphaOfLengthBetween(0, 10); + return new GetAliasesResponse(createIndicesAliasesMap(0, 0).build(), status, errorMsg); } - private static ImmutableOpenMap.Builder> addIndices(int min, int max) { + private static ImmutableOpenMap.Builder> createIndicesAliasesMap(int min, int max) { ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); int indicesNum = randomIntBetween(min, max); for (int i = 0; i < indicesNum; i++) { String index = randomAlphaOfLength(5); List aliasMetaData = new ArrayList<>(); int aliasesNum = randomIntBetween(0, 3); - for (int a = 0; a < aliasesNum; a++) { + for (int alias = 0; alias < aliasesNum; alias++) { aliasMetaData.add(createAliasMetaData()); } builder.put(index, aliasMetaData); @@ -135,4 +166,84 @@ private static AliasMetaData createAliasMetaData() { return builder.build(); } + private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { + boolean changeAlias = randomBoolean(); + AliasMetaData.Builder builder = AliasMetaData.builder(changeAlias ? randomAlphaOfLengthBetween(2, 5) : alias.getAlias()); + builder.searchRouting(alias.searchRouting()); + builder.indexRouting(alias.indexRouting()); + builder.filter(alias.filter()); + + if (false == changeAlias) { + if (randomBoolean()) { + builder.searchRouting(alias.searchRouting() + randomAlphaOfLengthBetween(1, 3)); + } else { + builder.indexRouting(alias.indexRouting() + randomAlphaOfLengthBetween(1, 3)); + } + } + return builder.build(); + } + + public void testFromXContentWithMissingAndFoundAlias() throws IOException { + String xContent = + "{\n" + + " \"error\": \"alias [something] missing\",\n" + + " \"status\": 404,\n" + + " \"index\": {\n" + + " \"aliases\": {\n" + + " \"alias\": {}\n" + + " }\n" + + " }\n" + + "}"; + XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); + GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); + assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(response.errorMsg(), equalTo("alias [something] missing")); + assertThat(response.getAliases().size(), equalTo(1)); + assertThat(response.getAliases().get("index").size(), equalTo(1)); + assertThat(response.getAliases().get("index").get(0), notNullValue()); + assertThat(response.getAliases().get("index").get(0).alias(), equalTo("alias")); + } + + public void testFromXContentWithElasticsearchException() throws IOException { + String xContent = + "{\n" + + " \"error\": {\n" + + " \"root_cause\": [\n" + + " {\n" + + " \"type\": \"index_not_found_exception\",\n" + + " \"reason\": \"no such index\",\n" + + " \"resource.type\": \"index_or_alias\",\n" + + " \"resource.id\": \"index\",\n" + + " \"index_uuid\": \"_na_\",\n" + + " \"index\": \"index\"\n" + + " }\n" + + " ],\n" + + " \"type\": \"index_not_found_exception\",\n" + + " \"reason\": \"no such index\",\n" + + " \"resource.type\": \"index_or_alias\",\n" + + " \"resource.id\": \"index\",\n" + + " \"index_uuid\": \"_na_\",\n" + + " \"index\": \"index\"\n" + + " },\n" + + " \"status\": 404\n" + + "}"; + + XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); + ElasticsearchException expectThrows = expectThrows(ElasticsearchException.class, () -> GetAliasesResponse.fromXContent(parser)); + assertThat(expectThrows.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(expectThrows.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); + } + + public void testFromXContentWithNoAliasFound() throws IOException { + String xContent = + "{\n" + + " \"error\": \"alias [aa] missing\",\n" + + " \"status\": 404\n" + + "}"; + XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); + ElasticsearchException expectThrows = expectThrows(ElasticsearchException.class, () -> GetAliasesResponse.fromXContent(parser)); + assertThat(expectThrows.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(expectThrows.getMessage(), equalTo("alias [aa] missing")); + } + } From baed505d0e88715b60ddbe69706dbe014da0840a Mon Sep 17 00:00:00 2001 From: olcbean Date: Fri, 13 Apr 2018 17:17:51 +0000 Subject: [PATCH 04/17] chmod --- .../src/main/java/org/elasticsearch/client/Request.java | 0 .../src/test/java/org/elasticsearch/client/IndicesClientIT.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java mode change 100755 => 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java 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 old mode 100755 new mode 100644 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 old mode 100755 new mode 100644 From 7720b711d8341f902f48f007e662794e5c2d0728 Mon Sep 17 00:00:00 2001 From: olcbean Date: Fri, 18 May 2018 18:10:09 +0200 Subject: [PATCH 05/17] addressing reviewers comments --- .../elasticsearch/client/IndicesClientIT.java | 45 +++++++----- .../indices/alias/get/GetAliasesResponse.java | 69 +++++++------------ .../alias/get/TransportGetAliasesAction.java | 18 ++--- .../alias/GetAliasesResponseTests.java | 54 +++++++-------- 4 files changed, 84 insertions(+), 102 deletions(-) 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 1a10fedeae563..ac3b158278173 100644 --- 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 @@ -50,10 +50,10 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; import org.elasticsearch.action.admin.indices.rollover.RolloverRequest; import org.elasticsearch.action.admin.indices.rollover.RolloverResponse; -import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; -import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse; import org.elasticsearch.action.admin.indices.shrink.ResizeRequest; import org.elasticsearch.action.admin.indices.shrink.ResizeResponse; import org.elasticsearch.action.admin.indices.shrink.ResizeType; @@ -846,33 +846,42 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { 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]")); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, + highLevelClient().indices()::getAliasAsync); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), + 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]")); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, + highLevelClient().indices()::getAliasAsync); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), equalTo("alias [" + alias + "] missing")); } 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]")); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, + highLevelClient().indices()::getAliasAsync); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), + 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]")); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, + highLevelClient().indices()::getAliasAsync); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), + equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); + } + { + GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices("non_existent_index*"); + GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, + highLevelClient().indices()::getAliasAsync); + assertThat(getAliasesResponse.getAliases().size(), equalTo(0)); } { GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices(index).aliases(alias, "non_existent_alias"); diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index cea2a1ea3d510..5b7089c4518b8 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -22,7 +22,6 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.Version; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; @@ -51,23 +50,16 @@ public class GetAliasesResponse extends ActionResponse implements StatusToXConte private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); private RestStatus status = RestStatus.OK; - private String errorMsg = ""; + private String errorMessage; - public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMsg) { + public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMessage) { this.aliases = aliases; - if (status == null) { - this.status = RestStatus.OK; - } - this.status = status; - if (errorMsg == null) { - this.errorMsg = ""; - } else { - this.errorMsg = errorMsg; - } + this.status = status == null ? RestStatus.OK : status; + this.errorMessage = errorMessage; } public GetAliasesResponse(ImmutableOpenMap> aliases) { - this(aliases, RestStatus.OK, ""); + this(aliases, RestStatus.OK, null); } GetAliasesResponse() { @@ -82,13 +74,13 @@ public ImmutableOpenMap> getAliases() { return aliases; } - public String errorMsg() { - return errorMsg; + public String errorMessage() { + return errorMessage; } @Override public String toString() { - return Strings.toString(this, true, true) + ", status:" + status + ", errorMsg:\"" + errorMsg + "\""; + return Strings.toString(this, true, true); } @Override @@ -107,10 +99,10 @@ public void readFrom(StreamInput in) throws IOException { } aliases = aliasesBuilder.build(); if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { - // if (in.getVersion().onOrAfter(Version.V_6_3_0)) { + // if (in.getVersion().onOrAfter(Version.V_6_4_0)) { + status = RestStatus.fromCode(in.readInt()); if (in.readBoolean()) { - status = RestStatus.fromCode(in.readInt()); - errorMsg = in.readString(); + errorMessage = in.readString(); } } } @@ -127,11 +119,11 @@ public void writeTo(StreamOutput out) throws IOException { } } if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { - // if (out.getVersion().onOrAfter(Version.V_6_3_0)) { - if (status != RestStatus.OK) { + // if (out.getVersion().onOrAfter(Version.V_6_4_0)) { + out.writeInt(status.getStatus()); + if (null != errorMessage) { out.writeBoolean(true); - out.writeInt(status.getStatus()); - out.writeString(errorMsg); + out.writeString(errorMessage); } else { out.writeBoolean(false); } @@ -149,15 +141,15 @@ public boolean equals(Object o) { GetAliasesResponse that = (GetAliasesResponse) o; return Objects.equals(fromListAliasesToSet(aliases), fromListAliasesToSet(that.aliases)) && Objects.equals(status, that.status) - && Objects.equals(errorMsg, that.errorMsg); + && Objects.equals(errorMessage, that.errorMessage); } @Override public int hashCode() { - return Objects.hash(fromListAliasesToSet(aliases), status, errorMsg); + return Objects.hash(fromListAliasesToSet(aliases), status, errorMessage); } - private ImmutableOpenMap> fromListAliasesToSet(ImmutableOpenMap> list) { + private static ImmutableOpenMap> fromListAliasesToSet(ImmutableOpenMap> list) { ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); list.forEach(e -> builder.put(e.key, new HashSet<>(e.value))); return builder.build(); @@ -182,12 +174,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { if (status != null && RestStatus.OK != status) { - builder.field("error", errorMsg); + builder.field("error", errorMessage); builder.field("status", status.getStatus()); } for (final ObjectObjectCursor> entry : aliases) { - if (namesProvided == false || indicesToDisplay.contains(entry.key)) { + if (false == namesProvided || indicesToDisplay.contains(entry.key)) { builder.startObject(entry.key); { builder.startObject("aliases"); @@ -215,11 +207,10 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx String currentFieldName; Token token; - String exceptionMsg = null; + String exceptionMessage = null; RestStatus status = RestStatus.OK; - ElasticsearchException exception = null; - while ((token = parser.nextToken()) != Token.END_OBJECT) { + while (parser.nextToken() != Token.END_OBJECT) { if (parser.currentToken() == Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -231,10 +222,10 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx } else if ("error".equals(currentFieldName)) { if ((token = parser.nextToken()) != Token.FIELD_NAME) { if (token == Token.VALUE_STRING) { - exceptionMsg = parser.text(); + exceptionMessage = parser.text(); } else if (token == Token.START_OBJECT) { - token = parser.nextToken(); - exception = ElasticsearchException.innerFromXContent(parser, true); + parser.nextToken(); + exceptionMessage = ElasticsearchException.innerFromXContent(parser, true).getMessage(); } } } else { @@ -246,15 +237,7 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx } } } - if (exception != null) { - throw new ElasticsearchStatusException(exception.getMessage(), status, exception.getCause()); - } - if (RestStatus.OK != status && aliasesBuilder.isEmpty()) { - throw new ElasticsearchStatusException(exceptionMsg, status); - } - GetAliasesResponse getAliasesResponse = new GetAliasesResponse(aliasesBuilder.build(), status, exceptionMsg); - - return getAliasesResponse; + return new GetAliasesResponse(aliasesBuilder.build(), status, exceptionMessage); } private static List parseAliases(XContentParser parser) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index 36135287324d7..07e0507a9f37d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -78,8 +78,8 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(state, request); ImmutableOpenMap> result = state.metaData().findAliases(request.aliases(), concreteIndices); - SetOnce message = new SetOnce<>(); - SetOnce status = new SetOnce<>(); + String message = null; + RestStatus status = RestStatus.OK; if (false == Strings.isAllOrWildcard(request.aliases())) { String[] aliasesNames = Strings.EMPTY_ARRAY; @@ -113,21 +113,15 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac difference.removeAll(matches); if (false == difference.isEmpty()) { - status.set(RestStatus.NOT_FOUND); + status = RestStatus.NOT_FOUND; if (difference.size() == 1) { - message.set(String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next()))); + message = String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next())); } else { - message.set(String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0])))); + message = String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0]))); } } } - if (status.get() == null) { - status.set(RestStatus.OK); - } - if (message.get() == null) { - message.set(""); - } - listener.onResponse(new GetAliasesResponse(result, status.get(), message.get())); + listener.onResponse(new GetAliasesResponse(result, status, message)); } private static String toNamesString(final String... names) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index c803d38c0866f..5b1dab6b61cd2 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -19,8 +19,6 @@ package org.elasticsearch.action.admin.indices.alias; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; @@ -45,12 +43,7 @@ public class GetAliasesResponseTests extends AbstractStreamableXContentTestCase< @Override protected GetAliasesResponse doParseInstance(XContentParser parser) throws IOException { - try { - return GetAliasesResponse.fromXContent(parser); - } catch (ElasticsearchStatusException e) { - ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); - return new GetAliasesResponse(builder.build(), e.status(), e.getMessage()); - } + return GetAliasesResponse.fromXContent(parser); } @Override @@ -67,19 +60,18 @@ protected GetAliasesResponse createBlankInstance() { protected GetAliasesResponse mutateInstance(GetAliasesResponse response) { switch (randomInt(2)) { case 0: - return new GetAliasesResponse(mutateAliases(response.getAliases()), response.status(), response.errorMsg()); + return new GetAliasesResponse(mutateAliases(response.getAliases()), response.status(), response.errorMessage()); case 1: return new GetAliasesResponse(response.getAliases(), - randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), response.errorMsg()); + randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), response.errorMessage()); case 2: if (response.status() == RestStatus.OK) { return new GetAliasesResponse(response.getAliases(), - randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), randomAlphaOfLengthBetween(0, 100)); + randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), randomAlphaOfLengthBetween(5, 100)); } return new GetAliasesResponse(response.getAliases(), response.status(), randomAlphaOfLengthBetween(5, 100)); default: - assert false; - return null; + throw new UnsupportedOperationException(); } } @@ -128,10 +120,10 @@ protected Predicate getRandomFieldsExcludeFilter() { } private static GetAliasesResponse createTestItem() { - RestStatus status = randomFrom(RestStatus.values()); - // only if the status is not OK, then there is an error msg in the response body - String errorMsg = RestStatus.OK == status ? (randomBoolean() ? null : "") : randomAlphaOfLengthBetween(0, 10); - return new GetAliasesResponse(createIndicesAliasesMap(0, 0).build(), status, errorMsg); + RestStatus status = randomFrom(/*RestStatus.OK, */RestStatus.NOT_FOUND); + // only if the status is not OK, then there is an error message/exception in the response body + String errorMessage = RestStatus.OK == status ? null : randomAlphaOfLengthBetween(5, 10); + return new GetAliasesResponse(createIndicesAliasesMap(1, 5).build(), status, errorMessage); } private static ImmutableOpenMap.Builder> createIndicesAliasesMap(int min, int max) { @@ -194,14 +186,15 @@ public void testFromXContentWithMissingAndFoundAlias() throws IOException { " }\n" + " }\n" + "}"; + final String index = "index"; XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(response.errorMsg(), equalTo("alias [something] missing")); + assertThat(response.errorMessage(), equalTo("alias [something] missing")); assertThat(response.getAliases().size(), equalTo(1)); - assertThat(response.getAliases().get("index").size(), equalTo(1)); - assertThat(response.getAliases().get("index").get(0), notNullValue()); - assertThat(response.getAliases().get("index").get(0).alias(), equalTo("alias")); + assertThat(response.getAliases().get(index).size(), equalTo(1)); + assertThat(response.getAliases().get(index).get(0), notNullValue()); + assertThat(response.getAliases().get(index).get(0).alias(), equalTo("alias")); } public void testFromXContentWithElasticsearchException() throws IOException { @@ -228,10 +221,12 @@ public void testFromXContentWithElasticsearchException() throws IOException { " \"status\": 404\n" + "}"; - XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); - ElasticsearchException expectThrows = expectThrows(ElasticsearchException.class, () -> GetAliasesResponse.fromXContent(parser)); - assertThat(expectThrows.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(expectThrows.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), + equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); + } } public void testFromXContentWithNoAliasFound() throws IOException { @@ -240,10 +235,11 @@ public void testFromXContentWithNoAliasFound() throws IOException { " \"error\": \"alias [aa] missing\",\n" + " \"status\": 404\n" + "}"; - XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); - ElasticsearchException expectThrows = expectThrows(ElasticsearchException.class, () -> GetAliasesResponse.fromXContent(parser)); - assertThat(expectThrows.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(expectThrows.getMessage(), equalTo("alias [aa] missing")); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.errorMessage(), equalTo("alias [aa] missing")); + } } } From 723809832b8fa75c3324370d570c3ed6bb367e47 Mon Sep 17 00:00:00 2001 From: olcbean Date: Tue, 22 May 2018 20:56:53 +0200 Subject: [PATCH 06/17] addressing reviewers comments --- .../indices/alias/get/GetAliasesResponse.java | 19 +++++++++------- .../alias/GetAliasesResponseTests.java | 22 +++++++++---------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index 5b7089c4518b8..756989776fe6b 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -74,6 +74,14 @@ public ImmutableOpenMap> getAliases() { return aliases; } + /** + * Returns the error message if the request has not been executed successfully or null otherwise. + * + *

+ * Used only by the high-level REST client. + * + * @return The error message. + */ public String errorMessage() { return errorMessage; } @@ -100,7 +108,7 @@ public void readFrom(StreamInput in) throws IOException { aliases = aliasesBuilder.build(); if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { // if (in.getVersion().onOrAfter(Version.V_6_4_0)) { - status = RestStatus.fromCode(in.readInt()); + status = RestStatus.readFrom(in); if (in.readBoolean()) { errorMessage = in.readString(); } @@ -120,13 +128,8 @@ public void writeTo(StreamOutput out) throws IOException { } if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { // if (out.getVersion().onOrAfter(Version.V_6_4_0)) { - out.writeInt(status.getStatus()); - if (null != errorMessage) { - out.writeBoolean(true); - out.writeString(errorMessage); - } else { - out.writeBoolean(false); - } + RestStatus.writeTo(out, status); + out.writeOptionalString(errorMessage); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index 5b1dab6b61cd2..d4963790b58cc 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -116,12 +116,11 @@ private static ImmutableOpenMap> mutateAliases(Immut protected Predicate getRandomFieldsExcludeFilter() { return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new index || p.endsWith(".aliases") // do not add new alias - || p.contains(".aliases."); // do not be testing the AlilasMetaData.fromContent + || p.contains(".aliases."); // do not insert random fields in AlilasMetaData.fromContent } private static GetAliasesResponse createTestItem() { - RestStatus status = randomFrom(/*RestStatus.OK, */RestStatus.NOT_FOUND); - // only if the status is not OK, then there is an error message/exception in the response body + RestStatus status = randomFrom(RestStatus.OK, RestStatus.NOT_FOUND); String errorMessage = RestStatus.OK == status ? null : randomAlphaOfLengthBetween(5, 10); return new GetAliasesResponse(createIndicesAliasesMap(1, 5).build(), status, errorMessage); } @@ -187,14 +186,15 @@ public void testFromXContentWithMissingAndFoundAlias() throws IOException { " }\n" + "}"; final String index = "index"; - XContentParser parser = createParser(JsonXContent.jsonXContent, xContent); - GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); - assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(response.errorMessage(), equalTo("alias [something] missing")); - assertThat(response.getAliases().size(), equalTo(1)); - assertThat(response.getAliases().get(index).size(), equalTo(1)); - assertThat(response.getAliases().get(index).get(0), notNullValue()); - assertThat(response.getAliases().get(index).get(0).alias(), equalTo("alias")); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); + assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(response.errorMessage(), equalTo("alias [something] missing")); + assertThat(response.getAliases().size(), equalTo(1)); + assertThat(response.getAliases().get(index).size(), equalTo(1)); + assertThat(response.getAliases().get(index).get(0), notNullValue()); + assertThat(response.getAliases().get(index).get(0).alias(), equalTo("alias")); + } } public void testFromXContentWithElasticsearchException() throws IOException { From e2ffdab32ce0d6b496c6b0250bd166ef61a44f5e Mon Sep 17 00:00:00 2001 From: olcbean Date: Wed, 23 May 2018 14:36:40 +0200 Subject: [PATCH 07/17] insert random data into AliasMetaData modify AliasMetaData to correctly handle nested objects other than `filter` --- .../admin/indices/alias/get/TransportGetAliasesAction.java | 2 +- .../org/elasticsearch/cluster/metadata/AliasMetaData.java | 2 ++ .../action/admin/indices/alias/GetAliasesResponseTests.java | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index 07e0507a9f37d..4f6adf74ae426 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -79,7 +79,7 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac ImmutableOpenMap> result = state.metaData().findAliases(request.aliases(), concreteIndices); String message = null; - RestStatus status = RestStatus.OK; + RestStatus status = null; if (false == Strings.isAllOrWildcard(request.aliases())) { String[] aliasesNames = Strings.EMPTY_ARRAY; diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java index cf9ed0e75191a..ebcd39b49bfca 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java @@ -326,6 +326,8 @@ public static AliasMetaData fromXContent(XContentParser parser) throws IOExcepti if ("filter".equals(currentFieldName)) { Map filter = parser.mapOrdered(); builder.filter(filter); + } else { + parser.skipChildren(); } } else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) { if ("filter".equals(currentFieldName)) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index d4963790b58cc..e3c03c0a3c3e8 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -116,13 +116,13 @@ private static ImmutableOpenMap> mutateAliases(Immut protected Predicate getRandomFieldsExcludeFilter() { return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new index || p.endsWith(".aliases") // do not add new alias - || p.contains(".aliases."); // do not insert random fields in AlilasMetaData.fromContent + || p.contains(".filter"); // do not insert random data into AliasMetaData#filter } private static GetAliasesResponse createTestItem() { RestStatus status = randomFrom(RestStatus.OK, RestStatus.NOT_FOUND); String errorMessage = RestStatus.OK == status ? null : randomAlphaOfLengthBetween(5, 10); - return new GetAliasesResponse(createIndicesAliasesMap(1, 5).build(), status, errorMessage); + return new GetAliasesResponse(createIndicesAliasesMap(0, 5).build(), status, errorMessage); } private static ImmutableOpenMap.Builder> createIndicesAliasesMap(int min, int max) { From 9a2079f9d2d2397ec9fc1fc460bb2007885e0f22 Mon Sep 17 00:00:00 2001 From: olcbean Date: Fri, 25 May 2018 20:04:36 +0200 Subject: [PATCH 08/17] adding serialization bwc tests --- .../indices/alias/get/GetAliasesResponse.java | 10 +- .../alias/get/TransportGetAliasesAction.java | 1 - .../alias/GetAliasesResponseTests.java | 96 +++++++++++++------ .../elasticsearch/test/XContentTestUtils.java | 2 +- 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index 756989776fe6b..ff2172cd03a9d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -54,12 +54,14 @@ public class GetAliasesResponse extends ActionResponse implements StatusToXConte public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMessage) { this.aliases = aliases; - this.status = status == null ? RestStatus.OK : status; + if (status != null) { + this.status = status; + } this.errorMessage = errorMessage; } public GetAliasesResponse(ImmutableOpenMap> aliases) { - this(aliases, RestStatus.OK, null); + this(aliases, null, null); } GetAliasesResponse() { @@ -176,7 +178,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { - if (status != null && RestStatus.OK != status) { + if (RestStatus.OK != status) { builder.field("error", errorMessage); builder.field("status", status.getStatus()); } @@ -211,7 +213,7 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx String currentFieldName; Token token; String exceptionMessage = null; - RestStatus status = RestStatus.OK; + RestStatus status = null; while (parser.nextToken() != Token.END_OBJECT) { if (parser.currentToken() == Token.FIELD_NAME) { diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index 4f6adf74ae426..f4de4c7f39f8d 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -20,7 +20,6 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; -import org.apache.lucene.util.SetOnce; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index e3c03c0a3c3e8..c13a2779cbb29 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -19,15 +19,20 @@ package org.elasticsearch.action.admin.indices.alias; +import org.elasticsearch.Version; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.io.stream.InputStreamStreamInput; +import org.elasticsearch.common.io.stream.OutputStreamStreamOutput; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.AbstractStreamableXContentTestCase; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -36,6 +41,7 @@ import java.util.Set; import java.util.function.Predicate; +import static org.elasticsearch.test.VersionUtils.randomVersion; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; @@ -176,14 +182,14 @@ private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { public void testFromXContentWithMissingAndFoundAlias() throws IOException { String xContent = - "{\n" + - " \"error\": \"alias [something] missing\",\n" + - " \"status\": 404,\n" + - " \"index\": {\n" + - " \"aliases\": {\n" + - " \"alias\": {}\n" + - " }\n" + - " }\n" + + "{" + + " \"error\": \"alias [something] missing\"," + + " \"status\": 404," + + " \"index\": {" + + " \"aliases\": {" + + " \"alias\": {}" + + " }" + + " }" + "}"; final String index = "index"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { @@ -199,26 +205,26 @@ public void testFromXContentWithMissingAndFoundAlias() throws IOException { public void testFromXContentWithElasticsearchException() throws IOException { String xContent = - "{\n" + - " \"error\": {\n" + - " \"root_cause\": [\n" + - " {\n" + - " \"type\": \"index_not_found_exception\",\n" + - " \"reason\": \"no such index\",\n" + - " \"resource.type\": \"index_or_alias\",\n" + - " \"resource.id\": \"index\",\n" + - " \"index_uuid\": \"_na_\",\n" + - " \"index\": \"index\"\n" + - " }\n" + - " ],\n" + - " \"type\": \"index_not_found_exception\",\n" + - " \"reason\": \"no such index\",\n" + - " \"resource.type\": \"index_or_alias\",\n" + - " \"resource.id\": \"index\",\n" + - " \"index_uuid\": \"_na_\",\n" + - " \"index\": \"index\"\n" + - " },\n" + - " \"status\": 404\n" + + "{" + + " \"error\": {" + + " \"root_cause\": [" + + " {" + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }" + + " ]," + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }," + + " \"status\": 404" + "}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { @@ -231,9 +237,9 @@ public void testFromXContentWithElasticsearchException() throws IOException { public void testFromXContentWithNoAliasFound() throws IOException { String xContent = - "{\n" + - " \"error\": \"alias [aa] missing\",\n" + - " \"status\": 404\n" + + "{" + + " \"error\": \"alias [aa] missing\"," + + " \"status\": 404" + "}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); @@ -242,4 +248,32 @@ public void testFromXContentWithNoAliasFound() throws IOException { } } + public void testSerializationBwc() throws IOException { + final Version targetNodeVersion = randomVersion(random()); + final GetAliasesResponse outResponse = createTestInstance(); + + try (final ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); + final OutputStreamStreamOutput out = new OutputStreamStreamOutput(outBuffer);) { + out.setVersion(targetNodeVersion); + outResponse.writeTo(out); + + try (final ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); + final InputStreamStreamInput in = new InputStreamStreamInput(inBuffer);) { + final GetAliasesResponse inResponse = new GetAliasesResponse(null); + in.setVersion(targetNodeVersion); + inResponse.readFrom(in); + + assertThat(outResponse.getAliases(), equalTo(inResponse.getAliases())); + if (targetNodeVersion.onOrAfter(Version.V_7_0_0_alpha1)) { + // if (targetNodeVersion.onOrAfter(Version.V_6_4_0_ID)) { + assertThat(outResponse.status(), equalTo(inResponse.status())); + assertThat(outResponse.errorMessage(), equalTo(inResponse.errorMessage())); + } else { + assertThat(inResponse.status(), equalTo(RestStatus.OK)); + assertThat(inResponse.errorMessage(), equalTo(null)); + } + } + } + } + } diff --git a/test/framework/src/main/java/org/elasticsearch/test/XContentTestUtils.java b/test/framework/src/main/java/org/elasticsearch/test/XContentTestUtils.java index 724a99f2c9425..7e80810d7dd27 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/XContentTestUtils.java +++ b/test/framework/src/main/java/org/elasticsearch/test/XContentTestUtils.java @@ -60,7 +60,7 @@ public static Map convertToMap(ToXContent part) throws IOExcepti /** - * Compares to maps generated from XContentObjects. The order of elements in arrays is ignored. + * Compares two maps generated from XContentObjects. The order of elements in arrays is ignored. * * @return null if maps are equal or path to the element where the difference was found */ From df3b2fb5ceb932d082cc8fd2da94a897855a1840 Mon Sep 17 00:00:00 2001 From: olcbean Date: Mon, 28 May 2018 21:44:42 +0200 Subject: [PATCH 09/17] adding a serialization test to verify that a response serialized by 6.3 is ocrrectly deserialized --- .../indices/alias/get/GetAliasesResponse.java | 10 +-- .../alias/GetAliasesResponseTests.java | 85 ++++++++++++++++++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index ff2172cd03a9d..eb6a752a03876 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -49,14 +49,12 @@ public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); - private RestStatus status = RestStatus.OK; + private RestStatus status; private String errorMessage; public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMessage) { this.aliases = aliases; - if (status != null) { - this.status = status; - } + this.status = status; this.errorMessage = errorMessage; } @@ -178,7 +176,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { - if (RestStatus.OK != status) { + if (null != status && RestStatus.OK != status) { builder.field("error", errorMessage); builder.field("status", status.getStatus()); } @@ -242,7 +240,7 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx } } } - return new GetAliasesResponse(aliasesBuilder.build(), status, exceptionMessage); + return new GetAliasesResponse(aliasesBuilder.build(), status == null ? RestStatus.OK : status , exceptionMessage); } private static List parseAliases(XContentParser parser) throws IOException { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index c13a2779cbb29..29b88b96dada5 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -24,8 +24,10 @@ import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.io.stream.InputStreamStreamInput; import org.elasticsearch.common.io.stream.OutputStreamStreamOutput; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.rest.RestStatus; @@ -34,7 +36,9 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; +import java.util.Base64; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -44,6 +48,7 @@ import static org.elasticsearch.test.VersionUtils.randomVersion; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.core.AnyOf.anyOf; public class GetAliasesResponseTests extends AbstractStreamableXContentTestCase { @@ -258,7 +263,7 @@ public void testSerializationBwc() throws IOException { outResponse.writeTo(out); try (final ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); - final InputStreamStreamInput in = new InputStreamStreamInput(inBuffer);) { + final StreamInput in = new InputStreamStreamInput(inBuffer);) { final GetAliasesResponse inResponse = new GetAliasesResponse(null); in.setVersion(targetNodeVersion); inResponse.readFrom(in); @@ -276,4 +281,82 @@ public void testSerializationBwc() throws IOException { } } + // testing that a response serialized by ES6.3 can be successfully deserialized on master + public void testSerializationFwd_6_3_0() throws IOException { + +// The following response has been serialized on v6.3 and Base64 encoded +// "{" + +// " \"index2\": {" + +// " \"aliases\": {" + +// " \"alias2\": {" + +// " \"search_routing\": \"1,2\"" + +// " }" + +// " }" + +// " }," + +// " \"index1\": {" + +// " \"aliases\": {" + +// " \"alias1\": {}," + +// " \"alias11\": {" + +// " \"filter\": {" + +// " \"term\": {" + +// " \"year\": \"2018\"" + +// " }" + +// " }," + +// " \"index_routing\": \"2\"," + +// " \"search_routing\": \"1,2\"" + +// " }" + +// " }" + +// " }," + +// " \"index3\": {" + +// " \"aliases\": {}" + +// " }" + +// "}"; + String out63 = "AwZpbmRleDECBmFsaWFzMQAAAAdhbGlhczExAS5VAaEbREZMAKpWqkxNLFKyUjIyMLRQqgUAAAD//wMAAQEyAQMxLDIGaW5kZXgyAQZhbGlhcz" + + "IAAAEDMSwyBmluZGV4MwA="; + + byte[] decode = Base64.getDecoder().decode(out63); + GetAliasesResponse inResponse = new GetAliasesResponse(null); + + try (InputStream inBytes = new ByteArrayInputStream(decode); + StreamInput in = new InputStreamStreamInput(inBytes);) { + in.setVersion(Version.V_6_3_0); + inResponse.readFrom(in); + + ImmutableOpenMap> aliases = inResponse.getAliases(); + assertThat(aliases.size(), equalTo(3)); + + assertThat(aliases.containsKey("index1"), equalTo(true)); + List aliasesIndex1 = aliases.get("index1"); + assertThat(aliasesIndex1.size(), equalTo(2)); + + for (int i = 0; i < aliasesIndex1.size(); i++) { + AliasMetaData aliasMetaData = aliasesIndex1.get(i); + assertThat(aliasMetaData.alias(), anyOf(equalTo("alias1"), equalTo("alias11"))); + if (aliasMetaData.alias().equals("alias1")) { + assertThat(aliasMetaData.filter(), equalTo(null)); + assertThat(aliasMetaData.searchRouting(), equalTo(null)); + assertThat(aliasMetaData.indexRouting(), equalTo(null)); + } else if (aliasMetaData.alias().equals("alias11")) { + assertThat(aliasMetaData.filter(), equalTo(new CompressedXContent("{\"year\":\"2018\"}"))); + assertThat(aliasMetaData.indexRouting(), equalTo("2")); + assertThat(aliasMetaData.searchRouting(), equalTo("1,2")); + } + } + + assertThat(aliases.containsKey("index2"), equalTo(true)); + List aliasesIndex2 = aliases.get("index2"); + assertThat(aliasesIndex2.size(), equalTo(1)); + + AliasMetaData aliasMetaData = aliasesIndex2.get(0); + assertThat(aliasMetaData.alias(), equalTo("alias2")); + assertThat(aliasMetaData.filter(), equalTo(null)); + assertThat(aliasMetaData.searchRouting(), equalTo("1,2")); + assertThat(aliasMetaData.indexRouting(), equalTo(null)); + + assertThat(aliases.containsKey("index3"), equalTo(true)); + List aliasesIndex3 = aliases.get("index3"); + assertThat(aliasesIndex3.size(), equalTo(0)); + } + } + } From 0e3ad61742ceb9f6a04a505195f6c5e49dec56c3 Mon Sep 17 00:00:00 2001 From: olcbean Date: Tue, 29 May 2018 11:31:44 +0200 Subject: [PATCH 10/17] clean up --- .../admin/indices/alias/GetAliasesResponseTests.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java index 29b88b96dada5..71457029711c2 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java @@ -257,13 +257,13 @@ public void testSerializationBwc() throws IOException { final Version targetNodeVersion = randomVersion(random()); final GetAliasesResponse outResponse = createTestInstance(); - try (final ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); - final OutputStreamStreamOutput out = new OutputStreamStreamOutput(outBuffer);) { + try (ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); + OutputStreamStreamOutput out = new OutputStreamStreamOutput(outBuffer);) { out.setVersion(targetNodeVersion); outResponse.writeTo(out); - try (final ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); - final StreamInput in = new InputStreamStreamInput(inBuffer);) { + try (ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); + StreamInput in = new InputStreamStreamInput(inBuffer);) { final GetAliasesResponse inResponse = new GetAliasesResponse(null); in.setVersion(targetNodeVersion); inResponse.readFrom(in); @@ -274,7 +274,7 @@ public void testSerializationBwc() throws IOException { assertThat(outResponse.status(), equalTo(inResponse.status())); assertThat(outResponse.errorMessage(), equalTo(inResponse.errorMessage())); } else { - assertThat(inResponse.status(), equalTo(RestStatus.OK)); + assertThat(inResponse.status(), equalTo(null)); assertThat(inResponse.errorMessage(), equalTo(null)); } } From 519992bc87e47c605295b7e0c6e1a734ba437d57 Mon Sep 17 00:00:00 2001 From: olcbean Date: Tue, 29 May 2018 11:54:34 +0200 Subject: [PATCH 11/17] clean up --- .../indices/alias/get/GetAliasesResponse.java | 4 +--- .../alias/get/TransportGetAliasesAction.java | 16 +++------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index eb6a752a03876..6306dc16e43a9 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -109,9 +109,7 @@ public void readFrom(StreamInput in) throws IOException { if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { // if (in.getVersion().onOrAfter(Version.V_6_4_0)) { status = RestStatus.readFrom(in); - if (in.readBoolean()) { - errorMessage = in.readString(); - } + errorMessage = in.readOptionalString(); } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index f4de4c7f39f8d..2936426f3fc04 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -78,7 +78,7 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac ImmutableOpenMap> result = state.metaData().findAliases(request.aliases(), concreteIndices); String message = null; - RestStatus status = null; + RestStatus status = RestStatus.OK; if (false == Strings.isAllOrWildcard(request.aliases())) { String[] aliasesNames = Strings.EMPTY_ARRAY; @@ -114,23 +114,13 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac if (false == difference.isEmpty()) { status = RestStatus.NOT_FOUND; if (difference.size() == 1) { - message = String.format(Locale.ROOT, "alias [%s] missing", toNamesString(difference.iterator().next())); + message = String.format(Locale.ROOT, "alias [%s] missing", Strings.collectionToCommaDelimitedString(difference)); } else { - message = String.format(Locale.ROOT, "aliases [%s] missing", toNamesString(difference.toArray(new String[0]))); + message = String.format(Locale.ROOT, "aliases [%s] missing", Strings.collectionToCommaDelimitedString(difference)); } } } listener.onResponse(new GetAliasesResponse(result, status, message)); } - private static String toNamesString(final String... names) { - if (names == null || names.length == 0) { - return ""; - } else if (names.length == 1) { - return names[0]; - } else { - return Arrays.stream(names).collect(Collectors.joining(",")); - } - } - } From 8660d4332e8ba5bf8cc77e9d883224d67cb06602 Mon Sep 17 00:00:00 2001 From: javanna Date: Tue, 5 Jun 2018 13:47:41 +0200 Subject: [PATCH 12/17] fix bw comp issues --- .../indices/alias/get/GetAliasesResponse.java | 9 +-- .../{ => get}/GetAliasesResponseTests.java | 81 ++++++++++--------- 2 files changed, 46 insertions(+), 44 deletions(-) rename server/src/test/java/org/elasticsearch/action/admin/indices/alias/{ => get}/GetAliasesResponseTests.java (89%) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index 6306dc16e43a9..5a101ebbbbd98 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -49,7 +49,8 @@ public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); - private RestStatus status; + //default value is needed for bw comp in case the status is not serialized back + private RestStatus status = RestStatus.OK; private String errorMessage; public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMessage) { @@ -58,10 +59,6 @@ public GetAliasesResponse(ImmutableOpenMap> aliases, this.errorMessage = errorMessage; } - public GetAliasesResponse(ImmutableOpenMap> aliases) { - this(aliases, null, null); - } - GetAliasesResponse() { } @@ -174,7 +171,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { - if (null != status && RestStatus.OK != status) { + if (RestStatus.OK != status) { builder.field("error", errorMessage); builder.field("status", status.getStatus()); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java similarity index 89% rename from server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java rename to server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java index 71457029711c2..ffc31b403ab26 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java @@ -17,10 +17,9 @@ * under the License. */ -package org.elasticsearch.action.admin.indices.alias; +package org.elasticsearch.action.admin.indices.alias.get; import org.elasticsearch.Version; -import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; import org.elasticsearch.common.collect.ImmutableOpenMap; @@ -64,7 +63,7 @@ protected GetAliasesResponse createTestInstance() { @Override protected GetAliasesResponse createBlankInstance() { - return new GetAliasesResponse(null); + return new GetAliasesResponse(); } @Override @@ -264,58 +263,65 @@ public void testSerializationBwc() throws IOException { try (ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); StreamInput in = new InputStreamStreamInput(inBuffer);) { - final GetAliasesResponse inResponse = new GetAliasesResponse(null); + final GetAliasesResponse inResponse = new GetAliasesResponse(); in.setVersion(targetNodeVersion); inResponse.readFrom(in); - assertThat(outResponse.getAliases(), equalTo(inResponse.getAliases())); + assertThat(inResponse.getAliases(), equalTo(outResponse.getAliases())); if (targetNodeVersion.onOrAfter(Version.V_7_0_0_alpha1)) { // if (targetNodeVersion.onOrAfter(Version.V_6_4_0_ID)) { - assertThat(outResponse.status(), equalTo(inResponse.status())); - assertThat(outResponse.errorMessage(), equalTo(inResponse.errorMessage())); + assertThat(inResponse.status(), equalTo(outResponse.status())); + assertThat(inResponse.errorMessage(), equalTo(outResponse.errorMessage())); } else { - assertThat(inResponse.status(), equalTo(null)); + assertThat(inResponse.status(), equalTo(RestStatus.OK)); assertThat(inResponse.errorMessage(), equalTo(null)); } + + try (ByteArrayOutputStream outBuffer2 = new ByteArrayOutputStream(); + OutputStreamStreamOutput out2 = new OutputStreamStreamOutput(outBuffer);) { + out2.setVersion(randomVersion(random())); + inResponse.writeTo(out2); + } } } } // testing that a response serialized by ES6.3 can be successfully deserialized on master public void testSerializationFwd_6_3_0() throws IOException { - -// The following response has been serialized on v6.3 and Base64 encoded -// "{" + -// " \"index2\": {" + -// " \"aliases\": {" + -// " \"alias2\": {" + -// " \"search_routing\": \"1,2\"" + -// " }" + -// " }" + -// " }," + -// " \"index1\": {" + -// " \"aliases\": {" + -// " \"alias1\": {}," + -// " \"alias11\": {" + -// " \"filter\": {" + -// " \"term\": {" + -// " \"year\": \"2018\"" + -// " }" + -// " }," + -// " \"index_routing\": \"2\"," + -// " \"search_routing\": \"1,2\"" + -// " }" + -// " }" + -// " }," + -// " \"index3\": {" + -// " \"aliases\": {}" + -// " }" + -// "}"; + /* + The following response has been serialized on v6.3 and Base64 encoded + "{" + + " \"index2\": {" + + " \"aliases\": {" + + " \"alias2\": {" + + " \"search_routing\": \"1,2\"" + + " }" + + " }" + + " }," + + " \"index1\": {" + + " \"aliases\": {" + + " \"alias1\": {}," + + " \"alias11\": {" + + " \"filter\": {" + + " \"term\": {" + + " \"year\": \"2018\"" + + " }" + + " }," + + " \"index_routing\": \"2\"," + + " \"search_routing\": \"1,2\"" + + " }" + + " }" + + " }," + + " \"index3\": {" + + " \"aliases\": {}" + + " }" + + "}"; + */ String out63 = "AwZpbmRleDECBmFsaWFzMQAAAAdhbGlhczExAS5VAaEbREZMAKpWqkxNLFKyUjIyMLRQqgUAAAD//wMAAQEyAQMxLDIGaW5kZXgyAQZhbGlhcz" + "IAAAEDMSwyBmluZGV4MwA="; byte[] decode = Base64.getDecoder().decode(out63); - GetAliasesResponse inResponse = new GetAliasesResponse(null); + GetAliasesResponse inResponse = new GetAliasesResponse(); try (InputStream inBytes = new ByteArrayInputStream(decode); StreamInput in = new InputStreamStreamInput(inBytes);) { @@ -358,5 +364,4 @@ public void testSerializationFwd_6_3_0() throws IOException { assertThat(aliasesIndex3.size(), equalTo(0)); } } - } From f21b3caeff8da832914e8c9480a7269610f2df1e Mon Sep 17 00:00:00 2001 From: javanna Date: Tue, 5 Jun 2018 14:03:00 +0200 Subject: [PATCH 13/17] remove unclear if --- .../admin/indices/alias/get/TransportGetAliasesAction.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index 2936426f3fc04..cea7dc48d76a2 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -80,11 +80,7 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac String message = null; RestStatus status = RestStatus.OK; if (false == Strings.isAllOrWildcard(request.aliases())) { - String[] aliasesNames = Strings.EMPTY_ARRAY; - - if (false == Strings.isAllOrWildcard(request.aliases())) { - aliasesNames = request.aliases(); - } + String[] aliasesNames = request.aliases(); final Set aliasNames = new HashSet<>(); for (final ObjectObjectCursor> cursor : result) { @@ -122,5 +118,4 @@ protected void masterOperation(GetAliasesRequest request, ClusterState state, Ac } listener.onResponse(new GetAliasesResponse(result, status, message)); } - } From fa9d4e1a5949f037d578d368c4c20e6633f2b2d5 Mon Sep 17 00:00:00 2001 From: javanna Date: Tue, 5 Jun 2018 21:47:23 +0200 Subject: [PATCH 14/17] introduce client specific GetAliasesResponse Also revert non bw compatible changes made to REST action and transport action --- .../client/GetAliasesResponse.java | 176 +++++++++++++ .../elasticsearch/client/IndicesClient.java | 8 +- .../client/GetAliasesResponseTests.java | 237 +++++++++++++++++ .../elasticsearch/client/IndicesClientIT.java | 87 ++++--- .../IndicesClientDocumentationIT.java | 9 +- .../indices/alias/get/GetAliasesResponse.java | 176 +------------ .../alias/get/TransportGetAliasesAction.java | 55 +--- .../admin/indices/RestGetAliasesAction.java | 99 +++++++- .../alias/get/GetAliasesResponseTests.java | 240 +----------------- 9 files changed, 578 insertions(+), 509 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java new file mode 100644 index 0000000000000..fd889f42381c9 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java @@ -0,0 +1,176 @@ +/* + * 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.client; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.xcontent.StatusToXContentObject; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; +import org.elasticsearch.rest.RestStatus; + +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { + + private final RestStatus status; + private final String errorMessage; + private final Map> aliases; + + public GetAliasesResponse(RestStatus status, String errorMessage, Map> aliases) { + this.status = status; + this.errorMessage = errorMessage; + this.aliases = aliases; + } + + @Override + public RestStatus status() { + return status; + } + + public String getErrorMessage() { + return errorMessage; + } + + public Map> getAliases() { + return aliases; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GetAliasesResponse that = (GetAliasesResponse) o; + return status == that.status && + Objects.equals(errorMessage, that.errorMessage) && + Objects.equals(aliases, that.aliases); + } + + @Override + public int hashCode() { + return Objects.hash(status, errorMessage, aliases); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + { + if (status != RestStatus.OK) { + builder.field("error", errorMessage); + builder.field("status", status.getStatus()); + } + + for (Map.Entry> entry : aliases.entrySet()) { + builder.startObject(entry.getKey()); + { + builder.startObject("aliases"); + { + for (final AliasMetaData alias : entry.getValue()) { + AliasMetaData.Builder.toXContent(alias, builder, ToXContent.EMPTY_PARAMS); + } + } + builder.endObject(); + } + builder.endObject(); + } + } + builder.endObject(); + return builder; + } + + public static GetAliasesResponse fromXContent(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { + parser.nextToken(); + } + ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); + Map> aliases = new HashMap<>(); + + String currentFieldName; + Token token; + String exceptionMessage = null; + RestStatus status = RestStatus.OK; + + while (parser.nextToken() != Token.END_OBJECT) { + if (parser.currentToken() == Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + + if ("status".equals(currentFieldName)) { + if ((token = parser.nextToken()) != Token.FIELD_NAME) { + ensureExpectedToken(Token.VALUE_NUMBER, token, parser::getTokenLocation); + status = RestStatus.fromCode(parser.intValue()); + } + } else if ("error".equals(currentFieldName)) { + if ((token = parser.nextToken()) != Token.FIELD_NAME) { + if (token == Token.VALUE_STRING) { + exceptionMessage = parser.text(); + } else if (token == Token.START_OBJECT) { + parser.nextToken(); + exceptionMessage = ElasticsearchException.innerFromXContent(parser, true).getMessage(); + } + } + } else { + String indexName = parser.currentName(); + if (parser.nextToken() == Token.START_OBJECT) { + Set parseInside = parseAliases(parser); + aliases.put(indexName, parseInside); + } + } + } + } + return new GetAliasesResponse(status, exceptionMessage, aliases); + } + + private static Set parseAliases(XContentParser parser) throws IOException { + Set aliases = new HashSet<>(); + Token token; + String currentFieldName = null; + while ((token = parser.nextToken()) != Token.END_OBJECT) { + if (token == Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == Token.START_OBJECT) { + if ("aliases".equals(currentFieldName)) { + while (parser.nextToken() != Token.END_OBJECT) { + AliasMetaData fromXContent = AliasMetaData.Builder.fromXContent(parser); + aliases.add(fromXContent); + } + } else { + parser.skipChildren(); + } + } else if (token == Token.START_ARRAY) { + parser.skipChildren(); + } + } + return aliases; + } +} 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 3da932d59d6f8..efffb94747697 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 @@ -20,12 +20,10 @@ package org.elasticsearch.client; import org.apache.http.Header; -import org.elasticsearch.action.Action; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; 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; @@ -48,17 +46,17 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.admin.indices.rollover.RolloverRequest; import org.elasticsearch.action.admin.indices.rollover.RolloverResponse; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse; import org.elasticsearch.action.admin.indices.shrink.ResizeRequest; import org.elasticsearch.action.admin.indices.shrink.ResizeResponse; -import org.elasticsearch.rest.RestStatus; import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest; import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.Collections; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java new file mode 100644 index 0000000000000..a98cd2475e8b8 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java @@ -0,0 +1,237 @@ +/* + * 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.client; + +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.test.AbstractXContentTestCase; +import org.elasticsearch.test.EqualsHashCodeTestUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +import static org.hamcrest.Matchers.equalTo; + +public class GetAliasesResponseTests extends AbstractXContentTestCase { + + @Override + protected GetAliasesResponse createTestInstance() { + RestStatus status = randomFrom(RestStatus.OK, RestStatus.NOT_FOUND); + String errorMessage = RestStatus.OK == status ? null : randomAlphaOfLengthBetween(5, 10); + return new GetAliasesResponse(status, errorMessage, createIndicesAliasesMap(0, 5)); + } + + private static Map> createIndicesAliasesMap(int min, int max) { + Map> map = new HashMap<>(); + int indicesNum = randomIntBetween(min, max); + for (int i = 0; i < indicesNum; i++) { + String index = randomAlphaOfLength(5); + Set aliasMetaData = new HashSet<>(); + int aliasesNum = randomIntBetween(0, 3); + for (int alias = 0; alias < aliasesNum; alias++) { + aliasMetaData.add(createAliasMetaData()); + } + map.put(index, aliasMetaData); + } + return map; + } + + private static AliasMetaData createAliasMetaData() { + AliasMetaData.Builder builder = AliasMetaData.builder(randomAlphaOfLengthBetween(3, 10)); + if (randomBoolean()) { + builder.routing(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.searchRouting(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.indexRouting(randomAlphaOfLengthBetween(3, 10)); + } + if (randomBoolean()) { + builder.filter("{\"term\":{\"year\":2016}}"); + } + return builder.build(); + } + + @Override + protected GetAliasesResponse doParseInstance(XContentParser parser) throws IOException { + return GetAliasesResponse.fromXContent(parser); + } + + @Override + protected Predicate getRandomFieldsExcludeFilter() { + return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new index + || p.endsWith(".aliases") // do not add new alias + || p.contains(".filter"); // do not insert random data into AliasMetaData#filter + } + + @Override + protected boolean supportsUnknownFields() { + return true; + } + + public void testEqualsAndHashCode() { + EqualsHashCodeTestUtils.checkEqualsAndHashCode(createTestInstance(), + response -> new GetAliasesResponse(response.status(), response.getErrorMessage(), response.getAliases()), + GetAliasesResponseTests::mutateInstance); + } + + private static GetAliasesResponse mutateInstance(GetAliasesResponse response) { + switch (randomInt(2)) { + case 0: + return new GetAliasesResponse(response.status(), response.getErrorMessage(), mutateAliases(response.getAliases())); + case 1: + return new GetAliasesResponse(randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), + response.getErrorMessage(), response.getAliases()); + case 2: + if (response.status() == RestStatus.OK) { + return new GetAliasesResponse(randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), + randomAlphaOfLengthBetween(5, 100), response.getAliases()); + } + return new GetAliasesResponse(response.status(), randomAlphaOfLengthBetween(5, 100), response.getAliases()); + default: + throw new UnsupportedOperationException(); + } + } + + private static Map> mutateAliases(Map> aliases) { + if (aliases.isEmpty()) { + return createIndicesAliasesMap(1, 3); + } + + if (randomBoolean()) { + Map> updatedMap = new HashMap<>(aliases); + Map> list = createIndicesAliasesMap(1, 2); + list.forEach((key, value) -> updatedMap.put(key, value)); + return updatedMap; + } + + Set indices = new HashSet<>(aliases.keySet()); + + List indicesToBeModified = randomSubsetOf(randomIntBetween(1, indices.size()), indices); + Map> map = new HashMap<>(); + + for (String index : indices) { + Set set = new HashSet<>(aliases.get(index)); + if (indicesToBeModified.contains(index)) { + if (randomBoolean() || set.isEmpty()) { + set.add(createAliasMetaData()); + } else { + AliasMetaData aliasMetaData = set.iterator().next(); + set.add(mutateAliasMetaData(aliasMetaData)); + } + } + map.put(index, set); + } + return map; + } + + private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { + boolean changeAlias = randomBoolean(); + AliasMetaData.Builder builder = AliasMetaData.builder(changeAlias ? randomAlphaOfLengthBetween(2, 5) : alias.getAlias()); + builder.searchRouting(alias.searchRouting()); + builder.indexRouting(alias.indexRouting()); + builder.filter(alias.filter()); + + if (false == changeAlias) { + if (randomBoolean()) { + builder.searchRouting(alias.searchRouting() + randomAlphaOfLengthBetween(1, 3)); + } else { + builder.indexRouting(alias.indexRouting() + randomAlphaOfLengthBetween(1, 3)); + } + } + return builder.build(); + } + + public void testFromXContentWithElasticsearchException() throws IOException { + String xContent = + "{" + + " \"error\": {" + + " \"root_cause\": [" + + " {" + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }" + + " ]," + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }," + + " \"status\": 404" + + "}"; + + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.getErrorMessage(), + equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); + } + } + + public void testFromXContentWithNoAliasFound() throws IOException { + String xContent = + "{" + + " \"error\": \"alias [aa] missing\"," + + " \"status\": 404" + + "}"; + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); + assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(getAliasesResponse.getErrorMessage(), equalTo("alias [aa] missing")); + } + } + + public void testFromXContentWithMissingAndFoundAlias() throws IOException { + String xContent = + "{" + + " \"error\": \"alias [something] missing\"," + + " \"status\": 404," + + " \"index\": {" + + " \"aliases\": {" + + " \"alias\": {}" + + " }" + + " }" + + "}"; + final String index = "index"; + try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { + GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); + assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); + assertThat(response.getErrorMessage(), equalTo("alias [something] missing")); + assertThat(response.getAliases().size(), equalTo(1)); + assertThat(response.getAliases().get(index).size(), equalTo(1)); + AliasMetaData aliasMetaData = response.getAliases().get(index).iterator().next(); + assertThat(aliasMetaData.alias(), equalTo("alias")); + } + } +} 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 045109d977766..a035c64cb095a 100644 --- 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 @@ -28,7 +28,6 @@ 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; @@ -66,6 +65,7 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.broadcast.BroadcastResponse; +import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.ValidationException; import org.elasticsearch.common.settings.Setting; @@ -829,11 +829,12 @@ public void testGetAlias() throws IOException { 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()); + AliasMetaData aliasMetaData = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData, notNullValue()); + assertThat(aliasMetaData.alias(), equalTo("alias1")); + assertThat(aliasMetaData.getFilter(), nullValue()); + assertThat(aliasMetaData.getIndexRouting(), nullValue()); + assertThat(aliasMetaData.getSearchRouting(), nullValue()); } { GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("alias*"); @@ -842,11 +843,13 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); } { GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("_all"); @@ -855,11 +858,13 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); } { GetAliasesRequest getAliasesRequest = new GetAliasesRequest().aliases("*"); @@ -868,11 +873,13 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); } { GetAliasesRequest getAliasesRequest = new GetAliasesRequest().indices("_all"); @@ -881,11 +888,13 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); } { @@ -895,11 +904,13 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); } { @@ -909,17 +920,18 @@ public void testGetAlias() throws IOException { 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")); + AliasMetaData aliasMetaData1 = getAliasesResponse.getAliases().get("index1").iterator().next(); + assertThat(aliasMetaData1, notNullValue()); + assertThat(aliasMetaData1.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")); + AliasMetaData aliasMetaData2 = getAliasesResponse.getAliases().get("index2").iterator().next(); + assertThat(aliasMetaData2, notNullValue()); + assertThat(aliasMetaData2.alias(), equalTo("alias2")); assertThat(getAliasesResponse.getAliases().get("index3").size(), equalTo(0)); } } public void testGetAliasesNonExistentIndexOrAlias() throws IOException { - String alias = "alias"; String index = "index"; { @@ -927,7 +939,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), + assertThat(getAliasesResponse.getErrorMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { @@ -935,7 +947,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), equalTo("alias [" + alias + "] missing")); + assertThat(getAliasesResponse.getErrorMessage(), equalTo("alias [" + alias + "] missing")); } createIndex(index, Settings.EMPTY); client().performRequest(HttpPut.METHOD_NAME, index + "/_alias/" + alias); @@ -944,7 +956,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), + assertThat(getAliasesResponse.getErrorMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { @@ -952,7 +964,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), + assertThat(getAliasesResponse.getErrorMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { @@ -969,8 +981,9 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { 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)); + AliasMetaData aliasMetaData = getAliasesResponse.getAliases().get(index).iterator().next(); + assertThat(aliasMetaData, notNullValue()); + assertThat(aliasMetaData.alias(), equalTo(alias)); /* { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index b83ac1675814a..8758d2b2c1161 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -27,7 +27,6 @@ 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; @@ -65,6 +64,7 @@ import org.elasticsearch.action.support.DefaultShardOperationFailedException; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.ESRestHighLevelClientTestCase; +import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.SyncedFlushResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; @@ -83,8 +83,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -1757,12 +1757,11 @@ public void testGetAlias() throws Exception { // end::get-alias-execute // tag::get-alias-response - ImmutableOpenMap> aliases = - response.getAliases(); // <1> + Map> aliases = response.getAliases(); // <1> // end::get-alias-response assertThat(response.getAliases().get("index").size(), equalTo(1)); - assertThat(response.getAliases().get("index").get(0).alias(), equalTo("alias")); + assertThat(response.getAliases().get("index").iterator().next().alias(), equalTo("alias")); // tag::get-alias-listener ActionListener listener = diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java index 5a101ebbbbd98..d0ad58b6e351c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponse.java @@ -20,74 +20,33 @@ package org.elasticsearch.action.admin.indices.alias.get; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; - -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.Version; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.StatusToXContentObject; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentParser.Token; -import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Objects; -import java.util.Set; - -import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; -public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { +public class GetAliasesResponse extends ActionResponse { private ImmutableOpenMap> aliases = ImmutableOpenMap.of(); - //default value is needed for bw comp in case the status is not serialized back - private RestStatus status = RestStatus.OK; - private String errorMessage; - public GetAliasesResponse(ImmutableOpenMap> aliases, RestStatus status, String errorMessage) { + public GetAliasesResponse(ImmutableOpenMap> aliases) { this.aliases = aliases; - this.status = status; - this.errorMessage = errorMessage; } GetAliasesResponse() { } - @Override - public RestStatus status() { - return status; - } - public ImmutableOpenMap> getAliases() { return aliases; } - /** - * Returns the error message if the request has not been executed successfully or null otherwise. - * - *

- * Used only by the high-level REST client. - * - * @return The error message. - */ - public String errorMessage() { - return errorMessage; - } - - @Override - public String toString() { - return Strings.toString(this, true, true); - } - @Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); @@ -103,11 +62,6 @@ public void readFrom(StreamInput in) throws IOException { aliasesBuilder.put(key, Collections.unmodifiableList(value)); } aliases = aliasesBuilder.build(); - if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { - // if (in.getVersion().onOrAfter(Version.V_6_4_0)) { - status = RestStatus.readFrom(in); - errorMessage = in.readOptionalString(); - } } @Override @@ -121,11 +75,6 @@ public void writeTo(StreamOutput out) throws IOException { aliasMetaData.writeTo(out); } } - if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) { - // if (out.getVersion().onOrAfter(Version.V_6_4_0)) { - RestStatus.writeTo(out, status); - out.writeOptionalString(errorMessage); - } } @Override @@ -137,128 +86,11 @@ public boolean equals(Object o) { return false; } GetAliasesResponse that = (GetAliasesResponse) o; - return Objects.equals(fromListAliasesToSet(aliases), fromListAliasesToSet(that.aliases)) - && Objects.equals(status, that.status) - && Objects.equals(errorMessage, that.errorMessage); + return Objects.equals(aliases, that.aliases); } @Override public int hashCode() { - return Objects.hash(fromListAliasesToSet(aliases), status, errorMessage); - } - - private static ImmutableOpenMap> fromListAliasesToSet(ImmutableOpenMap> list) { - ImmutableOpenMap.Builder> builder = ImmutableOpenMap.builder(); - list.forEach(e -> builder.put(e.key, new HashSet<>(e.value))); - return builder.build(); + return Objects.hash(aliases); } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - - final boolean namesProvided = (params.param("name") != null); - final ImmutableOpenMap> aliasMap = this.aliases; - - final Set indicesToDisplay = new HashSet<>(); - - if (namesProvided) { - for (final ObjectObjectCursor> cursor : aliasMap) { - if (cursor.value != null && false == cursor.value.isEmpty()) { - indicesToDisplay.add(cursor.key); - } - } - } - - builder.startObject(); - { - if (RestStatus.OK != status) { - builder.field("error", errorMessage); - builder.field("status", status.getStatus()); - } - - for (final ObjectObjectCursor> entry : aliases) { - if (false == namesProvided || indicesToDisplay.contains(entry.key)) { - builder.startObject(entry.key); - { - builder.startObject("aliases"); - { - for (final AliasMetaData alias : entry.value) { - AliasMetaData.Builder.toXContent(alias, builder, ToXContent.EMPTY_PARAMS); - } - } - builder.endObject(); - } - builder.endObject(); - } - } - } - builder.endObject(); - return builder; - } - - public static GetAliasesResponse fromXContent(XContentParser parser) throws IOException { - if (parser.currentToken() == null) { - parser.nextToken(); - } - ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); - ImmutableOpenMap.Builder> aliasesBuilder = ImmutableOpenMap.builder(); - - String currentFieldName; - Token token; - String exceptionMessage = null; - RestStatus status = null; - - while (parser.nextToken() != Token.END_OBJECT) { - if (parser.currentToken() == Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - - if ("status".equals(currentFieldName)) { - if ((token = parser.nextToken()) != Token.FIELD_NAME) { - ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser::getTokenLocation); - status = RestStatus.fromCode(parser.intValue()); - } - } else if ("error".equals(currentFieldName)) { - if ((token = parser.nextToken()) != Token.FIELD_NAME) { - if (token == Token.VALUE_STRING) { - exceptionMessage = parser.text(); - } else if (token == Token.START_OBJECT) { - parser.nextToken(); - exceptionMessage = ElasticsearchException.innerFromXContent(parser, true).getMessage(); - } - } - } else { - String indexName = parser.currentName(); - if (parser.nextToken() == Token.START_OBJECT) { - List parseInside = parseAliases(parser); - aliasesBuilder.put(indexName, parseInside); - } - } - } - } - return new GetAliasesResponse(aliasesBuilder.build(), status == null ? RestStatus.OK : status , exceptionMessage); - } - - private static List parseAliases(XContentParser parser) throws IOException { - List aliases = new ArrayList<>(); - Token token; - String currentFieldName = null; - while ((token = parser.nextToken()) != Token.END_OBJECT) { - if (token == Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - } else if (token == Token.START_OBJECT) { - if ("aliases".equals(currentFieldName)) { - while (parser.nextToken() != Token.END_OBJECT) { - AliasMetaData fromXContent = AliasMetaData.Builder.fromXContent(parser); - aliases.add(fromXContent); - } - } else { - parser.skipChildren(); - } - } else if (token == Token.START_ARRAY) { - parser.skipChildren(); - } - } - return aliases; - } - } diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java index cea7dc48d76a2..96ecde4e4c6dd 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java @@ -18,8 +18,6 @@ */ package org.elasticsearch.action.admin.indices.alias.get; -import com.carrotsearch.hppc.cursors.ObjectObjectCursor; - import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; @@ -29,24 +27,13 @@ import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.rest.RestStatus; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.SortedSet; -import java.util.stream.Collectors; public class TransportGetAliasesAction extends TransportMasterNodeReadAction { @@ -76,46 +63,6 @@ protected GetAliasesResponse newResponse() { protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener listener) { String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(state, request); ImmutableOpenMap> result = state.metaData().findAliases(request.aliases(), concreteIndices); - - String message = null; - RestStatus status = RestStatus.OK; - if (false == Strings.isAllOrWildcard(request.aliases())) { - String[] aliasesNames = request.aliases(); - - final Set aliasNames = new HashSet<>(); - for (final ObjectObjectCursor> cursor : result) { - for (final AliasMetaData aliasMetaData : cursor.value) { - aliasNames.add(aliasMetaData.alias()); - } - } - - // first remove requested aliases that are exact matches - final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliasesNames).collect(Collectors.toSet()), aliasNames); - - // now remove requested aliases that contain wildcards that are simple matches - final List matches = new ArrayList<>(); - outer: - for (final String pattern : difference) { - if (pattern.contains("*")) { - for (final String aliasName : aliasNames) { - if (Regex.simpleMatch(pattern, aliasName)) { - matches.add(pattern); - continue outer; - } - } - } - } - - difference.removeAll(matches); - if (false == difference.isEmpty()) { - status = RestStatus.NOT_FOUND; - if (difference.size() == 1) { - message = String.format(Locale.ROOT, "alias [%s] missing", Strings.collectionToCommaDelimitedString(difference)); - } else { - message = String.format(Locale.ROOT, "aliases [%s] missing", Strings.collectionToCommaDelimitedString(difference)); - } - } - } - listener.onResponse(new GetAliasesResponse(result, status, message)); + listener.onResponse(new GetAliasesResponse(result)); } } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java index 3e5b2a4da9e3f..b24729f50d5f4 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAliasesAction.java @@ -19,17 +19,36 @@ package org.elasticsearch.rest.action.admin.indices; +import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.set.Sets; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.RestStatusToXContentListener; +import org.elasticsearch.rest.RestResponse; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.rest.action.RestBuilderListener; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.SortedSet; +import java.util.stream.Collectors; import static org.elasticsearch.rest.RestRequest.Method.GET; import static org.elasticsearch.rest.RestRequest.Method.HEAD; @@ -56,6 +75,7 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { + final boolean namesProvided = request.hasParam("name"); final String[] aliases = request.paramAsStringArrayOrEmptyIfAll("name"); final GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases); final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); @@ -63,7 +83,82 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions())); getAliasesRequest.local(request.paramAsBoolean("local", getAliasesRequest.local())); - return channel -> client.admin().indices().getAliases(getAliasesRequest, new RestStatusToXContentListener<>(channel)); + //we may want to move this logic to TransportGetAliasesAction but it is based on the original provided aliases, which will + //not always be available there (they may get replaced so retrieving request.aliases is not quite the same). + return channel -> client.admin().indices().getAliases(getAliasesRequest, new RestBuilderListener(channel) { + @Override + public RestResponse buildResponse(GetAliasesResponse response, XContentBuilder builder) throws Exception { + final ImmutableOpenMap> aliasMap = response.getAliases(); + + final Set aliasNames = new HashSet<>(); + final Set indicesToDisplay = new HashSet<>(); + for (final ObjectObjectCursor> cursor : aliasMap) { + for (final AliasMetaData aliasMetaData : cursor.value) { + aliasNames.add(aliasMetaData.alias()); + if (namesProvided) { + indicesToDisplay.add(cursor.key); + } + } + } + + // first remove requested aliases that are exact matches + final SortedSet difference = Sets.sortedDifference(Arrays.stream(aliases).collect(Collectors.toSet()), aliasNames); + + // now remove requested aliases that contain wildcards that are simple matches + final List matches = new ArrayList<>(); + outer: + for (final String pattern : difference) { + if (pattern.contains("*")) { + for (final String aliasName : aliasNames) { + if (Regex.simpleMatch(pattern, aliasName)) { + matches.add(pattern); + continue outer; + } + } + } + } + difference.removeAll(matches); + + final RestStatus status; + builder.startObject(); + { + if (difference.isEmpty()) { + status = RestStatus.OK; + } else { + status = RestStatus.NOT_FOUND; + final String message; + if (difference.size() == 1) { + message = String.format(Locale.ROOT, "alias [%s] missing", + Strings.collectionToCommaDelimitedString(difference)); + } else { + message = String.format(Locale.ROOT, "aliases [%s] missing", + Strings.collectionToCommaDelimitedString(difference)); + } + builder.field("error", message); + builder.field("status", status.getStatus()); + } + + for (final ObjectObjectCursor> entry : response.getAliases()) { + if (namesProvided == false || (namesProvided && indicesToDisplay.contains(entry.key))) { + builder.startObject(entry.key); + { + builder.startObject("aliases"); + { + for (final AliasMetaData alias : entry.value) { + AliasMetaData.Builder.toXContent(alias, builder, ToXContent.EMPTY_PARAMS); + } + } + builder.endObject(); + } + builder.endObject(); + } + } + } + builder.endObject(); + return new BytesRestResponse(status, builder); + } + + }); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java index ffc31b403ab26..6c15c419d092c 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesResponseTests.java @@ -19,42 +19,18 @@ package org.elasticsearch.action.admin.indices.alias.get; -import org.elasticsearch.Version; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData.Builder; import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.compress.CompressedXContent; -import org.elasticsearch.common.io.stream.InputStreamStreamInput; -import org.elasticsearch.common.io.stream.OutputStreamStreamOutput; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.test.AbstractStreamableXContentTestCase; +import org.elasticsearch.test.AbstractStreamableTestCase; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; -import java.util.Base64; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.function.Predicate; -import static org.elasticsearch.test.VersionUtils.randomVersion; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.core.AnyOf.anyOf; - -public class GetAliasesResponseTests extends AbstractStreamableXContentTestCase { - - @Override - protected GetAliasesResponse doParseInstance(XContentParser parser) throws IOException { - return GetAliasesResponse.fromXContent(parser); - } +public class GetAliasesResponseTests extends AbstractStreamableTestCase { @Override protected GetAliasesResponse createTestInstance() { @@ -68,21 +44,7 @@ protected GetAliasesResponse createBlankInstance() { @Override protected GetAliasesResponse mutateInstance(GetAliasesResponse response) { - switch (randomInt(2)) { - case 0: - return new GetAliasesResponse(mutateAliases(response.getAliases()), response.status(), response.errorMessage()); - case 1: - return new GetAliasesResponse(response.getAliases(), - randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), response.errorMessage()); - case 2: - if (response.status() == RestStatus.OK) { - return new GetAliasesResponse(response.getAliases(), - randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), randomAlphaOfLengthBetween(5, 100)); - } - return new GetAliasesResponse(response.getAliases(), response.status(), randomAlphaOfLengthBetween(5, 100)); - default: - throw new UnsupportedOperationException(); - } + return new GetAliasesResponse(mutateAliases(response.getAliases())); } private static ImmutableOpenMap> mutateAliases(ImmutableOpenMap> aliases) { @@ -122,17 +84,8 @@ private static ImmutableOpenMap> mutateAliases(Immut return builder.build(); } - @Override - protected Predicate getRandomFieldsExcludeFilter() { - return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new index - || p.endsWith(".aliases") // do not add new alias - || p.contains(".filter"); // do not insert random data into AliasMetaData#filter - } - private static GetAliasesResponse createTestItem() { - RestStatus status = randomFrom(RestStatus.OK, RestStatus.NOT_FOUND); - String errorMessage = RestStatus.OK == status ? null : randomAlphaOfLengthBetween(5, 10); - return new GetAliasesResponse(createIndicesAliasesMap(0, 5).build(), status, errorMessage); + return new GetAliasesResponse(createIndicesAliasesMap(0, 5).build()); } private static ImmutableOpenMap.Builder> createIndicesAliasesMap(int min, int max) { @@ -150,7 +103,7 @@ private static ImmutableOpenMap.Builder> createIndic return builder; } - private static AliasMetaData createAliasMetaData() { + public static AliasMetaData createAliasMetaData() { Builder builder = AliasMetaData.builder(randomAlphaOfLengthBetween(3, 10)); if (randomBoolean()) { builder.routing(randomAlphaOfLengthBetween(3, 10)); @@ -167,7 +120,7 @@ private static AliasMetaData createAliasMetaData() { return builder.build(); } - private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { + public static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { boolean changeAlias = randomBoolean(); AliasMetaData.Builder builder = AliasMetaData.builder(changeAlias ? randomAlphaOfLengthBetween(2, 5) : alias.getAlias()); builder.searchRouting(alias.searchRouting()); @@ -183,185 +136,4 @@ private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { } return builder.build(); } - - public void testFromXContentWithMissingAndFoundAlias() throws IOException { - String xContent = - "{" + - " \"error\": \"alias [something] missing\"," + - " \"status\": 404," + - " \"index\": {" + - " \"aliases\": {" + - " \"alias\": {}" + - " }" + - " }" + - "}"; - final String index = "index"; - try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { - GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); - assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(response.errorMessage(), equalTo("alias [something] missing")); - assertThat(response.getAliases().size(), equalTo(1)); - assertThat(response.getAliases().get(index).size(), equalTo(1)); - assertThat(response.getAliases().get(index).get(0), notNullValue()); - assertThat(response.getAliases().get(index).get(0).alias(), equalTo("alias")); - } - } - - public void testFromXContentWithElasticsearchException() throws IOException { - String xContent = - "{" + - " \"error\": {" + - " \"root_cause\": [" + - " {" + - " \"type\": \"index_not_found_exception\"," + - " \"reason\": \"no such index\"," + - " \"resource.type\": \"index_or_alias\"," + - " \"resource.id\": \"index\"," + - " \"index_uuid\": \"_na_\"," + - " \"index\": \"index\"" + - " }" + - " ]," + - " \"type\": \"index_not_found_exception\"," + - " \"reason\": \"no such index\"," + - " \"resource.type\": \"index_or_alias\"," + - " \"resource.id\": \"index\"," + - " \"index_uuid\": \"_na_\"," + - " \"index\": \"index\"" + - " }," + - " \"status\": 404" + - "}"; - - try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { - GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); - assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), - equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); - } - } - - public void testFromXContentWithNoAliasFound() throws IOException { - String xContent = - "{" + - " \"error\": \"alias [aa] missing\"," + - " \"status\": 404" + - "}"; - try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { - GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); - assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.errorMessage(), equalTo("alias [aa] missing")); - } - } - - public void testSerializationBwc() throws IOException { - final Version targetNodeVersion = randomVersion(random()); - final GetAliasesResponse outResponse = createTestInstance(); - - try (ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); - OutputStreamStreamOutput out = new OutputStreamStreamOutput(outBuffer);) { - out.setVersion(targetNodeVersion); - outResponse.writeTo(out); - - try (ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray()); - StreamInput in = new InputStreamStreamInput(inBuffer);) { - final GetAliasesResponse inResponse = new GetAliasesResponse(); - in.setVersion(targetNodeVersion); - inResponse.readFrom(in); - - assertThat(inResponse.getAliases(), equalTo(outResponse.getAliases())); - if (targetNodeVersion.onOrAfter(Version.V_7_0_0_alpha1)) { - // if (targetNodeVersion.onOrAfter(Version.V_6_4_0_ID)) { - assertThat(inResponse.status(), equalTo(outResponse.status())); - assertThat(inResponse.errorMessage(), equalTo(outResponse.errorMessage())); - } else { - assertThat(inResponse.status(), equalTo(RestStatus.OK)); - assertThat(inResponse.errorMessage(), equalTo(null)); - } - - try (ByteArrayOutputStream outBuffer2 = new ByteArrayOutputStream(); - OutputStreamStreamOutput out2 = new OutputStreamStreamOutput(outBuffer);) { - out2.setVersion(randomVersion(random())); - inResponse.writeTo(out2); - } - } - } - } - - // testing that a response serialized by ES6.3 can be successfully deserialized on master - public void testSerializationFwd_6_3_0() throws IOException { - /* - The following response has been serialized on v6.3 and Base64 encoded - "{" + - " \"index2\": {" + - " \"aliases\": {" + - " \"alias2\": {" + - " \"search_routing\": \"1,2\"" + - " }" + - " }" + - " }," + - " \"index1\": {" + - " \"aliases\": {" + - " \"alias1\": {}," + - " \"alias11\": {" + - " \"filter\": {" + - " \"term\": {" + - " \"year\": \"2018\"" + - " }" + - " }," + - " \"index_routing\": \"2\"," + - " \"search_routing\": \"1,2\"" + - " }" + - " }" + - " }," + - " \"index3\": {" + - " \"aliases\": {}" + - " }" + - "}"; - */ - String out63 = "AwZpbmRleDECBmFsaWFzMQAAAAdhbGlhczExAS5VAaEbREZMAKpWqkxNLFKyUjIyMLRQqgUAAAD//wMAAQEyAQMxLDIGaW5kZXgyAQZhbGlhcz" - + "IAAAEDMSwyBmluZGV4MwA="; - - byte[] decode = Base64.getDecoder().decode(out63); - GetAliasesResponse inResponse = new GetAliasesResponse(); - - try (InputStream inBytes = new ByteArrayInputStream(decode); - StreamInput in = new InputStreamStreamInput(inBytes);) { - in.setVersion(Version.V_6_3_0); - inResponse.readFrom(in); - - ImmutableOpenMap> aliases = inResponse.getAliases(); - assertThat(aliases.size(), equalTo(3)); - - assertThat(aliases.containsKey("index1"), equalTo(true)); - List aliasesIndex1 = aliases.get("index1"); - assertThat(aliasesIndex1.size(), equalTo(2)); - - for (int i = 0; i < aliasesIndex1.size(); i++) { - AliasMetaData aliasMetaData = aliasesIndex1.get(i); - assertThat(aliasMetaData.alias(), anyOf(equalTo("alias1"), equalTo("alias11"))); - if (aliasMetaData.alias().equals("alias1")) { - assertThat(aliasMetaData.filter(), equalTo(null)); - assertThat(aliasMetaData.searchRouting(), equalTo(null)); - assertThat(aliasMetaData.indexRouting(), equalTo(null)); - } else if (aliasMetaData.alias().equals("alias11")) { - assertThat(aliasMetaData.filter(), equalTo(new CompressedXContent("{\"year\":\"2018\"}"))); - assertThat(aliasMetaData.indexRouting(), equalTo("2")); - assertThat(aliasMetaData.searchRouting(), equalTo("1,2")); - } - } - - assertThat(aliases.containsKey("index2"), equalTo(true)); - List aliasesIndex2 = aliases.get("index2"); - assertThat(aliasesIndex2.size(), equalTo(1)); - - AliasMetaData aliasMetaData = aliasesIndex2.get(0); - assertThat(aliasMetaData.alias(), equalTo("alias2")); - assertThat(aliasMetaData.filter(), equalTo(null)); - assertThat(aliasMetaData.searchRouting(), equalTo("1,2")); - assertThat(aliasMetaData.indexRouting(), equalTo(null)); - - assertThat(aliases.containsKey("index3"), equalTo(true)); - List aliasesIndex3 = aliases.get("index3"); - assertThat(aliasesIndex3.size(), equalTo(0)); - } - } } From 035d823122241e146584c84b770e9b72478666d4 Mon Sep 17 00:00:00 2001 From: javanna Date: Wed, 6 Jun 2018 21:16:56 +0200 Subject: [PATCH 15/17] address review comments --- .../client/GetAliasesResponseTests.java | 40 +++++++++---------- .../elasticsearch/client/IndicesClientIT.java | 6 ++- .../IndicesClientDocumentationIT.java | 4 +- .../indices/RestGetAllAliasesAction.java | 8 +--- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java index a98cd2475e8b8..e5762298bcd2e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java @@ -170,26 +170,26 @@ private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { public void testFromXContentWithElasticsearchException() throws IOException { String xContent = "{" + - " \"error\": {" + - " \"root_cause\": [" + - " {" + - " \"type\": \"index_not_found_exception\"," + - " \"reason\": \"no such index\"," + - " \"resource.type\": \"index_or_alias\"," + - " \"resource.id\": \"index\"," + - " \"index_uuid\": \"_na_\"," + - " \"index\": \"index\"" + - " }" + - " ]," + - " \"type\": \"index_not_found_exception\"," + - " \"reason\": \"no such index\"," + - " \"resource.type\": \"index_or_alias\"," + - " \"resource.id\": \"index\"," + - " \"index_uuid\": \"_na_\"," + - " \"index\": \"index\"" + - " }," + - " \"status\": 404" + - "}"; + " \"error\": {" + + " \"root_cause\": [" + + " {" + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }" + + " ]," + + " \"type\": \"index_not_found_exception\"," + + " \"reason\": \"no such index\"," + + " \"resource.type\": \"index_or_alias\"," + + " \"resource.id\": \"index\"," + + " \"index_uuid\": \"_na_\"," + + " \"index\": \"index\"" + + " }," + + " \"status\": 404" + + "}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); 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 a035c64cb095a..419dcf7fcc993 100644 --- 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 @@ -932,6 +932,10 @@ public void testGetAlias() throws IOException { } public void testGetAliasesNonExistentIndexOrAlias() throws IOException { + /* + * This test is quite extensive as this 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. + */ String alias = "alias"; String index = "index"; { @@ -984,8 +988,8 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { AliasMetaData aliasMetaData = getAliasesResponse.getAliases().get(index).iterator().next(); assertThat(aliasMetaData, notNullValue()); assertThat(aliasMetaData.alias(), equalTo(alias)); - /* + This is the above response in json format: { "error": "alias [something] missing", "status": 404, diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index 8758d2b2c1161..f9ad5ce661b0b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -88,7 +88,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.equalTo; /** * This class is used to generate the Java Indices API documentation. @@ -1768,7 +1768,6 @@ public void testGetAlias() throws Exception { new ActionListener() { @Override public void onResponse(GetAliasesResponse getAliasesResponse) { - // <1> } @@ -2033,7 +2032,6 @@ public void testPutTemplate() throws Exception { new ActionListener() { @Override public void onResponse(PutIndexTemplateResponse putTemplateResponse) { - // <1> } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java index a695598d7d7c7..87cadbafd8321 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetAllAliasesAction.java @@ -26,9 +26,7 @@ import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.BaseRestHandler; @@ -40,10 +38,8 @@ import java.io.IOException; import java.util.List; -import java.util.Set; import static org.elasticsearch.rest.RestRequest.Method.GET; -import static org.elasticsearch.rest.RestRequest.Method.HEAD; import static org.elasticsearch.rest.RestStatus.OK; /** @@ -89,8 +85,8 @@ public RestResponse buildResponse(final GetIndexResponse response, final XConten return new BytesRestResponse(OK, builder); } - private void writeAliases(final List aliases, final XContentBuilder builder, final Params params) - throws IOException { + private void writeAliases(final List aliases, final XContentBuilder builder, + final Params params) throws IOException { builder.startObject("aliases"); { if (aliases != null) { From 5da9ed6bcaf6f9f1ed96990c49ba981945e16472 Mon Sep 17 00:00:00 2001 From: javanna Date: Thu, 7 Jun 2018 10:47:24 +0200 Subject: [PATCH 16/17] fix javadocs --- .../src/main/java/org/elasticsearch/client/IndicesClient.java | 1 - 1 file changed, 1 deletion(-) 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 4e719a21169e4..93f36f5acfbf8 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 @@ -1021,7 +1021,6 @@ public UpdateSettingsResponse putSettings(UpdateSettingsRequest updateSettingsRe /** * Updates specific index level settings using the Update Indices Settings API. ->>>>>>> master *

* See Update Indices Settings * API on elastic.co From 5bcc1ce1ccc450fa3316daa1c9199fcce0bf1fc8 Mon Sep 17 00:00:00 2001 From: javanna Date: Mon, 11 Jun 2018 21:34:49 +0200 Subject: [PATCH 17/17] address review comments --- .../client/GetAliasesResponse.java | 93 ++++++++++++------- .../client/GetAliasesResponseTests.java | 90 +++--------------- .../elasticsearch/client/IndicesClientIT.java | 8 +- .../high-level/indices/get_alias.asciidoc | 3 +- 4 files changed, 78 insertions(+), 116 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java index fd889f42381c9..26bdcd2d26779 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/GetAliasesResponse.java @@ -30,24 +30,43 @@ import org.elasticsearch.rest.RestStatus; import java.io.IOException; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.Objects; import java.util.Set; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; +/** + * Response obtained from the get aliases API. + * The format is pretty horrible as it holds aliases, but at the same time errors can come back through the status and error fields. + * Such errors are mostly 404 - NOT FOUND for aliases that were specified but not found. In such case the client won't throw exception + * so it allows to retrieve the returned aliases, while at the same time checking if errors were returned. + * There's also the case where an exception is returned, like for instance an {@link org.elasticsearch.index.IndexNotFoundException}. + * We would usually throw such exception, but we configure the client to not throw for 404 to support the case above, hence we also not + * throw in case an index is not found, although it is a hard error that doesn't come back with aliases. + */ public class GetAliasesResponse extends ActionResponse implements StatusToXContentObject { private final RestStatus status; - private final String errorMessage; + private final String error; + private final ElasticsearchException exception; + private final Map> aliases; - public GetAliasesResponse(RestStatus status, String errorMessage, Map> aliases) { + GetAliasesResponse(RestStatus status, String error, Map> aliases) { this.status = status; - this.errorMessage = errorMessage; + this.error = error; this.aliases = aliases; + this.exception = null; + } + + private GetAliasesResponse(RestStatus status, ElasticsearchException exception) { + this.status = status; + this.error = null; + this.aliases = Collections.emptyMap(); + this.exception = exception; } @Override @@ -55,31 +74,25 @@ public RestStatus status() { return status; } - public String getErrorMessage() { - return errorMessage; - } - - public Map> getAliases() { - return aliases; + /** + * Return the possibly returned error, null otherwise + */ + public String getError() { + return error; } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GetAliasesResponse that = (GetAliasesResponse) o; - return status == that.status && - Objects.equals(errorMessage, that.errorMessage) && - Objects.equals(aliases, that.aliases); + /** + * Return the exception that may have been returned + */ + public ElasticsearchException getException() { + return exception; } - @Override - public int hashCode() { - return Objects.hash(status, errorMessage, aliases); + /** + * Return the requested aliases + */ + public Map> getAliases() { + return aliases; } @Override @@ -87,7 +100,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { if (status != RestStatus.OK) { - builder.field("error", errorMessage); + builder.field("error", error); builder.field("status", status.getStatus()); } @@ -109,6 +122,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws return builder; } + /** + * Parse the get aliases response + */ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOException { if (parser.currentToken() == null) { parser.nextToken(); @@ -118,7 +134,8 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx String currentFieldName; Token token; - String exceptionMessage = null; + String error = null; + ElasticsearchException exception = null; RestStatus status = RestStatus.OK; while (parser.nextToken() != Token.END_OBJECT) { @@ -131,13 +148,14 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx status = RestStatus.fromCode(parser.intValue()); } } else if ("error".equals(currentFieldName)) { - if ((token = parser.nextToken()) != Token.FIELD_NAME) { - if (token == Token.VALUE_STRING) { - exceptionMessage = parser.text(); - } else if (token == Token.START_OBJECT) { - parser.nextToken(); - exceptionMessage = ElasticsearchException.innerFromXContent(parser, true).getMessage(); - } + token = parser.nextToken(); + if (token == Token.VALUE_STRING) { + error = parser.text(); + } else if (token == Token.START_OBJECT) { + parser.nextToken(); + exception = ElasticsearchException.innerFromXContent(parser, true); + } else if (token == Token.START_ARRAY) { + parser.skipChildren(); } } else { String indexName = parser.currentName(); @@ -148,7 +166,12 @@ public static GetAliasesResponse fromXContent(XContentParser parser) throws IOEx } } } - return new GetAliasesResponse(status, exceptionMessage, aliases); + if (exception != null) { + assert error == null; + assert aliases.isEmpty(); + return new GetAliasesResponse(status, exception); + } + return new GetAliasesResponse(status, error, aliases); } private static Set parseAliases(XContentParser parser) throws IOException { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java index e5762298bcd2e..5f3354ad2b95d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/GetAliasesResponseTests.java @@ -24,17 +24,16 @@ import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.AbstractXContentTestCase; -import org.elasticsearch.test.EqualsHashCodeTestUtils; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Predicate; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; public class GetAliasesResponseTests extends AbstractXContentTestCase { @@ -94,77 +93,13 @@ protected boolean supportsUnknownFields() { return true; } - public void testEqualsAndHashCode() { - EqualsHashCodeTestUtils.checkEqualsAndHashCode(createTestInstance(), - response -> new GetAliasesResponse(response.status(), response.getErrorMessage(), response.getAliases()), - GetAliasesResponseTests::mutateInstance); - } - - private static GetAliasesResponse mutateInstance(GetAliasesResponse response) { - switch (randomInt(2)) { - case 0: - return new GetAliasesResponse(response.status(), response.getErrorMessage(), mutateAliases(response.getAliases())); - case 1: - return new GetAliasesResponse(randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), - response.getErrorMessage(), response.getAliases()); - case 2: - if (response.status() == RestStatus.OK) { - return new GetAliasesResponse(randomValueOtherThan(response.status(), () -> randomFrom(RestStatus.values())), - randomAlphaOfLengthBetween(5, 100), response.getAliases()); - } - return new GetAliasesResponse(response.status(), randomAlphaOfLengthBetween(5, 100), response.getAliases()); - default: - throw new UnsupportedOperationException(); - } - } - - private static Map> mutateAliases(Map> aliases) { - if (aliases.isEmpty()) { - return createIndicesAliasesMap(1, 3); - } - - if (randomBoolean()) { - Map> updatedMap = new HashMap<>(aliases); - Map> list = createIndicesAliasesMap(1, 2); - list.forEach((key, value) -> updatedMap.put(key, value)); - return updatedMap; - } - - Set indices = new HashSet<>(aliases.keySet()); - - List indicesToBeModified = randomSubsetOf(randomIntBetween(1, indices.size()), indices); - Map> map = new HashMap<>(); - - for (String index : indices) { - Set set = new HashSet<>(aliases.get(index)); - if (indicesToBeModified.contains(index)) { - if (randomBoolean() || set.isEmpty()) { - set.add(createAliasMetaData()); - } else { - AliasMetaData aliasMetaData = set.iterator().next(); - set.add(mutateAliasMetaData(aliasMetaData)); - } - } - map.put(index, set); - } - return map; - } - - private static AliasMetaData mutateAliasMetaData(AliasMetaData alias) { - boolean changeAlias = randomBoolean(); - AliasMetaData.Builder builder = AliasMetaData.builder(changeAlias ? randomAlphaOfLengthBetween(2, 5) : alias.getAlias()); - builder.searchRouting(alias.searchRouting()); - builder.indexRouting(alias.indexRouting()); - builder.filter(alias.filter()); - - if (false == changeAlias) { - if (randomBoolean()) { - builder.searchRouting(alias.searchRouting() + randomAlphaOfLengthBetween(1, 3)); - } else { - builder.indexRouting(alias.indexRouting() + randomAlphaOfLengthBetween(1, 3)); - } - } - return builder.build(); + @Override + protected void assertEqualInstances(GetAliasesResponse expectedInstance, GetAliasesResponse newInstance) { + assertEquals(expectedInstance.getAliases(), newInstance.getAliases()); + assertEquals(expectedInstance.status(), newInstance.status()); + assertEquals(expectedInstance.getError(), newInstance.getError()); + assertNull(expectedInstance.getException()); + assertNull(newInstance.getException()); } public void testFromXContentWithElasticsearchException() throws IOException { @@ -193,8 +128,9 @@ public void testFromXContentWithElasticsearchException() throws IOException { try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); + assertThat(getAliasesResponse.getError(), nullValue()); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), + assertThat(getAliasesResponse.getException().getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } } @@ -208,7 +144,8 @@ public void testFromXContentWithNoAliasFound() throws IOException { try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { GetAliasesResponse getAliasesResponse = GetAliasesResponse.fromXContent(parser); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), equalTo("alias [aa] missing")); + assertThat(getAliasesResponse.getError(), equalTo("alias [aa] missing")); + assertThat(getAliasesResponse.getException(), nullValue()); } } @@ -227,11 +164,12 @@ public void testFromXContentWithMissingAndFoundAlias() throws IOException { try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) { GetAliasesResponse response = GetAliasesResponse.fromXContent(parser); assertThat(response.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(response.getErrorMessage(), equalTo("alias [something] missing")); + assertThat(response.getError(), equalTo("alias [something] missing")); assertThat(response.getAliases().size(), equalTo(1)); assertThat(response.getAliases().get(index).size(), equalTo(1)); AliasMetaData aliasMetaData = response.getAliases().get(index).iterator().next(); assertThat(aliasMetaData.alias(), equalTo("alias")); + assertThat(response.getException(), nullValue()); } } } 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 b97b4638555e4..63736780bef9e 100644 --- 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 @@ -983,7 +983,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), + assertThat(getAliasesResponse.getException().getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { @@ -991,7 +991,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), equalTo("alias [" + alias + "] missing")); + assertThat(getAliasesResponse.getError(), equalTo("alias [" + alias + "] missing")); } createIndex(index, Settings.EMPTY); client().performRequest(HttpPut.METHOD_NAME, index + "/_alias/" + alias); @@ -1000,7 +1000,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), + assertThat(getAliasesResponse.getException().getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { @@ -1008,7 +1008,7 @@ public void testGetAliasesNonExistentIndexOrAlias() throws IOException { GetAliasesResponse getAliasesResponse = execute(getAliasesRequest, highLevelClient().indices()::getAlias, highLevelClient().indices()::getAliasAsync); assertThat(getAliasesResponse.status(), equalTo(RestStatus.NOT_FOUND)); - assertThat(getAliasesResponse.getErrorMessage(), + assertThat(getAliasesResponse.getException().getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]")); } { diff --git a/docs/java-rest/high-level/indices/get_alias.asciidoc b/docs/java-rest/high-level/indices/get_alias.asciidoc index cee3f9045c4d0..77a336e0a024c 100644 --- a/docs/java-rest/high-level/indices/get_alias.asciidoc +++ b/docs/java-rest/high-level/indices/get_alias.asciidoc @@ -33,7 +33,8 @@ include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request- include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-alias-request-indicesOptions] -------------------------------------------------- <1> Setting `IndicesOptions` controls how unavailable indices are resolved and -how wildcard expressions are expanded +how wildcard expressions are expanded when looking for aliases that belong to +specified indices. ["source","java",subs="attributes,callouts,macros"] --------------------------------------------------