Browse Source

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

Closes #15305
Yannick Welsch 10 years ago
parent
commit
bef0bedba9

+ 17 - 28
core/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequest.java

@@ -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) {
-                    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) {
+            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)
-                            + "]: 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);

+ 30 - 11
core/src/main/java/org/elasticsearch/rest/action/admin/indices/alias/RestIndicesAliasesAction.java

@@ -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);
                             }
                         }
                     }

+ 2 - 2
core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java

@@ -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"));
         }
     }
 

+ 16 - 1
docs/reference/indices/aliases.asciidoc

@@ -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]

+ 47 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/indices.update_aliases/10_basic.yaml

@@ -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'}}