Add support to _aliases endpoint to specify multiple indices and aliases in one action
Closes #15305
This commit is contained in:
parent
b4e0c876d5
commit
bef0bedba9
|
@ -78,19 +78,19 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
indices(indices);
|
||||
aliases(aliases);
|
||||
}
|
||||
|
||||
|
||||
public AliasActions(AliasAction.Type type, String index, String alias) {
|
||||
aliasAction = new AliasAction(type);
|
||||
indices(index);
|
||||
aliases(alias);
|
||||
}
|
||||
|
||||
|
||||
AliasActions(AliasAction.Type type, String[] index, String alias) {
|
||||
aliasAction = new AliasAction(type);
|
||||
indices(index);
|
||||
aliases(alias);
|
||||
}
|
||||
|
||||
|
||||
public AliasActions(AliasAction action) {
|
||||
this.aliasAction = action;
|
||||
indices(action.index());
|
||||
|
@ -110,7 +110,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
aliasAction.filter(filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public AliasActions filter(QueryBuilder filter) {
|
||||
aliasAction.filter(filter);
|
||||
return this;
|
||||
|
@ -197,7 +197,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
aliasAction = readAliasAction(in);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeStringArray(indices);
|
||||
out.writeStringArray(aliases);
|
||||
|
@ -225,7 +225,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
addAliasAction(new AliasActions(action));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an alias to the index.
|
||||
* @param alias The alias
|
||||
|
@ -247,8 +247,8 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
addAliasAction(new AliasActions(AliasAction.Type.ADD, indices, alias).filter(filterBuilder));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes an alias to the index.
|
||||
*
|
||||
|
@ -259,7 +259,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
addAliasAction(new AliasActions(AliasAction.Type.REMOVE, indices, aliases));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
for (AliasActions aliasAction : allAliasActions) {
|
||||
if (aliasAction.actionType() == AliasAction.Type.ADD) {
|
||||
if (aliasAction.aliases.length != 1) {
|
||||
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)
|
||||
+ "] requires exactly one [alias] to be set", 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);
|
||||
}
|
||||
+ "]: [alias] may not be empty string", validationException);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(aliasAction.indices)) {
|
||||
|
@ -345,7 +334,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
public IndicesOptions indicesOptions() {
|
||||
return INDICES_OPTIONS;
|
||||
}
|
||||
|
||||
|
||||
private static AliasActions readAliasActions(StreamInput in) throws IOException {
|
||||
AliasActions actions = new AliasActions();
|
||||
return actions.readFrom(in);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.rest.action.admin.indices.alias;
|
||||
|
||||
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.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.AliasAction;
|
||||
|
@ -30,9 +31,10 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.AcknowledgedRestListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.cluster.metadata.AliasAction.newAddAliasAction;
|
||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||
|
||||
/**
|
||||
|
@ -75,8 +77,8 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
|
|||
} else {
|
||||
throw new IllegalArgumentException("Alias action [" + action + "] not supported");
|
||||
}
|
||||
String index = null;
|
||||
String alias = null;
|
||||
String[] indices = null;
|
||||
String[] aliases = null;
|
||||
Map<String, Object> filter = null;
|
||||
String routing = null;
|
||||
boolean routingSet = false;
|
||||
|
@ -90,9 +92,9 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
if ("index".equals(currentFieldName)) {
|
||||
index = parser.text();
|
||||
indices = new String[] { parser.text() };
|
||||
} else if ("alias".equals(currentFieldName)) {
|
||||
alias = parser.text();
|
||||
aliases = new String[] { parser.text() };
|
||||
} else if ("routing".equals(currentFieldName)) {
|
||||
routing = parser.textOrNull();
|
||||
routingSet = true;
|
||||
|
@ -103,6 +105,23 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
|
|||
searchRouting = parser.textOrNull();
|
||||
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) {
|
||||
if ("filter".equals(currentFieldName)) {
|
||||
filter = parser.mapOrdered();
|
||||
|
@ -111,19 +130,19 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
|
|||
}
|
||||
|
||||
if (type == AliasAction.Type.ADD) {
|
||||
AliasAction aliasAction = newAddAliasAction(index, alias).filter(filter);
|
||||
AliasActions aliasActions = new AliasActions(type, indices, aliases);
|
||||
if (routingSet) {
|
||||
aliasAction.routing(routing);
|
||||
aliasActions.routing(routing);
|
||||
}
|
||||
if (indexRoutingSet) {
|
||||
aliasAction.indexRouting(indexRouting);
|
||||
aliasActions.indexRouting(indexRouting);
|
||||
}
|
||||
if (searchRoutingSet) {
|
||||
aliasAction.searchRouting(searchRouting);
|
||||
aliasActions.searchRouting(searchRouting);
|
||||
}
|
||||
indicesAliasesRequest.addAliasAction(aliasAction);
|
||||
indicesAliasesRequest.addAliasAction(aliasActions);
|
||||
} else if (type == AliasAction.Type.REMOVE) {
|
||||
indicesAliasesRequest.removeAlias(index, alias);
|
||||
indicesAliasesRequest.removeAlias(indices, aliases);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -759,7 +759,7 @@ public class IndexAliasesIT extends ESIntegTestCase {
|
|||
admin().indices().prepareAliases().addAliasAction(AliasAction.newAddAliasAction("index1", null)).get();
|
||||
fail("Expected ActionRequestValidationException");
|
||||
} 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();
|
||||
fail("Expected ActionRequestValidationException");
|
||||
} catch (ActionRequestValidationException e) {
|
||||
assertThat(e.getMessage(), containsString("requires an [alias] to be set"));
|
||||
assertThat(e.getMessage(), containsString("[alias] may not be empty string"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
[source,js]
|
||||
|
|
|
@ -32,3 +32,50 @@
|
|||
name: test_alias
|
||||
|
||||
- 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'}}
|
||||
|
|
Loading…
Reference in New Issue