Add support to _aliases endpoint to specify multiple indices and aliases in one action

Closes #15305
This commit is contained in:
Yannick Welsch 2015-12-07 17:23:53 +01:00
parent b4e0c876d5
commit bef0bedba9
5 changed files with 112 additions and 42 deletions

View File

@ -78,19 +78,19 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
indices(indices); indices(indices);
aliases(aliases); aliases(aliases);
} }
public AliasActions(AliasAction.Type type, String index, String alias) { public AliasActions(AliasAction.Type type, String index, String alias) {
aliasAction = new AliasAction(type); aliasAction = new AliasAction(type);
indices(index); indices(index);
aliases(alias); aliases(alias);
} }
AliasActions(AliasAction.Type type, String[] index, String alias) { AliasActions(AliasAction.Type type, String[] index, String alias) {
aliasAction = new AliasAction(type); aliasAction = new AliasAction(type);
indices(index); indices(index);
aliases(alias); aliases(alias);
} }
public AliasActions(AliasAction action) { public AliasActions(AliasAction action) {
this.aliasAction = action; this.aliasAction = action;
indices(action.index()); indices(action.index());
@ -110,7 +110,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
aliasAction.filter(filter); aliasAction.filter(filter);
return this; return this;
} }
public AliasActions filter(QueryBuilder filter) { public AliasActions filter(QueryBuilder filter) {
aliasAction.filter(filter); aliasAction.filter(filter);
return this; return this;
@ -197,7 +197,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
aliasAction = readAliasAction(in); aliasAction = readAliasAction(in);
return this; return this;
} }
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
out.writeStringArray(indices); out.writeStringArray(indices);
out.writeStringArray(aliases); out.writeStringArray(aliases);
@ -225,7 +225,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
addAliasAction(new AliasActions(action)); addAliasAction(new AliasActions(action));
return this; return this;
} }
/** /**
* Adds an alias to the index. * Adds an alias to the index.
* @param alias The alias * @param alias The alias
@ -247,8 +247,8 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
addAliasAction(new AliasActions(AliasAction.Type.ADD, indices, alias).filter(filterBuilder)); addAliasAction(new AliasActions(AliasAction.Type.ADD, indices, alias).filter(filterBuilder));
return this; return this;
} }
/** /**
* Removes an alias to the index. * Removes an alias to the index.
* *
@ -259,7 +259,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
addAliasAction(new AliasActions(AliasAction.Type.REMOVE, indices, aliases)); addAliasAction(new AliasActions(AliasAction.Type.REMOVE, indices, aliases));
return this; return this;
} }
/** /**
* Removes an alias to the index. * Removes an alias to the index.
* *
@ -286,25 +286,14 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
return addValidationError("Must specify at least one alias action", validationException); return addValidationError("Must specify at least one alias action", validationException);
} }
for (AliasActions aliasAction : allAliasActions) { for (AliasActions aliasAction : allAliasActions) {
if (aliasAction.actionType() == AliasAction.Type.ADD) { if (aliasAction.aliases.length == 0) {
if (aliasAction.aliases.length != 1) { validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH)
+ "]: aliases may not be empty", validationException);
}
for (String alias : aliasAction.aliases) {
if (!Strings.hasText(alias)) {
validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH) validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH)
+ "] requires exactly one [alias] to be set", validationException); + "]: [alias] may not be empty string", validationException);
}
if (!Strings.hasText(aliasAction.aliases[0])) {
validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH)
+ "] requires an [alias] to be set", validationException);
}
} else {
if (aliasAction.aliases.length == 0) {
validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH)
+ "]: aliases may not be empty", validationException);
}
for (String alias : aliasAction.aliases) {
if (!Strings.hasText(alias)) {
validationException = addValidationError("Alias action [" + aliasAction.actionType().name().toLowerCase(Locale.ENGLISH)
+ "]: [alias] may not be empty string", validationException);
}
} }
} }
if (CollectionUtils.isEmpty(aliasAction.indices)) { if (CollectionUtils.isEmpty(aliasAction.indices)) {
@ -345,7 +334,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
public IndicesOptions indicesOptions() { public IndicesOptions indicesOptions() {
return INDICES_OPTIONS; return INDICES_OPTIONS;
} }
private static AliasActions readAliasActions(StreamInput in) throws IOException { private static AliasActions readAliasActions(StreamInput in) throws IOException {
AliasActions actions = new AliasActions(); AliasActions actions = new AliasActions();
return actions.readFrom(in); return actions.readFrom(in);

View File

@ -20,6 +20,7 @@
package org.elasticsearch.rest.action.admin.indices.alias; package org.elasticsearch.rest.action.admin.indices.alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.AliasAction; import org.elasticsearch.cluster.metadata.AliasAction;
@ -30,9 +31,10 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.*; import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.AcknowledgedRestListener; import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.elasticsearch.cluster.metadata.AliasAction.newAddAliasAction;
import static org.elasticsearch.rest.RestRequest.Method.POST; import static org.elasticsearch.rest.RestRequest.Method.POST;
/** /**
@ -75,8 +77,8 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
} else { } else {
throw new IllegalArgumentException("Alias action [" + action + "] not supported"); throw new IllegalArgumentException("Alias action [" + action + "] not supported");
} }
String index = null; String[] indices = null;
String alias = null; String[] aliases = null;
Map<String, Object> filter = null; Map<String, Object> filter = null;
String routing = null; String routing = null;
boolean routingSet = false; boolean routingSet = false;
@ -90,9 +92,9 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
currentFieldName = parser.currentName(); currentFieldName = parser.currentName();
} else if (token.isValue()) { } else if (token.isValue()) {
if ("index".equals(currentFieldName)) { if ("index".equals(currentFieldName)) {
index = parser.text(); indices = new String[] { parser.text() };
} else if ("alias".equals(currentFieldName)) { } else if ("alias".equals(currentFieldName)) {
alias = parser.text(); aliases = new String[] { parser.text() };
} else if ("routing".equals(currentFieldName)) { } else if ("routing".equals(currentFieldName)) {
routing = parser.textOrNull(); routing = parser.textOrNull();
routingSet = true; routingSet = true;
@ -103,6 +105,23 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
searchRouting = parser.textOrNull(); searchRouting = parser.textOrNull();
searchRoutingSet = true; searchRoutingSet = true;
} }
} else if (token == XContentParser.Token.START_ARRAY) {
if ("indices".equals(currentFieldName)) {
List<String> indexNames = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
String index = parser.text();
indexNames.add(index);
}
indices = indexNames.toArray(new String[indexNames.size()]);
}
if ("aliases".equals(currentFieldName)) {
List<String> aliasNames = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
String alias = parser.text();
aliasNames.add(alias);
}
aliases = aliasNames.toArray(new String[aliasNames.size()]);
}
} else if (token == XContentParser.Token.START_OBJECT) { } else if (token == XContentParser.Token.START_OBJECT) {
if ("filter".equals(currentFieldName)) { if ("filter".equals(currentFieldName)) {
filter = parser.mapOrdered(); filter = parser.mapOrdered();
@ -111,19 +130,19 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
} }
if (type == AliasAction.Type.ADD) { if (type == AliasAction.Type.ADD) {
AliasAction aliasAction = newAddAliasAction(index, alias).filter(filter); AliasActions aliasActions = new AliasActions(type, indices, aliases);
if (routingSet) { if (routingSet) {
aliasAction.routing(routing); aliasActions.routing(routing);
} }
if (indexRoutingSet) { if (indexRoutingSet) {
aliasAction.indexRouting(indexRouting); aliasActions.indexRouting(indexRouting);
} }
if (searchRoutingSet) { if (searchRoutingSet) {
aliasAction.searchRouting(searchRouting); aliasActions.searchRouting(searchRouting);
} }
indicesAliasesRequest.addAliasAction(aliasAction); indicesAliasesRequest.addAliasAction(aliasActions);
} else if (type == AliasAction.Type.REMOVE) { } else if (type == AliasAction.Type.REMOVE) {
indicesAliasesRequest.removeAlias(index, alias); indicesAliasesRequest.removeAlias(indices, aliases);
} }
} }
} }

View File

@ -759,7 +759,7 @@ public class IndexAliasesIT extends ESIntegTestCase {
admin().indices().prepareAliases().addAliasAction(AliasAction.newAddAliasAction("index1", null)).get(); admin().indices().prepareAliases().addAliasAction(AliasAction.newAddAliasAction("index1", null)).get();
fail("Expected ActionRequestValidationException"); fail("Expected ActionRequestValidationException");
} catch (ActionRequestValidationException e) { } catch (ActionRequestValidationException e) {
assertThat(e.getMessage(), containsString("requires an [alias] to be set")); assertThat(e.getMessage(), containsString("[alias] may not be empty string"));
} }
} }
@ -768,7 +768,7 @@ public class IndexAliasesIT extends ESIntegTestCase {
admin().indices().prepareAliases().addAliasAction(AliasAction.newAddAliasAction("index1", "")).get(); admin().indices().prepareAliases().addAliasAction(AliasAction.newAddAliasAction("index1", "")).get();
fail("Expected ActionRequestValidationException"); fail("Expected ActionRequestValidationException");
} catch (ActionRequestValidationException e) { } catch (ActionRequestValidationException e) {
assertThat(e.getMessage(), containsString("requires an [alias] to be set")); assertThat(e.getMessage(), containsString("[alias] may not be empty string"));
} }
} }

View File

@ -63,7 +63,22 @@ curl -XPOST 'http://localhost:9200/_aliases' -d '
}' }'
-------------------------------------------------- --------------------------------------------------
Alternatively, you can use a glob pattern to associate an alias to Multiple indices can be specified for an action with the `indices` array syntax:
[source,js]
--------------------------------------------------
curl -XPOST 'http://localhost:9200/_aliases' -d '
{
"actions" : [
{ "add" : { "indices" : ["test1", "test2"], "alias" : "alias1" } }
]
}'
--------------------------------------------------
To specify multiple aliases in one action, the corresponding `aliases` array
syntax exists as well.
For the example above, a glob pattern can also be used to associate an alias to
more than one index that share a common name: more than one index that share a common name:
[source,js] [source,js]

View File

@ -32,3 +32,50 @@
name: test_alias name: test_alias
- match: {test_index.aliases.test_alias: {'index_routing': 'routing_value', 'search_routing': 'routing_value'}} - match: {test_index.aliases.test_alias: {'index_routing': 'routing_value', 'search_routing': 'routing_value'}}
---
"Basic test for multiple aliases":
- do:
indices.create:
index: test_index
- do:
indices.exists_alias:
name: test_alias1
- is_false: ''
- do:
indices.exists_alias:
name: test_alias2
- is_false: ''
- do:
indices.update_aliases:
body:
actions:
- add:
indices: [test_index]
aliases: [test_alias1, test_alias2]
routing: routing_value
- do:
indices.exists_alias:
name: test_alias1
- is_true: ''
- do:
indices.exists_alias:
name: test_alias2
- is_true: ''
- do:
indices.get_alias:
index: test_index
- match: {test_index.aliases.test_alias1: {'index_routing': 'routing_value', 'search_routing': 'routing_value'}}
- match: {test_index.aliases.test_alias2: {'index_routing': 'routing_value', 'search_routing': 'routing_value'}}