Browse Source

Replaced `ignore_indices` with `ignore_unavailable`, `expand_wildcards` and `allow_no_indices`.

* `ignore_unavailable` - Controls whether to ignore if any specified indices are unavailable, this includes indices that don't exist or closed indices. Either `true` or `false` can be specified.
* `allow_no_indices` - Controls whether to fail if a wildcard indices expressions results into no concrete indices. Either `true` or `false` can be specified. For example if the wildcard expression `foo*` is specified and no indices are available that start with `foo` then depending on this setting the request will fail. This setting is also applicable when `_all`, `*` or no index has been specified.
* `expand_wildcards` - Controls to what kind of concrete indices wildcard indices expression expand to. If `open` is specified then the wildcard expression if expanded to only open indices and if `closed` is specified then the wildcard expression if expanded only to closed indices. Also both values (`open,closed`) can be specified to expand to all indices.

Closes to #4436
Martijn van Groningen 12 years ago
parent
commit
f4bf0d5112
100 changed files with 1036 additions and 480 deletions
  1. 12 3
      docs/reference/api-conventions.asciidoc
  2. 2 2
      docs/reference/indices/aliases.asciidoc
  3. 1 1
      docs/reference/indices/open-close.asciidoc
  4. 4 4
      docs/reference/modules/snapshots.asciidoc
  5. 1 1
      docs/reference/search/percolate.asciidoc
  6. 13 5
      rest-api-spec/api/count.json
  7. 13 5
      rest-api-spec/api/delete_by_query.json
  8. 13 5
      rest-api-spec/api/indices.clear_cache.json
  9. 13 5
      rest-api-spec/api/indices.exists_alias.json
  10. 13 5
      rest-api-spec/api/indices.exists_type.json
  11. 13 5
      rest-api-spec/api/indices.flush.json
  12. 13 5
      rest-api-spec/api/indices.get_alias.json
  13. 13 5
      rest-api-spec/api/indices.optimize.json
  14. 13 5
      rest-api-spec/api/indices.refresh.json
  15. 13 5
      rest-api-spec/api/indices.segments.json
  16. 13 5
      rest-api-spec/api/indices.snapshot_index.json
  17. 14 6
      rest-api-spec/api/indices.stats.json
  18. 13 5
      rest-api-spec/api/indices.status.json
  19. 13 5
      rest-api-spec/api/indices.validate_query.json
  20. 13 5
      rest-api-spec/api/search.json
  21. 13 5
      rest-api-spec/api/suggest.json
  22. 2 1
      rest-api-spec/test/indices.segments/10_basic.yaml
  23. 8 8
      src/main/java/org/elasticsearch/action/admin/cluster/shards/ClusterSearchShardsRequest.java
  24. 5 4
      src/main/java/org/elasticsearch/action/admin/cluster/shards/ClusterSearchShardsRequestBuilder.java
  25. 1 1
      src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java
  26. 31 20
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java
  27. 6 6
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestBuilder.java
  28. 1 1
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/TransportCreateSnapshotAction.java
  29. 34 20
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java
  30. 7 6
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequestBuilder.java
  31. 1 1
      src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/TransportRestoreSnapshotAction.java
  32. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/alias/exists/TransportAliasesExistAction.java
  33. 7 0
      src/main/java/org/elasticsearch/action/admin/indices/alias/get/BaseAliasesRequestBuilder.java
  34. 8 8
      src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java
  35. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java
  36. 16 12
      src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequest.java
  37. 7 5
      src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java
  38. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java
  39. 14 1
      src/main/java/org/elasticsearch/action/admin/indices/delete/DeleteIndexRequest.java
  40. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/delete/DeleteIndexRequestBuilder.java
  41. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java
  42. 15 1
      src/main/java/org/elasticsearch/action/admin/indices/exists/indices/IndicesExistsRequest.java
  43. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/exists/indices/IndicesExistsRequestBuilder.java
  44. 8 5
      src/main/java/org/elasticsearch/action/admin/indices/exists/indices/TransportIndicesExistsAction.java
  45. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/exists/types/TransportTypesExistsAction.java
  46. 8 8
      src/main/java/org/elasticsearch/action/admin/indices/exists/types/TypesExistsRequest.java
  47. 4 4
      src/main/java/org/elasticsearch/action/admin/indices/exists/types/TypesExistsRequestBuilder.java
  48. 13 1
      src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/DeleteMappingRequest.java
  49. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/DeleteMappingRequestBuilder.java
  50. 1 2
      src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/TransportDeleteMappingAction.java
  51. 14 0
      src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java
  52. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequestBuilder.java
  53. 1 2
      src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java
  54. 16 12
      src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexRequest.java
  55. 7 5
      src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexRequestBuilder.java
  56. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/open/TransportOpenIndexAction.java
  57. 2 0
      src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsRequest.java
  58. 6 1
      src/main/java/org/elasticsearch/action/admin/indices/settings/TransportUpdateSettingsAction.java
  59. 13 1
      src/main/java/org/elasticsearch/action/admin/indices/settings/UpdateSettingsRequest.java
  60. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/settings/UpdateSettingsRequestBuilder.java
  61. 3 0
      src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java
  62. 13 1
      src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/DeleteWarmerRequest.java
  63. 11 0
      src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/DeleteWarmerRequestBuilder.java
  64. 1 1
      src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/TransportDeleteWarmerAction.java
  65. 2 2
      src/main/java/org/elasticsearch/action/admin/indices/warmer/put/TransportPutWarmerAction.java
  66. 61 16
      src/main/java/org/elasticsearch/action/percolate/MultiPercolateRequest.java
  67. 6 4
      src/main/java/org/elasticsearch/action/percolate/MultiPercolateRequestBuilder.java
  68. 0 3
      src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java
  69. 9 2
      src/main/java/org/elasticsearch/action/percolate/TransportMultiPercolateAction.java
  70. 44 14
      src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java
  71. 11 9
      src/main/java/org/elasticsearch/action/search/MultiSearchRequestBuilder.java
  72. 8 8
      src/main/java/org/elasticsearch/action/search/SearchRequest.java
  73. 6 4
      src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java
  74. 1 1
      src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
  75. 1 1
      src/main/java/org/elasticsearch/action/search/type/TransportSearchTypeAction.java
  76. 0 65
      src/main/java/org/elasticsearch/action/support/IgnoreIndices.java
  77. 169 0
      src/main/java/org/elasticsearch/action/support/IndicesOptions.java
  78. 8 8
      src/main/java/org/elasticsearch/action/support/broadcast/BroadcastOperationRequest.java
  79. 3 3
      src/main/java/org/elasticsearch/action/support/broadcast/BroadcastOperationRequestBuilder.java
  80. 2 1
      src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastOperationAction.java
  81. 8 8
      src/main/java/org/elasticsearch/action/support/master/info/ClusterInfoRequest.java
  82. 3 3
      src/main/java/org/elasticsearch/action/support/master/info/ClusterInfoRequestBuilder.java
  83. 1 1
      src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java
  84. 10 10
      src/main/java/org/elasticsearch/action/support/replication/IndicesReplicationOperationRequest.java
  85. 6 4
      src/main/java/org/elasticsearch/action/support/replication/IndicesReplicationOperationRequestBuilder.java
  86. 1 1
      src/main/java/org/elasticsearch/action/support/replication/TransportIndicesReplicationOperationAction.java
  87. 73 19
      src/main/java/org/elasticsearch/cluster/metadata/MetaData.java
  88. 0 3
      src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java
  89. 3 6
      src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java
  90. 8 0
      src/main/java/org/elasticsearch/common/collect/ImmutableOpenMap.java
  91. 1 11
      src/main/java/org/elasticsearch/index/query/IndicesFilterParser.java
  92. 1 11
      src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java
  93. 2 4
      src/main/java/org/elasticsearch/rest/action/admin/cluster/shards/RestClusterSearchShardsAction.java
  94. 2 5
      src/main/java/org/elasticsearch/rest/action/admin/indices/alias/get/RestGetAliasesAction.java
  95. 2 5
      src/main/java/org/elasticsearch/rest/action/admin/indices/alias/head/RestAliasesExistAction.java
  96. 2 4
      src/main/java/org/elasticsearch/rest/action/admin/indices/cache/clear/RestClearIndicesCacheAction.java
  97. 2 4
      src/main/java/org/elasticsearch/rest/action/admin/indices/close/RestCloseIndexAction.java
  98. 2 0
      src/main/java/org/elasticsearch/rest/action/admin/indices/delete/RestDeleteIndexAction.java
  99. 2 0
      src/main/java/org/elasticsearch/rest/action/admin/indices/exists/indices/RestIndicesExistsAction.java
  100. 2 4
      src/main/java/org/elasticsearch/rest/action/admin/indices/exists/types/RestTypesExistsAction.java

+ 12 - 3
docs/reference/api-conventions.asciidoc

@@ -25,9 +25,18 @@ using simple `test1,test2,test3` notation (or `_all` for all indices). It also
 support wildcards, for example: `test*`, and the ability to "add" (`+`)
 and "remove" (`-`), for example: `+test*,-test3`.
 
-All multi indices API support the `ignore_indices` option. Setting it to
-`missing` will cause indices that do not exists to be ignored from the
-execution. By default, when it's not set, the request will fail.
+All multi indices API support the following url query string parameters:
+* `ignore_unavailable` - Controls whether to ignore if any specified indices are unavailable, this includes indices
+   that don't exist or closed indices. Either `true` or `false` can be specified.
+* `allow_no_indices` - Controls whether to fail if a wildcard indices expressions results into no concrete indices.
+   Either `true` or `false` can be specified. For example if the wildcard expression `foo*` is specified and no indices
+   are available that start with `foo` then depending on this setting the request will fail. This setting is also applicable
+   when `_all`, `*` or no index has been specified.
+* `expand_wildcards` - Controls to what kind of concrete indices wildcard indices expression expand to. If `open` is
+  specified then the wildcard expression if expanded to only open indices and if `closed` is specified then the wildcard
+  expression if expanded only to closed indices. Also both values (`open,closed`) can be specified to expand to all indices.
+
+The defaults settings for the above parameters dependent on the api being used.
 
 NOTE: Single index APIs such as the <<docs>> and the
 <<indices-aliases,single-index `alias` APIs>> do not support multiple indices.

+ 2 - 2
docs/reference/indices/aliases.asciidoc

@@ -229,9 +229,9 @@ Possible options:
     option, this option supports wildcards and the option the specify
     multiple alias names separated by a comma. This is a required option. 
 
-`ignore_indices`::
+`ignore_unavailable`::
     What to do is an specified index name doesn't
-    exist. If set to `missing` then those indices are ignored.
+    exist. If set to `true` then those indices are ignored.
 
 The rest endpoint is: `/{index}/_alias/{alias}`.
 

+ 1 - 1
docs/reference/indices/open-close.asciidoc

@@ -19,7 +19,7 @@ curl -XPOST 'localhost:9200/my_index/_open'
 
 It is possible to open and close multiple indices. An error will be thrown
 if the request explicitly refers to a missing index. This behaviour can be
-disabled using the `ignore_indices=missing` parameter.
+disabled using the `ignore_unavailable=true` parameter.
 
 All indices can be opened or closed at once using `_all` as the index name
 or specifying patterns that identify them all (e.g. `*`).

+ 4 - 4
docs/reference/modules/snapshots.asciidoc

@@ -91,15 +91,15 @@ by specifying the list of indices in the body of the snapshot request.
 -----------------------------------
 $ curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1" -d '{
     "indices": "index_1,index_2",
-    "ignore_indices": "missing",
+    "ignore_unavailable": "true",
     "include_global_state": false
 }'
 -----------------------------------
 
 The list of indices that should be included into the snapshot can be specified using the `indices` parameter that
 supports <<search-multi-index-type,multi index syntax>>. The snapshot request also supports the
-`ignore_indices` option. Setting it to `missing` will cause indices that do not exists to be ignored during snapshot
-creation. By default, when `ignore_indices` option is not set and an index is missing the snapshot request will fail.
+`ignore_unavailable` option. Setting it to `true` will cause indices that do not exists to be ignored during snapshot
+creation. By default, when `ignore_unavailable` option is not set and an index is missing the snapshot request will fail.
 By setting `include_global_state` to false it's possible to prevent the cluster global state to be stored as part of
 the snapshot.
 
@@ -169,7 +169,7 @@ http://docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html#appendRepl
 -----------------------------------
 $ curl -XPOST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore" -d '{
     "indices": "index_1,index_2",
-    "ignore_indices": "missing",
+    "ignore_unavailable": "missing",
     "include_global_state": false,
     "rename_pattern": "index_(.)+",
     "rename_replacement": "restored_index_$1"

+ 1 - 1
docs/reference/search/percolate.asciidoc

@@ -177,7 +177,7 @@ that the percolate request only gets executed on the shard where the routing val
 the percolate request only gets executed on one shard instead of all shards. Multiple values can be specified as a
 comma separated string, in that case the request can be be executed on more than one shard.
 * `preference` - Controls which shard replicas are preferred to execute the request on. Works the same as in the search api.
-* `ignore_indices` - Controls if missing indices should silently be ignored. Same as is in the search api.
+* `ignore_unavailable` - Controls if missing concrete indices should silently be ignored. Same as is in the search api.
 * `percolate_format` - If `ids` is specified then the matches array in the percolate response will contain a string
 array of the matching ids instead of an array of objects. This can be useful the reduce the amount of data being send
 back to the client. Obviously if there are to percolator queries with same id from different indices there is no way

+ 13 - 5
rest-api-spec/api/count.json

@@ -16,11 +16,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+          "type" : "boolean",
+          "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+           "type" : "boolean",
+           "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "min_score": {
           "type" : "number",

+ 13 - 5
rest-api-spec/api/delete_by_query.json

@@ -36,11 +36,19 @@
           "type" : "string",
           "description" : "The field to use as default where no field prefix is given in the query string"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "replication": {
           "type" : "enum",

+ 13 - 5
rest-api-spec/api/indices.clear_cache.json

@@ -44,11 +44,19 @@
           "type" : "boolean",
           "description" : "Clear ID caches for parent/child"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "index": {
           "type" : "list",

+ 13 - 5
rest-api-spec/api/indices.exists_alias.json

@@ -17,11 +17,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+           "type" : "boolean",
+           "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+           "type" : "enum",
+           "options" : ["open","closed"],
+           "default" : ["open", "closed"],
+           "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         }
       }
     },

+ 13 - 5
rest-api-spec/api/indices.exists_type.json

@@ -18,11 +18,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         }
       }
     },

+ 13 - 5
rest-api-spec/api/indices.flush.json

@@ -20,11 +20,19 @@
           "type" : "boolean",
           "description" : "TODO: ?"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "refresh": {
           "type" : "boolean",

+ 13 - 5
rest-api-spec/api/indices.get_alias.json

@@ -17,11 +17,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         }
       }
     },

+ 13 - 5
rest-api-spec/api/indices.optimize.json

@@ -16,11 +16,19 @@
           "type" : "boolean",
           "description" : "Specify whether the index should be flushed after performing the operation (default: true)"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "max_num_segments": {
           "type" : "number",

+ 13 - 5
rest-api-spec/api/indices.refresh.json

@@ -12,11 +12,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "operation_threading": {
           "description" : "TODO: ?"

+ 13 - 5
rest-api-spec/api/indices.segments.json

@@ -12,11 +12,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "operation_threading": {
           "description" : "TODO: ?"

+ 13 - 5
rest-api-spec/api/indices.snapshot_index.json

@@ -12,11 +12,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         }
       }
     },

+ 14 - 6
rest-api-spec/api/indices.stats.json

@@ -32,7 +32,7 @@
         },
         "metric_family" : {
           "type" : "enum",
-          "options" : ["completion","docs", "fielddata", "filter_cache", "flush", "get", "groups", "id_cache", "ignore_indices", "indexing", "merge", "refresh", "search", "store", "warmer"],
+          "options" : ["completion","docs", "fielddata", "filter_cache", "flush", "get", "groups", "id_cache", "percolate", "indexing", "merge", "refresh", "search", "store", "warmer"],
           "description" : "Limit the information returned to a specific metric"
         },
         "search_groups" : {
@@ -93,11 +93,19 @@
           "type" : "boolean",
           "description" : "Return information about ID cache"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "indexing": {
           "type" : "boolean",

+ 13 - 5
rest-api-spec/api/indices.status.json

@@ -12,11 +12,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "operation_threading": {
           "description" : "TODO: ?"

+ 13 - 5
rest-api-spec/api/indices.validate_query.json

@@ -20,11 +20,19 @@
           "type" : "boolean",
           "description" : "Return detailed information about the error"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "operation_threading": {
           "description" : "TODO: ?"

+ 13 - 5
rest-api-spec/api/search.json

@@ -47,11 +47,19 @@
           "type" : "number",
           "description" : "Starting offset (default: 0)"
         },
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "indices_boost": {
           "type" : "list",

+ 13 - 5
rest-api-spec/api/suggest.json

@@ -12,11 +12,19 @@
         }
       },
       "params": {
-        "ignore_indices": {
-          "type" : "enum",
-          "options" : ["none","missing"],
-          "default" : "none",
-          "description" : "When performed on multiple indices, allows to ignore `missing` ones"
+        "ignore_unavailable": {
+            "type" : "boolean",
+            "description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
+        },
+        "allow_no_indices": {
+            "type" : "boolean",
+            "description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
+        },
+        "expand_wildcards": {
+            "type" : "enum",
+            "options" : ["open","closed"],
+            "default" : "open",
+            "description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
         },
         "preference": {
           "type" : "string",

+ 2 - 1
rest-api-spec/test/indices.segments/10_basic.yaml

@@ -1,6 +1,7 @@
 ---
 "segments test":
   - do:
-      indices.segments: {}
+      indices.segments:
+        allow_no_indices: true
   
   - is_true: ok

+ 8 - 8
src/main/java/org/elasticsearch/action/admin/cluster/shards/ClusterSearchShardsRequest.java

@@ -21,7 +21,7 @@ package org.elasticsearch.action.admin.cluster.shards;
 
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.Strings;
@@ -40,7 +40,7 @@ public class ClusterSearchShardsRequest extends MasterNodeOperationRequest<Clust
     private String preference;
     private boolean local = false;
     private String[] types = Strings.EMPTY_ARRAY;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.lenient();
 
 
     public ClusterSearchShardsRequest() {
@@ -79,12 +79,12 @@ public class ClusterSearchShardsRequest extends MasterNodeOperationRequest<Clust
         return indices;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public ClusterSearchShardsRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public ClusterSearchShardsRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -164,7 +164,7 @@ public class ClusterSearchShardsRequest extends MasterNodeOperationRequest<Clust
         preference = in.readOptionalString();
 
         types = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         local = in.readBoolean();
     }
 
@@ -181,7 +181,7 @@ public class ClusterSearchShardsRequest extends MasterNodeOperationRequest<Clust
         out.writeOptionalString(preference);
 
         out.writeStringArray(types);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
         out.writeBoolean(local);
     }
 

+ 5 - 4
src/main/java/org/elasticsearch/action/admin/cluster/shards/ClusterSearchShardsRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.cluster.shards;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.ClusterAdminClient;
 import org.elasticsearch.client.internal.InternalClusterAdminClient;
@@ -77,10 +77,11 @@ public class ClusterSearchShardsRequestBuilder extends MasterNodeOperationReques
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal indices wildcard expressions.
+     * For example indices that don't exist.
      */
-    public ClusterSearchShardsRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request().ignoreIndices(ignoreIndices);
+    public ClusterSearchShardsRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request().indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java

@@ -76,7 +76,7 @@ public class TransportClusterSearchShardsAction extends TransportMasterNodeOpera
     @Override
     protected void masterOperation(final ClusterSearchShardsRequest request, final ClusterState state, final ActionListener<ClusterSearchShardsResponse> listener) throws ElasticSearchException {
         ClusterState clusterState = clusterService.state();
-        String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+        String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.indicesOptions());
         Map<String, Set<String>> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
         Set<String> nodeIds = newHashSet();
         GroupShardsIterator groupShardsIterator = clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());

+ 31 - 20
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java

@@ -22,7 +22,7 @@ package org.elasticsearch.action.admin.cluster.snapshots.create;
 import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesReference;
@@ -68,7 +68,7 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
 
     private String[] indices = EMPTY_ARRAY;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     private Settings settings = EMPTY_SETTINGS;
 
@@ -108,8 +108,8 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
                 break;
             }
         }
-        if (ignoreIndices == null) {
-            validationException = addValidationError("ignoreIndices is null", validationException);
+        if (indicesOptions == null) {
+            validationException = addValidationError("indicesOptions is null", validationException);
         }
         if (settings == null) {
             validationException = addValidationError("settings is null", validationException);
@@ -196,22 +196,22 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies the indices options. Like what type of requested indices to ignore. For example indices that don't exist.
      *
-     * @return the desired behaviour regarding indices to ignore
+     * @return the desired behaviour regarding indices options
      */
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies the indices options. Like what type of requested indices to ignore. For example indices that don't exist.
      *
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * @param indicesOptions the desired behaviour regarding indices options
      * @return this request
      */
-    public CreateSnapshotRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public CreateSnapshotRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -338,6 +338,10 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
      * @return this request
      */
     public CreateSnapshotRequest source(Map source) {
+        boolean ignoreUnavailable = IndicesOptions.lenient().ignoreUnavailable();
+        boolean allowNoIndices = IndicesOptions.lenient().allowNoIndices();
+        boolean expandWildcardsOpen = IndicesOptions.lenient().expandWildcardsOpen();
+        boolean expandWildcardsClosed = IndicesOptions.lenient().expandWildcardsClosed();
         for (Map.Entry<String, Object> entry : ((Map<String, Object>) source).entrySet()) {
             String name = entry.getKey();
             if (name.equals("indices")) {
@@ -348,12 +352,18 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
                 } else {
                     throw new ElasticSearchIllegalArgumentException("malformed indices section, should be an array of strings");
                 }
-            } else if (name.equals("ignore_indices")) {
-                if (entry.getValue() instanceof String) {
-                    ignoreIndices(IgnoreIndices.fromString((String) entry.getValue()));
-                } else {
-                    throw new ElasticSearchIllegalArgumentException("malformed ignore_indices");
-                }
+            } else if (name.equals("ignore_unavailable") || name.equals("ignoreUnavailable")) {
+                assert entry.getValue() instanceof String;
+                ignoreUnavailable = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("allow_no_indices") || name.equals("allowNoIndices")) {
+                assert entry.getValue() instanceof String;
+                allowNoIndices = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("expand_wildcards_open") || name.equals("expandWildcardsOpen")) {
+                assert entry.getValue() instanceof String;
+                expandWildcardsOpen = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("expand_wildcards_closed") || name.equals("expandWildcardsClosed")) {
+                assert entry.getValue() instanceof String;
+                expandWildcardsClosed = Boolean.valueOf(entry.getValue().toString());
             } else if (name.equals("settings")) {
                 if (!(entry.getValue() instanceof Map)) {
                     throw new ElasticSearchIllegalArgumentException("malformed settings section, should indices an inner object");
@@ -366,6 +376,7 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
                 includeGlobalState((Boolean) entry.getValue());
             }
         }
+        indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
         return this;
     }
 
@@ -435,7 +446,7 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
         snapshot = in.readString();
         repository = in.readString();
         indices = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         settings = readSettingsFromStream(in);
         includeGlobalState = in.readBoolean();
         waitForCompletion = in.readBoolean();
@@ -447,7 +458,7 @@ public class CreateSnapshotRequest extends MasterNodeOperationRequest<CreateSnap
         out.writeString(snapshot);
         out.writeString(repository);
         out.writeStringArray(indices);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
         writeSettingsToStream(settings, out);
         out.writeBoolean(includeGlobalState);
         out.writeBoolean(waitForCompletion);

+ 6 - 6
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.cluster.snapshots.create;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.ClusterAdminClient;
 import org.elasticsearch.client.internal.InternalClusterAdminClient;
@@ -91,13 +91,13 @@ public class CreateSnapshotRequestBuilder extends MasterNodeOperationRequestBuil
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies the indices options. Like what type of requested indices to ignore. For example indices that don't exist.
      *
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
-     * @return this builder
+     * @param indicesOptions the desired behaviour regarding indices options
+     * @return this request
      */
-    public CreateSnapshotRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public CreateSnapshotRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/TransportCreateSnapshotAction.java

@@ -77,7 +77,7 @@ public class TransportCreateSnapshotAction extends TransportMasterNodeOperationA
         SnapshotsService.SnapshotRequest snapshotRequest =
                 new SnapshotsService.SnapshotRequest("create_snapshot[" + request.snapshot() + "]", request.snapshot(), request.repository())
                         .indices(request.indices())
-                        .ignoreIndices(request.ignoreIndices())
+                        .indicesOptions(request.indicesOptions())
                         .settings(request.settings())
                         .includeGlobalState(request.includeGlobalState())
                         .masterNodeTimeout(request.masterNodeTimeout());

+ 34 - 20
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java

@@ -22,7 +22,7 @@ package org.elasticsearch.action.admin.cluster.snapshots.restore;
 import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesReference;
@@ -56,7 +56,7 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
 
     private String[] indices = Strings.EMPTY_ARRAY;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     private String renamePattern;
 
@@ -94,8 +94,8 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
         if (indices == null) {
             validationException = addValidationError("indices are missing", validationException);
         }
-        if (ignoreIndices == null) {
-            validationException = addValidationError("ignoreIndices is missing", validationException);
+        if (indicesOptions == null) {
+            validationException = addValidationError("indicesOptions is missing", validationException);
         }
         if (settings == null) {
             validationException = addValidationError("settings are missing", validationException);
@@ -184,22 +184,24 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
      *
-     * @return the desired behaviour regarding indices to ignore
+     * @return the desired behaviour regarding indices to ignore and wildcard indices expression
      */
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
      *
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions
      * @return this request
      */
-    public RestoreSnapshotRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public RestoreSnapshotRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -379,6 +381,11 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
      * @return this request
      */
     public RestoreSnapshotRequest source(Map source) {
+        boolean ignoreUnavailable = IndicesOptions.lenient().ignoreUnavailable();
+        boolean allowNoIndices = IndicesOptions.lenient().allowNoIndices();
+        boolean expandWildcardsOpen = IndicesOptions.lenient().expandWildcardsOpen();
+        boolean expandWildcardsClosed = IndicesOptions.lenient().expandWildcardsClosed();
+
         for (Map.Entry<String, Object> entry : ((Map<String, Object>) source).entrySet()) {
             String name = entry.getKey();
             if (name.equals("indices")) {
@@ -389,12 +396,18 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
                 } else {
                     throw new ElasticSearchIllegalArgumentException("malformed indices section, should be an array of strings");
                 }
-            } else if (name.equals("ignore_indices")) {
-                if (entry.getValue() instanceof String) {
-                    ignoreIndices(IgnoreIndices.fromString((String) entry.getValue()));
-                } else {
-                    throw new ElasticSearchIllegalArgumentException("malformed ignore_indices");
-                }
+            } else if (name.equals("ignore_unavailable") || name.equals("ignoreUnavailable")) {
+                assert entry.getValue() instanceof String;
+                ignoreUnavailable = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("allow_no_indices") || name.equals("allowNoIndices")) {
+                assert entry.getValue() instanceof String;
+                allowNoIndices = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("expand_wildcards_open") || name.equals("expandWildcardsOpen")) {
+                assert entry.getValue() instanceof String;
+                expandWildcardsOpen = Boolean.valueOf(entry.getValue().toString());
+            } else if (name.equals("expand_wildcards_closed") || name.equals("expandWildcardsClosed")) {
+                assert entry.getValue() instanceof String;
+                expandWildcardsClosed = Boolean.valueOf(entry.getValue().toString());
             } else if (name.equals("settings")) {
                 if (!(entry.getValue() instanceof Map)) {
                     throw new ElasticSearchIllegalArgumentException("malformed settings section, should indices an inner object");
@@ -421,6 +434,7 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
                 throw new ElasticSearchIllegalArgumentException("Unknown parameter " + name);
             }
         }
+        indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
         return this;
     }
 
@@ -498,7 +512,7 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
         snapshot = in.readString();
         repository = in.readString();
         indices = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         renamePattern = in.readOptionalString();
         renameReplacement = in.readOptionalString();
         waitForCompletion = in.readBoolean();
@@ -512,7 +526,7 @@ public class RestoreSnapshotRequest extends MasterNodeOperationRequest<RestoreSn
         out.writeString(snapshot);
         out.writeString(repository);
         out.writeStringArray(indices);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
         out.writeOptionalString(renamePattern);
         out.writeOptionalString(renameReplacement);
         out.writeBoolean(waitForCompletion);

+ 7 - 6
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.cluster.snapshots.restore;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.ClusterAdminClient;
 import org.elasticsearch.client.internal.InternalClusterAdminClient;
@@ -92,13 +92,14 @@ public class RestoreSnapshotRequestBuilder extends MasterNodeOperationRequestBui
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
      *
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
-     * @return this builder
+     * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions
+     * @return this request
      */
-    public RestoreSnapshotRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public RestoreSnapshotRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/TransportRestoreSnapshotAction.java

@@ -78,7 +78,7 @@ public class TransportRestoreSnapshotAction extends TransportMasterNodeOperation
         RestoreService.RestoreRequest restoreRequest =
                 new RestoreService.RestoreRequest("restore_snapshot[" + request.snapshot() + "]", request.repository(), request.snapshot())
                         .indices(request.indices())
-                        .ignoreIndices(request.ignoreIndices())
+                        .indicesOptions(request.indicesOptions())
                         .renamePattern(request.renamePattern())
                         .renameReplacement(request.renameReplacement())
                         .includeGlobalState(request.includeGlobalState())

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/alias/exists/TransportAliasesExistAction.java

@@ -61,7 +61,7 @@ public class TransportAliasesExistAction extends TransportMasterNodeOperationAct
 
     @Override
     protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener<AliasesExistResponse> listener) throws ElasticSearchException {
-        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.indicesOptions());
         request.indices(concreteIndices);
 
         boolean result = state.metaData().hasAliases(request.aliases(), request.indices());

+ 7 - 0
src/main/java/org/elasticsearch/action/admin/indices/alias/get/BaseAliasesRequestBuilder.java

@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.alias.get;
 
 import com.google.common.collect.ObjectArrays;
 import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -57,4 +58,10 @@ public abstract class BaseAliasesRequestBuilder<Response extends ActionResponse,
         return (Builder) this;
     }
 
+    @SuppressWarnings("unchecked")
+    public Builder setIgnoreIndices(IndicesOptions options) {
+        request.indicesOptions(options);
+        return (Builder) this;
+    }
+
 }

+ 8 - 8
src/main/java/org/elasticsearch/action/admin/indices/alias/get/GetAliasesRequest.java

@@ -19,7 +19,7 @@
 package org.elasticsearch.action.admin.indices.alias.get;
 
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -36,7 +36,7 @@ public class GetAliasesRequest extends MasterNodeOperationRequest<GetAliasesRequ
     private String[] indices = Strings.EMPTY_ARRAY;
     private String[] aliases = Strings.EMPTY_ARRAY;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.NONE;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     public GetAliasesRequest(String[] aliases) {
         this.aliases = aliases;
@@ -59,8 +59,8 @@ public class GetAliasesRequest extends MasterNodeOperationRequest<GetAliasesRequ
         return this;
     }
 
-    public GetAliasesRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public GetAliasesRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -72,8 +72,8 @@ public class GetAliasesRequest extends MasterNodeOperationRequest<GetAliasesRequ
         return aliases;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     @Override
@@ -86,7 +86,7 @@ public class GetAliasesRequest extends MasterNodeOperationRequest<GetAliasesRequ
         super.readFrom(in);
         indices = in.readStringArray();
         aliases = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
@@ -94,6 +94,6 @@ public class GetAliasesRequest extends MasterNodeOperationRequest<GetAliasesRequ
         super.writeTo(out);
         out.writeStringArray(indices);
         out.writeStringArray(aliases);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/alias/get/TransportGetAliasesAction.java

@@ -64,7 +64,7 @@ public class TransportGetAliasesAction extends TransportMasterNodeOperationActio
 
     @Override
     protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener<GetAliasesResponse> listener) throws ElasticSearchException {
-        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.indicesOptions());
         request.indices(concreteIndices);
 
         @SuppressWarnings("unchecked") // ImmutableList to List results incompatible type

+ 16 - 12
src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequest.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.close;
 
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -35,7 +35,7 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
 public class CloseIndexRequest extends AcknowledgedRequest<CloseIndexRequest> {
 
     private String[] indices;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
 
     CloseIndexRequest() {
     }
@@ -75,20 +75,24 @@ public class CloseIndexRequest extends AcknowledgedRequest<CloseIndexRequest> {
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @return the desired behaviour regarding indices to ignore
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
+     *
+     * @return the desired behaviour regarding indices to ignore and wildcard indices expressions
      */
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * Specifies what type of requested indices to ignore and how to deal wild wildcard expressions.
+     * For example indices that don't exist.
+     *
+     * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions
      * @return the request itself
      */
-    public CloseIndexRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public CloseIndexRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -97,7 +101,7 @@ public class CloseIndexRequest extends AcknowledgedRequest<CloseIndexRequest> {
         super.readFrom(in);
         indices = in.readStringArray();
         readTimeout(in);
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
@@ -105,6 +109,6 @@ public class CloseIndexRequest extends AcknowledgedRequest<CloseIndexRequest> {
         super.writeTo(out);
         out.writeStringArray(indices);
         writeTimeout(out);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 7 - 5
src/main/java/org/elasticsearch/action/admin/indices/close/CloseIndexRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.close;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -49,12 +49,14 @@ public class CloseIndexRequestBuilder extends AcknowledgedRequestBuilder<CloseIn
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * Specifies what type of requested indices to ignore and wildcard indices expressions
+     * For example indices that don't exist.
+     *
+     * @param indicesOptions the desired behaviour regarding indices to ignore and indices wildcard expressions
      * @return the request itself
      */
-    public CloseIndexRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public CloseIndexRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java

@@ -77,7 +77,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeOperationActio
     protected void doExecute(CloseIndexRequest request, ActionListener<CloseIndexResponse> listener) {
         ClusterState state = clusterService.state();
         String[] indicesOrAliases = request.indices();
-        request.indices(state.metaData().concreteIndices(indicesOrAliases, request.ignoreIndices(), false));
+        request.indices(state.metaData().concreteIndices(indicesOrAliases, request.indicesOptions()));
 
         if (disableCloseAllIndices) {
             if (state.metaData().isExplicitAllIndices(indicesOrAliases) ||

+ 14 - 1
src/main/java/org/elasticsearch/action/admin/indices/delete/DeleteIndexRequest.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.delete;
 
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -37,7 +38,8 @@ import static org.elasticsearch.common.unit.TimeValue.readTimeValue;
 public class DeleteIndexRequest extends MasterNodeOperationRequest<DeleteIndexRequest> {
 
     private String[] indices;
-
+    // Delete index should work by default on both open and closed indices.
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, true, true, true);
     private TimeValue timeout = AcknowledgedRequest.DEFAULT_ACK_TIMEOUT;
 
     DeleteIndexRequest() {
@@ -54,6 +56,15 @@ public class DeleteIndexRequest extends MasterNodeOperationRequest<DeleteIndexRe
         this.indices = indices;
     }
 
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public DeleteIndexRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
+    }
+
     @Override
     public ActionRequestValidationException validate() {
         ActionRequestValidationException validationException = null;
@@ -107,6 +118,7 @@ public class DeleteIndexRequest extends MasterNodeOperationRequest<DeleteIndexRe
         for (int i = 0; i < indices.length; i++) {
             indices[i] = in.readString();
         }
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         timeout = readTimeValue(in);
     }
 
@@ -121,6 +133,7 @@ public class DeleteIndexRequest extends MasterNodeOperationRequest<DeleteIndexRe
                 out.writeString(index);
             }
         }
+        indicesOptions.writeIndicesOptions(out);
         timeout.writeTo(out);
     }
 }

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/delete/DeleteIndexRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.delete;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -52,6 +53,16 @@ public class DeleteIndexRequestBuilder extends MasterNodeOperationRequestBuilder
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public DeleteIndexRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     @Override
     protected void doExecute(ActionListener<DeleteIndexResponse> listener) {
         ((IndicesAdminClient) client).delete(request, listener);

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/delete/TransportDeleteIndexAction.java

@@ -81,7 +81,7 @@ public class TransportDeleteIndexAction extends TransportMasterNodeOperationActi
         ClusterState state = clusterService.state();
         String[] indicesOrAliases = request.indices();
 
-        request.indices(state.metaData().concreteIndices(request.indices()));
+        request.indices(state.metaData().concreteIndices(request.indices(), request.indicesOptions()));
 
         if (disableDeleteAllIndices) {
             if (state.metaData().isAllIndices(indicesOrAliases) ||

+ 15 - 1
src/main/java/org/elasticsearch/action/admin/indices/exists/indices/IndicesExistsRequest.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.exists.indices;
 
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -32,6 +33,7 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
 public class IndicesExistsRequest extends MasterNodeOperationRequest<IndicesExistsRequest> {
 
     private String[] indices = Strings.EMPTY_ARRAY;
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, true);
 
     public IndicesExistsRequest(String... indices) {
         this.indices = indices;
@@ -41,8 +43,18 @@ public class IndicesExistsRequest extends MasterNodeOperationRequest<IndicesExis
         return indices;
     }
 
-    public void indices(String[] indices) {
+    public IndicesExistsRequest indices(String[] indices) {
         this.indices = indices;
+        return this;
+    }
+
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public IndicesExistsRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
     }
 
     @Override
@@ -58,11 +70,13 @@ public class IndicesExistsRequest extends MasterNodeOperationRequest<IndicesExis
     public void readFrom(StreamInput in) throws IOException {
         super.readFrom(in);
         indices = in.readStringArray();
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
     public void writeTo(StreamOutput out) throws IOException {
         super.writeTo(out);
         out.writeStringArray(indices);
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/exists/indices/IndicesExistsRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.exists.indices;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -38,6 +39,16 @@ public class IndicesExistsRequestBuilder extends MasterNodeOperationRequestBuild
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public IndicesExistsRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     @Override
     protected void doExecute(ActionListener<IndicesExistsResponse> listener) {
         ((IndicesAdminClient) client).exists(request, listener);

+ 8 - 5
src/main/java/org/elasticsearch/action/admin/indices/exists/indices/TransportIndicesExistsAction.java

@@ -28,6 +28,7 @@ import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.indices.IndexMissingException;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.transport.TransportService;
 
@@ -77,11 +78,13 @@ public class TransportIndicesExistsAction extends TransportMasterNodeOperationAc
 
     @Override
     protected void masterOperation(final IndicesExistsRequest request, final ClusterState state, final ActionListener<IndicesExistsResponse> listener) throws ElasticSearchException {
-        boolean exists = true;
-        for (String index : request.indices()) {
-            if (!state.metaData().hasConcreteIndex(index)) {
-                exists = false;
-            }
+        boolean exists;
+        try {
+            // Similar as the previous behaviour, but now also aliases and wildcards are supported.
+            clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions());
+            exists = true;
+        } catch (IndexMissingException e) {
+            exists = false;
         }
         listener.onResponse(new IndicesExistsResponse(exists));
     }

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/exists/types/TransportTypesExistsAction.java

@@ -72,7 +72,7 @@ public class TransportTypesExistsAction extends TransportMasterNodeOperationActi
 
     @Override
     protected void masterOperation(final TypesExistsRequest request, final ClusterState state, final ActionListener<TypesExistsResponse> listener) throws ElasticSearchException {
-        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.ignoreIndices(), false);
+        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.indicesOptions());
         if (concreteIndices.length == 0) {
             listener.onResponse(new TypesExistsResponse(false));
             return;

+ 8 - 8
src/main/java/org/elasticsearch/action/admin/indices/exists/types/TypesExistsRequest.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.exists.types;
 
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -36,7 +36,7 @@ public class TypesExistsRequest extends MasterNodeOperationRequest<TypesExistsRe
     private String[] indices;
     private String[] types;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.NONE;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     TypesExistsRequest() {
     }
@@ -62,12 +62,12 @@ public class TypesExistsRequest extends MasterNodeOperationRequest<TypesExistsRe
         this.types = types;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public TypesExistsRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public TypesExistsRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -88,7 +88,7 @@ public class TypesExistsRequest extends MasterNodeOperationRequest<TypesExistsRe
         super.writeTo(out);
         out.writeStringArray(indices);
         out.writeStringArray(types);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 
     @Override
@@ -96,6 +96,6 @@ public class TypesExistsRequest extends MasterNodeOperationRequest<TypesExistsRe
         super.readFrom(in);
         indices = in.readStringArray();
         types = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 }

+ 4 - 4
src/main/java/org/elasticsearch/action/admin/indices/exists/types/TypesExistsRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.exists.types;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -59,10 +59,10 @@ public class TypesExistsRequestBuilder extends MasterNodeOperationRequestBuilder
     }
 
     /**
-     * @param ignoreIndices Specifies how to resolve indices that aren't active / ready
+     * @param indicesOptions Specifies how to resolve indices that aren't active / ready and indices wildcard expressions
      */
-    public TypesExistsRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public TypesExistsRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 13 - 1
src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/DeleteMappingRequest.java

@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.mapping.delete;
 
 import org.elasticsearch.Version;
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -35,7 +36,7 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
 public class DeleteMappingRequest extends AcknowledgedRequest<DeleteMappingRequest> {
 
     private String[] indices;
-
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
     private String type;
 
     DeleteMappingRequest() {
@@ -73,6 +74,15 @@ public class DeleteMappingRequest extends AcknowledgedRequest<DeleteMappingReque
         return indices;
     }
 
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public DeleteMappingRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
+    }
+
     /**
      * The mapping type.
      */
@@ -95,6 +105,7 @@ public class DeleteMappingRequest extends AcknowledgedRequest<DeleteMappingReque
         for (int i = 0; i < indices.length; i++) {
             indices[i] = in.readString();
         }
+        indicesOptions =  IndicesOptions.readIndicesOptions(in);
         if (in.readBoolean()) {
             type = in.readString();
         }
@@ -112,6 +123,7 @@ public class DeleteMappingRequest extends AcknowledgedRequest<DeleteMappingReque
                 out.writeString(index);
             }
         }
+        indicesOptions.writeIndicesOptions(out);
         if (type == null) {
             out.writeBoolean(false);
         } else {

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/DeleteMappingRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.mapping.delete;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -49,6 +50,16 @@ public class DeleteMappingRequestBuilder extends AcknowledgedRequestBuilder<Dele
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public DeleteMappingRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     @Override
     protected void doExecute(ActionListener<DeleteMappingResponse> listener) {
         ((IndicesAdminClient) client).deleteMapping(request, listener);

+ 1 - 2
src/main/java/org/elasticsearch/action/admin/indices/mapping/delete/TransportDeleteMappingAction.java

@@ -88,8 +88,7 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
 
     @Override
     protected void doExecute(DeleteMappingRequest request, ActionListener<DeleteMappingResponse> listener) {
-        // update to concrete indices
-        request.indices(clusterService.state().metaData().concreteIndices(request.indices()));
+        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
         super.doExecute(request, listener);
     }
 

+ 14 - 0
src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequest.java

@@ -23,6 +23,7 @@ import com.carrotsearch.hppc.ObjectOpenHashSet;
 import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -57,6 +58,8 @@ public class PutMappingRequest extends AcknowledgedRequest<PutMappingRequest> {
 
     private String[] indices;
 
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, true);
+
     private String type;
 
     private String source;
@@ -101,6 +104,15 @@ public class PutMappingRequest extends AcknowledgedRequest<PutMappingRequest> {
         return indices;
     }
 
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public PutMappingRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
+    }
+
     /**
      * The mapping type.
      */
@@ -243,6 +255,7 @@ public class PutMappingRequest extends AcknowledgedRequest<PutMappingRequest> {
     public void readFrom(StreamInput in) throws IOException {
         super.readFrom(in);
         indices = in.readStringArray();
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         type = in.readOptionalString();
         source = in.readString();
         readTimeout(in);
@@ -253,6 +266,7 @@ public class PutMappingRequest extends AcknowledgedRequest<PutMappingRequest> {
     public void writeTo(StreamOutput out) throws IOException {
         super.writeTo(out);
         out.writeStringArrayNullable(indices);
+        indicesOptions.writeIndicesOptions(out);
         out.writeOptionalString(type);
         out.writeString(source);
         writeTimeout(out);

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/mapping/put/PutMappingRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.mapping.put;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -41,6 +42,16 @@ public class PutMappingRequestBuilder extends AcknowledgedRequestBuilder<PutMapp
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public PutMappingRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     /**
      * The type of the mappings.
      */

+ 1 - 2
src/main/java/org/elasticsearch/action/admin/indices/mapping/put/TransportPutMappingAction.java

@@ -71,7 +71,7 @@ public class TransportPutMappingAction extends TransportMasterNodeOperationActio
 
     @Override
     protected void doExecute(PutMappingRequest request, ActionListener<PutMappingResponse> listener) {
-        request.indices(clusterService.state().metaData().concreteIndices(request.indices()));
+        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
         super.doExecute(request, listener);
     }
 
@@ -82,7 +82,6 @@ public class TransportPutMappingAction extends TransportMasterNodeOperationActio
 
     @Override
     protected void masterOperation(final PutMappingRequest request, final ClusterState state, final ActionListener<PutMappingResponse> listener) throws ElasticSearchException {
-
         PutMappingClusterStateUpdateRequest updateRequest = new PutMappingClusterStateUpdateRequest()
                 .ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
                 .indices(request.indices()).type(request.type())

+ 16 - 12
src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexRequest.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.open;
 
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -35,7 +35,7 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
 public class OpenIndexRequest extends AcknowledgedRequest<OpenIndexRequest> {
 
     private String[] indices;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, false, true);
 
     OpenIndexRequest() {
     }
@@ -75,20 +75,24 @@ public class OpenIndexRequest extends AcknowledgedRequest<OpenIndexRequest> {
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @return the current behaviour when it comes to index names
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
+     *
+     * @return the current behaviour when it comes to index names and wildcard indices expressions
      */
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * Specifies what type of requested indices to ignore and how to deal with wildcard expressions.
+     * For example indices that don't exist.
+     *
+     * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions
      * @return the request itself
      */
-    public OpenIndexRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public OpenIndexRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -97,7 +101,7 @@ public class OpenIndexRequest extends AcknowledgedRequest<OpenIndexRequest> {
         super.readFrom(in);
         indices = in.readStringArray();
         readTimeout(in);
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
@@ -105,6 +109,6 @@ public class OpenIndexRequest extends AcknowledgedRequest<OpenIndexRequest> {
         super.writeTo(out);
         out.writeStringArray(indices);
         writeTimeout(out);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 7 - 5
src/main/java/org/elasticsearch/action/admin/indices/open/OpenIndexRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.admin.indices.open;
 
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -49,12 +49,14 @@ public class OpenIndexRequestBuilder extends AcknowledgedRequestBuilder<OpenInde
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
-     * @param ignoreIndices the desired behaviour regarding indices to ignore
+     * Specifies what type of requested indices to ignore and how to deal with wildcard indices expressions.
+     * For example indices that don't exist.
+     *
+     * @param indicesOptions the desired behaviour regarding indices to ignore and wildcard indices expressions
      * @return the request itself
      */
-    public OpenIndexRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public OpenIndexRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/open/TransportOpenIndexAction.java

@@ -71,7 +71,7 @@ public class TransportOpenIndexAction extends TransportMasterNodeOperationAction
 
     @Override
     protected void doExecute(OpenIndexRequest request, ActionListener<OpenIndexResponse> listener) {
-        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.ignoreIndices(), false));
+        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
         super.doExecute(request, listener);
     }
 

+ 2 - 0
src/main/java/org/elasticsearch/action/admin/indices/segments/IndicesSegmentsRequest.java

@@ -19,6 +19,7 @@
 
 package org.elasticsearch.action.admin.indices.segments;
 
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
 import org.elasticsearch.common.Strings;
 
@@ -30,5 +31,6 @@ public class IndicesSegmentsRequest extends BroadcastOperationRequest<IndicesSeg
 
     public IndicesSegmentsRequest(String... indices) {
         super(indices);
+        indicesOptions(IndicesOptions.fromOptions(false, false, true, false));
     }
 }

+ 6 - 1
src/main/java/org/elasticsearch/action/admin/indices/settings/TransportUpdateSettingsAction.java

@@ -68,8 +68,13 @@ public class TransportUpdateSettingsAction extends TransportMasterNodeOperationA
     }
 
     @Override
-    protected void masterOperation(final UpdateSettingsRequest request, final ClusterState state, final ActionListener<UpdateSettingsResponse> listener) throws ElasticSearchException {
+    protected void doExecute(UpdateSettingsRequest request, ActionListener<UpdateSettingsResponse> listener) {
+        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
+        super.doExecute(request, listener);
+    }
 
+    @Override
+    protected void masterOperation(final UpdateSettingsRequest request, final ClusterState state, final ActionListener<UpdateSettingsResponse> listener) throws ElasticSearchException {
         UpdateSettingsClusterStateUpdateRequest clusterStateUpdateRequest = new UpdateSettingsClusterStateUpdateRequest()
                 .indices(request.indices())
                 .settings(request.settings())

+ 13 - 1
src/main/java/org/elasticsearch/action/admin/indices/settings/UpdateSettingsRequest.java

@@ -22,6 +22,7 @@ package org.elasticsearch.action.admin.indices.settings;
 import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -45,7 +46,7 @@ import static org.elasticsearch.common.settings.ImmutableSettings.writeSettingsT
 public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsRequest> {
 
     private String[] indices;
-
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, true);
     private Settings settings = EMPTY_SETTINGS;
 
     UpdateSettingsRequest() {
@@ -91,6 +92,15 @@ public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsReq
         return this;
     }
 
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public UpdateSettingsRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
+    }
+
     /**
      * Sets the settings to be updated
      */
@@ -134,6 +144,7 @@ public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsReq
     public void readFrom(StreamInput in) throws IOException {
         super.readFrom(in);
         indices = in.readStringArray();
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         settings = readSettingsFromStream(in);
         readTimeout(in, Version.V_0_90_6);
     }
@@ -142,6 +153,7 @@ public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsReq
     public void writeTo(StreamOutput out) throws IOException {
         super.writeTo(out);
         out.writeStringArrayNullable(indices);
+        indicesOptions.writeIndicesOptions(out);
         writeSettingsToStream(settings, out);
         writeTimeout(out, Version.V_0_90_6);
     }

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/settings/UpdateSettingsRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.settings;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -44,6 +45,16 @@ public class UpdateSettingsRequestBuilder extends AcknowledgedRequestBuilder<Upd
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public UpdateSettingsRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     /**
      * Sets the settings to be updated
      */

+ 3 - 0
src/main/java/org/elasticsearch/action/admin/indices/validate/query/ValidateQueryRequest.java

@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.validate.query;
 
 import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.QuerySourceBuilder;
 import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
 import org.elasticsearch.client.Requests;
@@ -58,6 +59,7 @@ public class ValidateQueryRequest extends BroadcastOperationRequest<ValidateQuer
     long nowInMillis;
 
     ValidateQueryRequest() {
+        this(Strings.EMPTY_ARRAY);
     }
 
     /**
@@ -66,6 +68,7 @@ public class ValidateQueryRequest extends BroadcastOperationRequest<ValidateQuer
      */
     public ValidateQueryRequest(String... indices) {
         super(indices);
+        indicesOptions(IndicesOptions.fromOptions(false, false, true, false));
     }
 
     @Override

+ 13 - 1
src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/DeleteWarmerRequest.java

@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.warmer.delete;
 
 import org.elasticsearch.Version;
 import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequest;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.Strings;
@@ -35,7 +36,7 @@ import java.io.IOException;
 public class DeleteWarmerRequest extends AcknowledgedRequest<DeleteWarmerRequest> {
 
     private String name;
-
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
     private String[] indices = Strings.EMPTY_ARRAY;
 
     DeleteWarmerRequest() {
@@ -87,11 +88,21 @@ public class DeleteWarmerRequest extends AcknowledgedRequest<DeleteWarmerRequest
         return indices;
     }
 
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
+    }
+
+    public DeleteWarmerRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
+        return this;
+    }
+
     @Override
     public void readFrom(StreamInput in) throws IOException {
         super.readFrom(in);
         name = in.readOptionalString();
         indices = in.readStringArray();
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         readTimeout(in, Version.V_0_90_6);
     }
 
@@ -100,6 +111,7 @@ public class DeleteWarmerRequest extends AcknowledgedRequest<DeleteWarmerRequest
         super.writeTo(out);
         out.writeOptionalString(name);
         out.writeStringArrayNullable(indices);
+        indicesOptions.writeIndicesOptions(out);
         writeTimeout(out, Version.V_0_90_6);
     }
 }

+ 11 - 0
src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/DeleteWarmerRequestBuilder.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.action.admin.indices.warmer.delete;
 
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
 import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.client.internal.InternalIndicesAdminClient;
@@ -47,6 +48,16 @@ public class DeleteWarmerRequestBuilder extends AcknowledgedRequestBuilder<Delet
         return this;
     }
 
+    /**
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
+     */
+    public DeleteWarmerRequestBuilder setIndicesOptions(IndicesOptions options) {
+        request.indicesOptions(options);
+        return this;
+    }
+
     @Override
     protected void doExecute(ActionListener<DeleteWarmerResponse> listener) {
         ((IndicesAdminClient) client).deleteWarmer(request, listener);

+ 1 - 1
src/main/java/org/elasticsearch/action/admin/indices/warmer/delete/TransportDeleteWarmerAction.java

@@ -79,7 +79,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
     @Override
     protected void doExecute(DeleteWarmerRequest request, ActionListener<DeleteWarmerResponse> listener) {
         // update to concrete indices
-        request.indices(clusterService.state().metaData().concreteIndices(request.indices()));
+        request.indices(clusterService.state().metaData().concreteIndices(request.indices(), request.indicesOptions()));
         super.doExecute(request, listener);
     }
 

+ 2 - 2
src/main/java/org/elasticsearch/action/admin/indices/warmer/put/TransportPutWarmerAction.java

@@ -83,7 +83,7 @@ public class TransportPutWarmerAction extends TransportMasterNodeOperationAction
 
     @Override
     protected ClusterBlockException checkBlock(PutWarmerRequest request, ClusterState state) {
-        String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.searchRequest().indices());
+        String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.searchRequest().indices(), request.searchRequest().indicesOptions());
         return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
     }
 
@@ -134,7 +134,7 @@ public class TransportPutWarmerAction extends TransportMasterNodeOperationAction
                     @Override
                     public ClusterState execute(ClusterState currentState) {
                         MetaData metaData = currentState.metaData();
-                        String[] concreteIndices = metaData.concreteIndices(request.searchRequest().indices());
+                        String[] concreteIndices = metaData.concreteIndices(request.searchRequest().indices(), request.searchRequest().indicesOptions());
 
                         BytesReference source = null;
                         if (request.searchRequest().source() != null && request.searchRequest().source().length() > 0) {

+ 61 - 16
src/main/java/org/elasticsearch/action/percolate/MultiPercolateRequest.java

@@ -19,11 +19,12 @@
 package org.elasticsearch.action.percolate;
 
 import com.google.common.collect.Lists;
+import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.ElasticSearchParseException;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
 import org.elasticsearch.action.get.GetRequest;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
@@ -47,7 +48,7 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
 
     private String[] indices;
     private String documentType;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
     private List<PercolateRequest> requests = Lists.newArrayList();
 
     public MultiPercolateRequest add(PercolateRequestBuilder requestBuilder) {
@@ -61,8 +62,8 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
         if (request.documentType() == null && documentType != null) {
             request.documentType(documentType);
         }
-        if (request.ignoreIndices() == IgnoreIndices.DEFAULT && ignoreIndices != IgnoreIndices.DEFAULT) {
-            request.ignoreIndices(ignoreIndices);
+        if (request.indicesOptions() == IndicesOptions.strict() && indicesOptions != IndicesOptions.strict()) {
+            request.indicesOptions(indicesOptions);
         }
         requests.add(request);
         return this;
@@ -95,8 +96,8 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
             if (documentType != null) {
                 percolateRequest.documentType(documentType);
             }
-            if (ignoreIndices != IgnoreIndices.DEFAULT) {
-                percolateRequest.ignoreIndices(ignoreIndices);
+            if (indicesOptions != IndicesOptions.strict()) {
+                percolateRequest.indicesOptions(indicesOptions);
             }
 
             // now parse the action
@@ -167,6 +168,11 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
             }
         }
 
+        boolean ignoreUnavailable = IndicesOptions.strict().ignoreUnavailable();
+        boolean allowNoIndices = IndicesOptions.strict().allowNoIndices();
+        boolean expandWildcardsOpen = IndicesOptions.strict().expandWildcardsOpen();
+        boolean expandWildcardsClosed = IndicesOptions.strict().expandWildcardsClosed();
+
         if (header.containsKey("id")) {
             GetRequest getRequest = new GetRequest(globalIndex);
             percolateRequest.getRequest(getRequest);
@@ -195,8 +201,27 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
                     percolateRequest.preference((String) value);
                 } else if ("percolate_routing".equals(entry.getKey()) || "percolateRouting".equals(entry.getKey())) {
                     percolateRequest.routing((String) value);
-                } else if ("ignore_indices".equals(entry.getKey()) || "ignoreIndices".equals(entry.getKey())) {
-                    percolateRequest.ignoreIndices(IgnoreIndices.fromString((String) value));
+                } else if ("ignore_unavailable".equals(currentFieldName) || "ignoreUnavailable".equals(currentFieldName)) {
+                    ignoreUnavailable = Boolean.valueOf((String) value);
+                } else if ("allow_no_indices".equals(currentFieldName) || "allowNoIndices".equals(currentFieldName)) {
+                    allowNoIndices = Boolean.valueOf((String) value);
+                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
+                    String[] wildcards;
+                    if (value instanceof String[]) {
+                        wildcards = (String[]) value;
+                    } else {
+                        wildcards = Strings.splitStringByCommaToArray((String) value);
+                    }
+
+                    for (String wildcard : wildcards) {
+                        if ("open".equals(wildcard)) {
+                            expandWildcardsOpen = true;
+                        } else if ("closed".equals(wildcard)) {
+                            expandWildcardsClosed = true;
+                        } else {
+                            throw new ElasticSearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
+                        }
+                    }
                 }
             }
 
@@ -228,11 +253,31 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
                     percolateRequest.preference((String) value);
                 } else if ("routing".equals(entry.getKey())) {
                     percolateRequest.routing((String) value);
-                } else if ("ignore_indices".equals(entry.getKey()) || "ignoreIndices".equals(entry.getKey())) {
-                    percolateRequest.ignoreIndices(IgnoreIndices.fromString((String) value));
+                } else if ("ignore_unavailable".equals(currentFieldName) || "ignoreUnavailable".equals(currentFieldName)) {
+                    ignoreUnavailable = Boolean.valueOf((String) value);
+                } else if ("allow_no_indices".equals(currentFieldName) || "allowNoIndices".equals(currentFieldName)) {
+                    allowNoIndices = Boolean.valueOf((String) value);
+                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
+                    String[] wildcards;
+                    if (value instanceof String[]) {
+                        wildcards = (String[]) value;
+                    } else {
+                        wildcards = Strings.splitStringByCommaToArray((String) value);
+                    }
+
+                    for (String wildcard : wildcards) {
+                        if ("open".equals(wildcard)) {
+                            expandWildcardsOpen = true;
+                        } else if ("closed".equals(wildcard)) {
+                            expandWildcardsClosed = true;
+                        } else {
+                            throw new ElasticSearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
+                        }
+                    }
                 }
             }
         }
+        percolateRequest.indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
     }
 
     private String[] parseArray(XContentParser parser) throws IOException {
@@ -257,12 +302,12 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
         return this.requests;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public MultiPercolateRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public MultiPercolateRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -308,7 +353,7 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
         super.readFrom(in);
         indices = in.readStringArray();
         documentType = in.readOptionalString();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         int size = in.readVInt();
         for (int i = 0; i < size; i++) {
             PercolateRequest request = new PercolateRequest();
@@ -322,7 +367,7 @@ public class MultiPercolateRequest extends ActionRequest<MultiPercolateRequest>
         super.writeTo(out);
         out.writeStringArrayNullable(indices);
         out.writeOptionalString(documentType);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
         out.writeVInt(requests.size());
         for (PercolateRequest request : requests) {
             request.writeTo(out);

+ 6 - 4
src/main/java/org/elasticsearch/action/percolate/MultiPercolateRequestBuilder.java

@@ -20,7 +20,7 @@ package org.elasticsearch.action.percolate;
 
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionRequestBuilder;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.internal.InternalClient;
 
@@ -49,10 +49,12 @@ public class MultiPercolateRequestBuilder extends ActionRequestBuilder<MultiPerc
     }
 
     /**
-     * Specifies how to globally ignore indices that are not available.
+     * Specifies how to globally ignore indices that are not available and how to deal with wildcard indices expressions.
+     *
+     * Invoke this method before invoking {@link #add(PercolateRequestBuilder)}.
      */
-    public MultiPercolateRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public MultiPercolateRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return this;
     }
 

+ 0 - 3
src/main/java/org/elasticsearch/action/percolate/PercolateRequest.java

@@ -188,9 +188,6 @@ public class PercolateRequest extends BroadcastOperationRequest<PercolateRequest
     @Override
     public ActionRequestValidationException validate() {
         ActionRequestValidationException validationException = super.validate();
-        if (indices == null || indices.length == 0) {
-            validationException = addValidationError("index is missing", validationException);
-        }
         if (documentType == null) {
             validationException = addValidationError("type is missing", validationException);
         }

+ 9 - 2
src/main/java/org/elasticsearch/action/percolate/TransportMultiPercolateAction.java

@@ -22,6 +22,7 @@ package org.elasticsearch.action.percolate;
 import com.carrotsearch.hppc.IntArrayList;
 import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.UnavailableShardsException;
 import org.elasticsearch.action.get.*;
 import org.elasticsearch.action.support.TransportAction;
 import org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException;
@@ -162,12 +163,18 @@ public class TransportMultiPercolateAction extends TransportAction<MultiPercolat
                 assert element != null;
                 if (element instanceof PercolateRequest) {
                     PercolateRequest percolateRequest = (PercolateRequest) element;
-                    String[] concreteIndices = clusterState.metaData().concreteIndices(percolateRequest.indices(), percolateRequest.ignoreIndices(), true);
+                    String[] concreteIndices = clusterState.metaData().concreteIndices(percolateRequest.indices(), percolateRequest.indicesOptions());
                     Map<String, Set<String>> routing = clusterState.metaData().resolveSearchRouting(percolateRequest.routing(), percolateRequest.indices());
                     // TODO: I only need shardIds, ShardIterator(ShardRouting) is only needed in TransportShardMultiPercolateAction
                     GroupShardsIterator shards = clusterService.operationRouting().searchShards(
-                            clusterState, percolateRequest.indices(), concreteIndices, routing, null
+                            clusterState, percolateRequest.indices(), concreteIndices, routing, percolateRequest.preference()
                     );
+                    if (shards.size() == 0) {
+                        reducedResponses.set(slot, new UnavailableShardsException(null, "No shards available"));
+                        responsesByItemAndShard.set(slot, new AtomicReferenceArray(0));
+                        expectedOperationsPerItem.set(slot, new AtomicInteger(0));
+                        continue;
+                    }
 
                     responsesByItemAndShard.set(slot, new AtomicReferenceArray(shards.size()));
                     expectedOperationsPerItem.set(slot, new AtomicInteger(shards.size()));

+ 44 - 14
src/main/java/org/elasticsearch/action/search/MultiSearchRequest.java

@@ -24,7 +24,7 @@ import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.ElasticSearchParseException;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesArray;
@@ -48,7 +48,7 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
 
     private List<SearchRequest> requests = Lists.newArrayList();
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     /**
      * Add a search request to execute. Note, the order is important, the search response will be returned in the
@@ -70,14 +70,14 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
 
     public MultiSearchRequest add(byte[] data, int from, int length, boolean contentUnsafe,
                                   @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType) throws Exception {
-        return add(new BytesArray(data, from, length), contentUnsafe, indices, types, searchType, null, IgnoreIndices.NONE, true);
+        return add(new BytesArray(data, from, length), contentUnsafe, indices, types, searchType, null, IndicesOptions.strict(), true);
     }
 
-    public MultiSearchRequest add(BytesReference data, boolean contentUnsafe, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, IgnoreIndices ignoreIndices) throws Exception {
-        return add(data, contentUnsafe, indices, types, searchType, null, ignoreIndices, true);
+    public MultiSearchRequest add(BytesReference data, boolean contentUnsafe, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, IndicesOptions indicesOptions) throws Exception {
+        return add(data, contentUnsafe, indices, types, searchType, null, indicesOptions, true);
     }
 
-    public MultiSearchRequest add(BytesReference data, boolean contentUnsafe, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, @Nullable String routing, IgnoreIndices ignoreIndices, boolean allowExplicitIndex) throws Exception {
+    public MultiSearchRequest add(BytesReference data, boolean contentUnsafe, @Nullable String[] indices, @Nullable String[] types, @Nullable String searchType, @Nullable String routing, IndicesOptions indicesOptions, boolean allowExplicitIndex) throws Exception {
         XContent xContent = XContentFactory.xContent(data);
         int from = 0;
         int length = data.length();
@@ -97,8 +97,8 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
             if (indices != null) {
                 searchRequest.indices(indices);
             }
-            if (ignoreIndices != null) {
-                searchRequest.ignoreIndices(ignoreIndices);
+            if (indicesOptions != null) {
+                searchRequest.indicesOptions(indicesOptions);
             }
             if (types != null && types.length > 0) {
                 searchRequest.types(types);
@@ -108,6 +108,11 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
             }
             searchRequest.searchType(searchType);
 
+            boolean ignoreUnavailable = IndicesOptions.strict().ignoreUnavailable();
+            boolean allowNoIndices = IndicesOptions.strict().allowNoIndices();
+            boolean expandWildcardsOpen = IndicesOptions.strict().expandWildcardsOpen();
+            boolean expandWildcardsClosed = IndicesOptions.strict().expandWildcardsClosed();
+
             // now parse the action
             if (nextMarker - from > 0) {
                 XContentParser parser = xContent.createParser(data.slice(from, nextMarker - from));
@@ -134,8 +139,21 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
                                     searchRequest.preference(parser.text());
                                 } else if ("routing".equals(currentFieldName)) {
                                     searchRequest.routing(parser.text());
-                                } else if ("ignore_indices".equals(currentFieldName) || "ignoreIndices".equals(currentFieldName)) {
-                                    searchRequest.ignoreIndices(IgnoreIndices.fromString(parser.text()));
+                                } else if ("ignore_unavailable".equals(currentFieldName) || "ignoreUnavailable".equals(currentFieldName)) {
+                                    ignoreUnavailable = parser.booleanValue();
+                                } else if ("allow_no_indices".equals(currentFieldName) || "allowNoIndices".equals(currentFieldName)) {
+                                    allowNoIndices = parser.booleanValue();
+                                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
+                                    String[] wildcards = Strings.splitStringByCommaToArray(parser.text());
+                                    for (String wildcard : wildcards) {
+                                        if ("open".equals(wildcard)) {
+                                            expandWildcardsOpen = true;
+                                        } else if ("closed".equals(wildcard)) {
+                                            expandWildcardsClosed = true;
+                                        } else {
+                                            throw new ElasticSearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
+                                        }
+                                    }
                                 }
                             } else if (token == XContentParser.Token.START_ARRAY) {
                                 if ("index".equals(currentFieldName) || "indices".equals(currentFieldName)) {
@@ -145,6 +163,17 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
                                     searchRequest.indices(parseArray(parser));
                                 } else if ("type".equals(currentFieldName) || "types".equals(currentFieldName)) {
                                     searchRequest.types(parseArray(parser));
+                                } else if ("expand_wildcards".equals(currentFieldName) || "expandWildcards".equals(currentFieldName)) {
+                                    String[] wildcards = parseArray(parser);
+                                    for (String wildcard : wildcards) {
+                                        if ("open".equals(wildcard)) {
+                                            expandWildcardsOpen = true;
+                                        } else if ("closed".equals(wildcard)) {
+                                            expandWildcardsClosed = true;
+                                        } else {
+                                            throw new ElasticSearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
+                                        }
+                                    }
                                 } else {
                                     throw new ElasticSearchParseException(currentFieldName + " doesn't support arrays");
                                 }
@@ -155,6 +184,7 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
                     parser.close();
                 }
             }
+            searchRequest.indicesOptions(IndicesOptions.fromOptions(ignoreUnavailable, allowNoIndices, expandWildcardsOpen, expandWildcardsClosed));
 
             // move pointers
             from = nextMarker + 1;
@@ -215,12 +245,12 @@ public class MultiSearchRequest extends ActionRequest<MultiSearchRequest> {
         return validationException;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public MultiSearchRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public MultiSearchRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 

+ 11 - 9
src/main/java/org/elasticsearch/action/search/MultiSearchRequestBuilder.java

@@ -21,7 +21,7 @@ package org.elasticsearch.action.search;
 
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionRequestBuilder;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.internal.InternalClient;
 
@@ -38,12 +38,12 @@ public class MultiSearchRequestBuilder extends ActionRequestBuilder<MultiSearchR
      * Add a search request to execute. Note, the order is important, the search response will be returned in the
      * same order as the search requests.
      * <p/>
-     * If ignoreIndices has been set on the search request, then the ignoreIndices of the multi search request
+     * If ignoreIndices has been set on the search request, then the indicesOptions of the multi search request
      * will not be used (if set).
      */
     public MultiSearchRequestBuilder add(SearchRequest request) {
-        if (request.ignoreIndices() == IgnoreIndices.DEFAULT && request().ignoreIndices() != IgnoreIndices.DEFAULT) {
-            request.ignoreIndices(request().ignoreIndices());
+        if (request.indicesOptions() == IndicesOptions.strict() && request().indicesOptions() != IndicesOptions.strict()) {
+            request.indicesOptions(request().indicesOptions());
         }
 
         super.request.add(request);
@@ -55,8 +55,8 @@ public class MultiSearchRequestBuilder extends ActionRequestBuilder<MultiSearchR
      * same order as the search requests.
      */
     public MultiSearchRequestBuilder add(SearchRequestBuilder request) {
-        if (request.request().ignoreIndices() == IgnoreIndices.DEFAULT && request().ignoreIndices() != IgnoreIndices.DEFAULT) {
-            request.request().ignoreIndices(request().ignoreIndices());
+        if (request.request().indicesOptions() == IndicesOptions.strict() && request().indicesOptions() != IndicesOptions.strict()) {
+            request.request().indicesOptions(request().indicesOptions());
         }
 
         super.request.add(request);
@@ -64,11 +64,13 @@ public class MultiSearchRequestBuilder extends ActionRequestBuilder<MultiSearchR
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal with wildcard indices expressions.
+     * For example indices that don't exist.
+     *
      * Invoke this method before invoking {@link #add(SearchRequestBuilder)}.
      */
-    public MultiSearchRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request().ignoreIndices(ignoreIndices);
+    public MultiSearchRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request().indicesOptions(indicesOptions);
         return this;
     }
 

+ 8 - 8
src/main/java/org/elasticsearch/action/search/SearchRequest.java

@@ -23,7 +23,7 @@ import org.elasticsearch.ElasticSearchGenerationException;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Requests;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.Strings;
@@ -81,7 +81,7 @@ public class SearchRequest extends ActionRequest<SearchRequest> {
 
     private SearchOperationThreading operationThreading = SearchOperationThreading.THREAD_PER_SHARD;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     public SearchRequest() {
     }
@@ -171,12 +171,12 @@ public class SearchRequest extends ActionRequest<SearchRequest> {
         return operationThreading(SearchOperationThreading.fromString(operationThreading, this.operationThreading));
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public SearchRequest ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public SearchRequest indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return this;
     }
 
@@ -470,7 +470,7 @@ public class SearchRequest extends ActionRequest<SearchRequest> {
         extraSource = in.readBytesReference();
 
         types = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
@@ -496,6 +496,6 @@ public class SearchRequest extends ActionRequest<SearchRequest> {
         out.writeBytesReference(source);
         out.writeBytesReference(extraSource);
         out.writeStringArray(types);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 6 - 4
src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java

@@ -22,7 +22,7 @@ package org.elasticsearch.action.search;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionRequestBuilder;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.internal.InternalClient;
 import org.elasticsearch.common.Nullable;
@@ -173,10 +173,12 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and wildcard indices expressions.
+     *
+     * For example indices that don't exist.
      */
-    public SearchRequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request().ignoreIndices(ignoreIndices);
+    public SearchRequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request().indicesOptions(indicesOptions);
         return this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/search/TransportSearchAction.java

@@ -87,7 +87,7 @@ public class TransportSearchAction extends TransportAction<SearchRequest, Search
         if (optimizeSingleShard && searchRequest.searchType() != SCAN && searchRequest.searchType() != COUNT) {
             try {
                 ClusterState clusterState = clusterService.state();
-                String[] concreteIndices = clusterState.metaData().concreteIndices(searchRequest.indices(), searchRequest.ignoreIndices(), true);
+                String[] concreteIndices = clusterState.metaData().concreteIndices(searchRequest.indices(), searchRequest.indicesOptions());
                 Map<String, Set<String>> routingMap = clusterState.metaData().resolveSearchRouting(searchRequest.routing(), searchRequest.indices());
                 int shardCount = clusterService.operationRouting().searchShardsCount(clusterState, searchRequest.indices(), concreteIndices, routingMap, searchRequest.preference());
                 if (shardCount == 1) {

+ 1 - 1
src/main/java/org/elasticsearch/action/search/type/TransportSearchTypeAction.java

@@ -106,7 +106,7 @@ public abstract class TransportSearchTypeAction extends TransportAction<SearchRe
 
             clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
 
-            String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+            String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.indicesOptions());
 
             for (String index : concreteIndices) {
                 clusterState.blocks().indexBlockedRaiseException(ClusterBlockLevel.READ, index);

+ 0 - 65
src/main/java/org/elasticsearch/action/support/IgnoreIndices.java

@@ -1,65 +0,0 @@
-/*
- * Licensed to ElasticSearch and Shay Banon 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.support;
-
-import org.elasticsearch.ElasticSearchIllegalArgumentException;
-
-/**
- * Specifies what type of requested indices to exclude.
- */
-public enum IgnoreIndices {
-
-    DEFAULT((byte) 0),
-    NONE((byte) 1),
-    MISSING((byte) 2);
-
-    private final byte id;
-
-    private IgnoreIndices(byte id) {
-        this.id = id;
-    }
-
-    public byte id() {
-        return id;
-    }
-
-    public static IgnoreIndices fromId(byte id) {
-        if (id == 0) {
-            return DEFAULT;
-        } else if (id == 1) {
-            return NONE;
-        } else if(id == 2) {
-            return MISSING;
-        } else {
-            throw new ElasticSearchIllegalArgumentException("No valid missing index type id: " + id);
-        }
-    }
-
-    public static IgnoreIndices fromString(String type) {
-        if ("none".equals(type)) {
-            return NONE;
-        } else if ("missing".equals(type)) {
-            return MISSING;
-        } else {
-            throw new ElasticSearchIllegalArgumentException("No valid missing index type: " + type);
-        }
-    }
-
-}

+ 169 - 0
src/main/java/org/elasticsearch/action/support/IndicesOptions.java

@@ -0,0 +1,169 @@
+/*
+ * Licensed to ElasticSearch and Shay Banon 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.support;
+
+import org.elasticsearch.ElasticSearchIllegalArgumentException;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.rest.RestRequest;
+
+import java.io.IOException;
+
+/**
+ * Controls how to deal when concrete indices are unavailable (closed & missing), to what wildcard expression expand
+ * (all, closed or open indices) and how to deal when a wildcard expression resolves into no concrete indices.
+ */
+public class IndicesOptions {
+
+    private static final IndicesOptions[] VALUES;
+
+    static {
+        byte max = 1 << 4;
+        VALUES = new IndicesOptions[max];
+        for (byte id = 0; id < max; id++) {
+            VALUES[id] = new IndicesOptions(id);
+        }
+    }
+
+    private final byte id;
+
+    private IndicesOptions(byte id) {
+        this.id = id;
+    }
+
+    /**
+     * @return Whether specified concrete indices should be ignored when unavailable (missing or closed)
+     */
+    public boolean ignoreUnavailable() {
+        return (id & 1) != 0;
+    }
+
+    /**
+     * @return Whether to ignore if a wildcard indices expression resolves into no concrete indices.
+     *         The `_all` string or when no indices have been specified also count as wildcard expressions.
+     */
+    public boolean allowNoIndices() {
+        return (id & 2) != 0;
+    }
+
+    /**
+     * @return Whether wildcard indices expressions should expanded into open indices should be
+     */
+    public boolean expandWildcardsOpen() {
+        return (id & 4) != 0;
+    }
+
+    /**
+     * @return Whether wildcard indices expressions should expanded into closed indices should be
+     */
+    public boolean expandWildcardsClosed() {
+        return (id & 8) != 0;
+    }
+
+    public void writeIndicesOptions(StreamOutput out) throws IOException {
+        out.write(id);
+    }
+
+    public static IndicesOptions readIndicesOptions(StreamInput in) throws IOException {
+        byte id = in.readByte();
+        if (id >= VALUES.length) {
+            throw new ElasticSearchIllegalArgumentException("No valid missing index type id: " + id);
+        }
+        return VALUES[id];
+    }
+
+    public static IndicesOptions fromOptions(boolean ignoreUnavailable, boolean allowNoIndices, boolean expandToOpenIndices, boolean expandToClosedIndices) {
+        byte id = toByte(ignoreUnavailable, allowNoIndices, expandToOpenIndices, expandToClosedIndices);
+        return VALUES[id];
+    }
+
+    public static IndicesOptions fromRequest(RestRequest request, IndicesOptions defaultSettings) {
+        String sWildcards = request.param("expand_wildcards");
+        String sIgnoreUnavailable = request.param("ignore_unavailable");
+        String sAllowNoIndices = request.param("allow_no_indices");
+        if (sWildcards == null && sIgnoreUnavailable == null && sAllowNoIndices == null) {
+            return defaultSettings;
+        }
+
+        boolean expandWildcardsOpen = defaultSettings.expandWildcardsOpen();
+        boolean expandWildcardsClosed = defaultSettings.expandWildcardsClosed();
+        if (sWildcards != null) {
+            String[] wildcards = Strings.splitStringByCommaToArray(sWildcards);
+            for (String wildcard : wildcards) {
+                if ("open".equals(wildcard)) {
+                    expandWildcardsOpen = true;
+                } else if ("closed".equals(wildcard)) {
+                    expandWildcardsClosed = true;
+                } else {
+                    throw new ElasticSearchIllegalArgumentException("No valid expand wildcard value [" + wildcard + "]");
+                }
+            }
+        }
+
+        return fromOptions(
+                toBool(sIgnoreUnavailable, defaultSettings.ignoreUnavailable()),
+                toBool(sAllowNoIndices, defaultSettings.allowNoIndices()),
+                expandWildcardsOpen,
+                expandWildcardsClosed
+        );
+    }
+
+    /**
+     * @return indices options that requires any specified index to exists, expands wildcards only to open indices and
+     *         allow that no indices are resolved from wildcard expressions (not returning an error).
+     */
+    public static IndicesOptions strict() {
+        return VALUES[6];
+    }
+
+    /**
+     * @return indices options that ignore unavailable indices, expand wildcards only to open indices and
+     *         allow that no indices are resolved from wildcard expressions (not returning an error).
+     */
+    public static IndicesOptions lenient() {
+        return VALUES[7];
+    }
+
+    private static byte toByte(boolean ignoreUnavailable, boolean allowNoIndices, boolean wildcardExpandToOpen, boolean wildcardExpandToClosed) {
+        byte id = 0;
+        if (ignoreUnavailable) {
+            id |= 1;
+        }
+        if (allowNoIndices) {
+            id |= 2;
+        }
+        if (wildcardExpandToOpen) {
+            id |= 4;
+        }
+        if (wildcardExpandToClosed) {
+            id |= 8;
+        }
+        return id;
+    }
+
+    private static boolean toBool(String sValue, boolean defaultValue) {
+        if (sValue == null) {
+            return defaultValue;
+        }
+        return !(sValue.equals("false") || sValue.equals("0") || sValue.equals("off"));
+    }
+
+}

+ 8 - 8
src/main/java/org/elasticsearch/action/support/broadcast/BroadcastOperationRequest.java

@@ -21,7 +21,7 @@ package org.elasticsearch.action.support.broadcast;
 
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 
@@ -35,7 +35,7 @@ public abstract class BroadcastOperationRequest<T extends BroadcastOperationRequ
     protected String[] indices;
 
     private BroadcastOperationThreading operationThreading = BroadcastOperationThreading.THREAD_PER_SHARD;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.NONE;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
 
     protected BroadcastOperationRequest() {
 
@@ -83,13 +83,13 @@ public abstract class BroadcastOperationRequest<T extends BroadcastOperationRequ
         return operationThreading(BroadcastOperationThreading.fromString(operationThreading, this.operationThreading));
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     @SuppressWarnings("unchecked")
-    public final T ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public final T indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return (T) this;
     }
 
@@ -106,7 +106,7 @@ public abstract class BroadcastOperationRequest<T extends BroadcastOperationRequ
         super.writeTo(out);
         out.writeStringArrayNullable(indices);
         out.writeByte(operationThreading.id());
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 
     @Override
@@ -114,6 +114,6 @@ public abstract class BroadcastOperationRequest<T extends BroadcastOperationRequ
         super.readFrom(in);
         indices = in.readStringArray();
         operationThreading = BroadcastOperationThreading.fromId(in.readByte());
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 }

+ 3 - 3
src/main/java/org/elasticsearch/action/support/broadcast/BroadcastOperationRequestBuilder.java

@@ -20,7 +20,7 @@
 package org.elasticsearch.action.support.broadcast;
 
 import org.elasticsearch.action.ActionRequestBuilder;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.InternalGenericClient;
 
 /**
@@ -57,8 +57,8 @@ public abstract class BroadcastOperationRequestBuilder<Request extends Broadcast
     }
 
     @SuppressWarnings("unchecked")
-    public final RequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public final RequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return (RequestBuilder) this;
     }
 }

+ 2 - 1
src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastOperationAction.java

@@ -126,7 +126,7 @@ public abstract class TransportBroadcastOperationAction<Request extends Broadcas
                 throw blockException;
             }
             // update to concrete indices
-            String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+            String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.indicesOptions());
             blockException = checkRequestBlock(clusterState, request, concreteIndices);
             if (blockException != null) {
                 throw blockException;
@@ -147,6 +147,7 @@ public abstract class TransportBroadcastOperationAction<Request extends Broadcas
                 } catch (Throwable e) {
                     listener.onFailure(e);
                 }
+                return;
             }
             request.beforeStart();
             // count the local operations, and perform the non local ones

+ 8 - 8
src/main/java/org/elasticsearch/action/support/master/info/ClusterInfoRequest.java

@@ -19,7 +19,7 @@
 
 package org.elasticsearch.action.support.master.info;
 
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequest;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -34,7 +34,7 @@ public abstract class ClusterInfoRequest<T extends ClusterInfoRequest> extends M
     private String[] indices = Strings.EMPTY_ARRAY;
     private String[] types = Strings.EMPTY_ARRAY;
 
-    private IgnoreIndices ignoreIndices = IgnoreIndices.NONE;
+    private IndicesOptions indicesOptions = IndicesOptions.strict();
     private boolean local = false;
 
     @SuppressWarnings("unchecked")
@@ -50,8 +50,8 @@ public abstract class ClusterInfoRequest<T extends ClusterInfoRequest> extends M
     }
 
     @SuppressWarnings("unchecked")
-    public T ignoreIndices(IgnoreIndices ignoreIndices) {
-        this.ignoreIndices = ignoreIndices;
+    public T indicesOptions(IndicesOptions indicesOptions) {
+        this.indicesOptions = indicesOptions;
         return (T) this;
     }
 
@@ -69,8 +69,8 @@ public abstract class ClusterInfoRequest<T extends ClusterInfoRequest> extends M
         return types;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
     public boolean local() {
@@ -82,7 +82,7 @@ public abstract class ClusterInfoRequest<T extends ClusterInfoRequest> extends M
         super.readFrom(in);
         indices = in.readStringArray();
         types = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
         local = in.readBoolean();
     }
 
@@ -91,7 +91,7 @@ public abstract class ClusterInfoRequest<T extends ClusterInfoRequest> extends M
         super.writeTo(out);
         out.writeStringArray(indices);
         out.writeStringArray(types);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
         out.writeBoolean(local);
     }
 }

+ 3 - 3
src/main/java/org/elasticsearch/action/support/master/info/ClusterInfoRequestBuilder.java

@@ -20,7 +20,7 @@ package org.elasticsearch.action.support.master.info;
 
 import com.google.common.collect.ObjectArrays;
 import org.elasticsearch.action.ActionResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
 import org.elasticsearch.client.internal.InternalGenericClient;
 
@@ -57,8 +57,8 @@ public abstract class ClusterInfoRequestBuilder<Request extends ClusterInfoReque
     }
 
     @SuppressWarnings("unchecked")
-    public Builder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request.ignoreIndices(ignoreIndices);
+    public Builder setIndicesOptions(IndicesOptions indicesOptions) {
+        request.indicesOptions(indicesOptions);
         return (Builder) this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java

@@ -49,7 +49,7 @@ public abstract class TransportClusterInfoAction<Request extends ClusterInfoRequ
 
     @Override
     protected final void masterOperation(final Request request, final ClusterState state, final ActionListener<Response> listener) throws ElasticSearchException {
-        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.ignoreIndices(), true);
+        String[] concreteIndices = state.metaData().concreteIndices(request.indices(), request.indicesOptions());
         request.indices(concreteIndices);
         doMasterOperation(request, state, listener);
     }

+ 10 - 10
src/main/java/org/elasticsearch/action/support/replication/IndicesReplicationOperationRequest.java

@@ -22,7 +22,7 @@ package org.elasticsearch.action.support.replication;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
 import org.elasticsearch.action.WriteConsistencyLevel;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.unit.TimeValue;
@@ -36,7 +36,7 @@ public class IndicesReplicationOperationRequest<T extends IndicesReplicationOper
 
     protected TimeValue timeout = ShardReplicationOperationRequest.DEFAULT_TIMEOUT;
     protected String[] indices;
-    private IgnoreIndices ignoreIndices = IgnoreIndices.DEFAULT;
+    private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, false);
 
     protected ReplicationType replicationType = ReplicationType.DEFAULT;
     protected WriteConsistencyLevel consistencyLevel = WriteConsistencyLevel.DEFAULT;
@@ -67,15 +67,15 @@ public class IndicesReplicationOperationRequest<T extends IndicesReplicationOper
         return this.indices;
     }
 
-    public IgnoreIndices ignoreIndices() {
-        return ignoreIndices;
+    public IndicesOptions indicesOptions() {
+        return indicesOptions;
     }
 
-    public T ignoreIndices(IgnoreIndices ignoreIndices) {
-        if (ignoreIndices == null) {
-            throw new IllegalArgumentException("IgnoreIndices must not be null");
+    public T indicesOptions(IndicesOptions indicesOptions) {
+        if (indicesOptions == null) {
+            throw new IllegalArgumentException("IndicesOptions must not be null");
         }
-        this.ignoreIndices = ignoreIndices;
+        this.indicesOptions = indicesOptions;
         return (T) this;
     }
 
@@ -139,7 +139,7 @@ public class IndicesReplicationOperationRequest<T extends IndicesReplicationOper
         consistencyLevel = WriteConsistencyLevel.fromId(in.readByte());
         timeout = TimeValue.readTimeValue(in);
         indices = in.readStringArray();
-        ignoreIndices = IgnoreIndices.fromId(in.readByte());
+        indicesOptions = IndicesOptions.readIndicesOptions(in);
     }
 
     @Override
@@ -149,6 +149,6 @@ public class IndicesReplicationOperationRequest<T extends IndicesReplicationOper
         out.writeByte(consistencyLevel.id());
         timeout.writeTo(out);
         out.writeStringArrayNullable(indices);
-        out.writeByte(ignoreIndices.id());
+        indicesOptions.writeIndicesOptions(out);
     }
 }

+ 6 - 4
src/main/java/org/elasticsearch/action/support/replication/IndicesReplicationOperationRequestBuilder.java

@@ -22,7 +22,7 @@ package org.elasticsearch.action.support.replication;
 import org.elasticsearch.action.ActionRequestBuilder;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.WriteConsistencyLevel;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.InternalGenericClient;
 import org.elasticsearch.common.unit.TimeValue;
 
@@ -60,10 +60,12 @@ public abstract class IndicesReplicationOperationRequestBuilder<Request extends
     }
 
     /**
-     * Specifies what type of requested indices to ignore. For example indices that don't exist.
+     * Specifies what type of requested indices to ignore and how to deal with wildcard indices expressions.
+     * For example indices that don't exist.
      */
-    public RequestBuilder setIgnoreIndices(IgnoreIndices ignoreIndices) {
-        request().ignoreIndices(ignoreIndices);
+    @SuppressWarnings("unchecked")
+    public RequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
+        request().indicesOptions(indicesOptions);
         return (RequestBuilder) this;
     }
 

+ 1 - 1
src/main/java/org/elasticsearch/action/support/replication/TransportIndicesReplicationOperationAction.java

@@ -75,7 +75,7 @@ public abstract class TransportIndicesReplicationOperationAction<Request extends
             throw blockException;
         }
         // get actual indices
-        String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.ignoreIndices(), false);
+        String[] concreteIndices = clusterState.metaData().concreteIndices(request.indices(), request.indicesOptions());
         blockException = checkRequestBlock(clusterState, request, concreteIndices);
         if (blockException != null) {
             throw blockException;

+ 73 - 19
src/main/java/org/elasticsearch/cluster/metadata/MetaData.java

@@ -27,7 +27,7 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.*;
 import org.elasticsearch.ElasticSearchIllegalArgumentException;
 import org.elasticsearch.Version;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.cluster.block.ClusterBlock;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.common.Nullable;
@@ -133,6 +133,7 @@ public class MetaData implements Iterable<IndexMetaData> {
 
     private final String[] allIndices;
     private final String[] allOpenIndices;
+    private final String[] allClosedIndices;
 
     private final ImmutableOpenMap<String, ImmutableOpenMap<String, AliasMetaData>> aliases;
     private final ImmutableOpenMap<String, String[]> aliasAndIndexToIndexMap;
@@ -167,13 +168,17 @@ public class MetaData implements Iterable<IndexMetaData> {
         int numIndices = allIndicesLst.size();
 
         List<String> allOpenIndices = Lists.newArrayList();
+        List<String> allClosedIndices = Lists.newArrayList();
         for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
             IndexMetaData indexMetaData = cursor.value;
             if (indexMetaData.state() == IndexMetaData.State.OPEN) {
                 allOpenIndices.add(indexMetaData.index());
+            } else if (indexMetaData.state() == IndexMetaData.State.CLOSE) {
+                allClosedIndices.add(indexMetaData.index());
             }
         }
         this.allOpenIndices = allOpenIndices.toArray(new String[allOpenIndices.size()]);
+        this.allClosedIndices = allClosedIndices.toArray(new String[allClosedIndices.size()]);
 
         // build aliases map
         ImmutableOpenMap.Builder<String, Object> tmpAliases = ImmutableOpenMap.builder(numAliases);
@@ -414,6 +419,14 @@ public class MetaData implements Iterable<IndexMetaData> {
         return allOpenIndices;
     }
 
+    public String[] concreteAllClosedIndices() {
+        return allClosedIndices;
+    }
+
+    public String[] getConcreteAllClosedIndices() {
+        return allClosedIndices;
+    }
+
     /**
      * Returns indexing routing for the given index.
      */
@@ -444,7 +457,7 @@ public class MetaData implements Iterable<IndexMetaData> {
     }
 
     public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String aliasOrIndex) {
-        return resolveSearchRouting(routing, convertFromWildcards(new String[]{aliasOrIndex}, true, IgnoreIndices.MISSING));
+        return resolveSearchRouting(routing, convertFromWildcards(new String[]{aliasOrIndex}, IndicesOptions.lenient()));
     }
 
     public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String[] aliasesOrIndices) {
@@ -452,7 +465,7 @@ public class MetaData implements Iterable<IndexMetaData> {
             return resolveSearchRoutingAllIndices(routing);
         }
 
-        aliasesOrIndices = convertFromWildcards(aliasesOrIndices, true, IgnoreIndices.MISSING);
+        aliasesOrIndices = convertFromWildcards(aliasesOrIndices, IndicesOptions.lenient());
 
         if (aliasesOrIndices.length == 1) {
             return resolveSearchRoutingSingleValue(routing, aliasesOrIndices[0]);
@@ -595,24 +608,39 @@ public class MetaData implements Iterable<IndexMetaData> {
      * Translates the provided indices (possibly aliased) into actual indices.
      */
     public String[] concreteIndices(String[] indices) throws IndexMissingException {
-        return concreteIndices(indices, IgnoreIndices.NONE, false);
+        return concreteIndices(indices, IndicesOptions.fromOptions(false, true, true, true));
     }
 
     /**
      * Translates the provided indices (possibly aliased) into actual indices.
      */
     public String[] concreteIndicesIgnoreMissing(String[] indices) {
-        return concreteIndices(indices, IgnoreIndices.MISSING, false);
+        return concreteIndices(indices, IndicesOptions.fromOptions(true, true, true, false));
     }
 
     /**
      * Translates the provided indices (possibly aliased) into actual indices.
      */
-    public String[] concreteIndices(String[] aliasesOrIndices, IgnoreIndices ignoreIndices, boolean allOnlyOpen) throws IndexMissingException {
+    public String[] concreteIndices(String[] aliasesOrIndices, IndicesOptions indicesOptions) throws IndexMissingException {
         if (isAllIndices(aliasesOrIndices)) {
-            return allOnlyOpen ? concreteAllOpenIndices() : concreteAllIndices();
+            String[] concreteIndices;
+            if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
+                concreteIndices = concreteAllIndices();
+            } else if (indicesOptions.expandWildcardsOpen()) {
+                concreteIndices = concreteAllOpenIndices();
+            } else if (indicesOptions.expandWildcardsClosed()) {
+                concreteIndices = concreteAllClosedIndices();
+            } else {
+                assert false : "Shouldn't end up here";
+                concreteIndices = Strings.EMPTY_ARRAY;
+            }
+
+            if (!indicesOptions.allowNoIndices() && concreteIndices.length == 0) {
+                throw new IndexMissingException(new Index("_all"));
+            }
+            return concreteIndices;
         }
-        aliasesOrIndices = convertFromWildcards(aliasesOrIndices, allOnlyOpen, ignoreIndices);
+        aliasesOrIndices = convertFromWildcards(aliasesOrIndices, indicesOptions);
         // optimize for single element index (common case)
         if (aliasesOrIndices.length == 1) {
             String aliasOrIndex = aliasesOrIndices[0];
@@ -620,8 +648,8 @@ public class MetaData implements Iterable<IndexMetaData> {
             if (this.indices.containsKey(aliasOrIndex)) {
                 return aliasesOrIndices;
             }
-            String[] actualLst = aliasAndIndexToIndexMap.get(aliasOrIndex);
-            if (actualLst == null) {
+            String[] actualLst = aliasAndIndexToIndexMap.getOrDefault(aliasOrIndex, Strings.EMPTY_ARRAY);
+            if (!indicesOptions.allowNoIndices() && actualLst == null) {
                 throw new IndexMissingException(new Index(aliasOrIndex));
             } else {
                 return actualLst;
@@ -645,7 +673,7 @@ public class MetaData implements Iterable<IndexMetaData> {
         for (String index : aliasesOrIndices) {
             String[] actualLst = aliasAndIndexToIndexMap.get(index);
             if (actualLst == null) {
-                if (ignoreIndices != IgnoreIndices.MISSING) {
+                if (!indicesOptions.ignoreUnavailable()) {
                     throw new IndexMissingException(new Index(index));
                 }
             } else {
@@ -655,7 +683,7 @@ public class MetaData implements Iterable<IndexMetaData> {
             }
         }
 
-        if (actualIndices.isEmpty()) {
+        if (!indicesOptions.allowNoIndices() && actualIndices.isEmpty()) {
             throw new IndexMissingException(new Index(Arrays.toString(aliasesOrIndices)));
         }
         return actualIndices.toArray(new String[actualIndices.size()]);
@@ -682,7 +710,7 @@ public class MetaData implements Iterable<IndexMetaData> {
      * won't convert only to indices, but also to aliases. For example, alias_* will expand to alias_1 and alias_2, not
      * to the respective indices those aliases point to.
      */
-    public String[] convertFromWildcards(String[] aliasesOrIndices, boolean wildcardOnlyOpen, IgnoreIndices ignoreIndices) {
+    public String[] convertFromWildcards(String[] aliasesOrIndices, IndicesOptions indicesOptions) {
         if (aliasesOrIndices == null) {
             return null;
         }
@@ -706,13 +734,24 @@ public class MetaData implements Iterable<IndexMetaData> {
             } else if (aliasOrIndex.charAt(0) == '-') {
                 // if its the first, fill it with all the indices...
                 if (i == 0) {
-                    result = new HashSet<String>(Arrays.asList(wildcardOnlyOpen ? concreteAllOpenIndices() : concreteAllIndices()));
+                    String[] concreteIndices;
+                    if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
+                        concreteIndices = concreteAllIndices();
+                    } else if (indicesOptions.expandWildcardsOpen()) {
+                        concreteIndices = concreteAllOpenIndices();
+                    } else if (indicesOptions.expandWildcardsClosed()) {
+                        concreteIndices = concreteAllClosedIndices();
+                    } else {
+                        assert false : "Shouldn't end up here";
+                        concreteIndices = Strings.EMPTY_ARRAY;
+                    }
+                    result = new HashSet<String>(Arrays.asList(concreteIndices));
                 }
                 add = false;
                 aliasOrIndex = aliasOrIndex.substring(1);
             }
             if (!Regex.isSimpleMatchPattern(aliasOrIndex)) {
-                if (ignoreIndices != IgnoreIndices.MISSING && !aliasAndIndexToIndexMap.containsKey(aliasOrIndex)) {
+                if (!indicesOptions.ignoreUnavailable() && !aliasAndIndexToIndexMap.containsKey(aliasOrIndex)) {
                     throw new IndexMissingException(new Index(aliasOrIndex));
                 }
                 if (result != null) {
@@ -729,8 +768,19 @@ public class MetaData implements Iterable<IndexMetaData> {
                 result = new HashSet<String>();
                 result.addAll(Arrays.asList(aliasesOrIndices).subList(0, i));
             }
-            String[] indices = wildcardOnlyOpen ? concreteAllOpenIndices() : concreteAllIndices();
+            String[] indices;
+            if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
+                indices = concreteAllIndices();
+            } else if (indicesOptions.expandWildcardsOpen()) {
+                indices = concreteAllOpenIndices();
+            } else if (indicesOptions.expandWildcardsClosed()) {
+                indices = concreteAllClosedIndices();
+            } else {
+                assert false : "Shouldn't end up here";
+                indices = Strings.EMPTY_ARRAY;
+            }
             boolean found = false;
+            // iterating over all concrete indices and see if there is a wildcard match
             for (String index : indices) {
                 if (Regex.simpleMatch(aliasOrIndex, index)) {
                     found = true;
@@ -741,6 +791,7 @@ public class MetaData implements Iterable<IndexMetaData> {
                     }
                 }
             }
+            // iterating over all aliases and see if there is a wildcard match
             for (ObjectCursor<String> cursor : aliases.keys()) {
                 String alias = cursor.value;
                 if (Regex.simpleMatch(aliasOrIndex, alias)) {
@@ -752,13 +803,16 @@ public class MetaData implements Iterable<IndexMetaData> {
                     }
                 }
             }
-            if (!found && ignoreIndices != IgnoreIndices.MISSING) {
+            if (!found && !indicesOptions.allowNoIndices()) {
                 throw new IndexMissingException(new Index(aliasOrIndex));
             }
         }
         if (result == null) {
             return aliasesOrIndices;
         }
+        if (result.isEmpty() && !indicesOptions.allowNoIndices()) {
+            throw new IndexMissingException(new Index(Arrays.toString(aliasesOrIndices)));
+        }
         return result.toArray(new String[result.size()]);
     }
 
@@ -828,7 +882,7 @@ public class MetaData implements Iterable<IndexMetaData> {
      */
     public String[] filteringAliases(String index, String... indicesOrAliases) {
         // expand the aliases wildcard
-        indicesOrAliases = convertFromWildcards(indicesOrAliases, true, IgnoreIndices.MISSING);
+        indicesOrAliases = convertFromWildcards(indicesOrAliases, IndicesOptions.lenient());
 
         if (isAllIndices(indicesOrAliases)) {
             return null;
@@ -917,7 +971,7 @@ public class MetaData implements Iterable<IndexMetaData> {
         if (concreteIndices.length == concreteAllIndices().length && indicesOrAliases.length > 0) {
 
             //we might have something like /-test1,+test1 that would identify all indices
-            //or something like /-test1 with test1 index missing and IgnoreIndices.MISSING
+            //or something like /-test1 with test1 index missing and IndicesOptions.lenient()
             if (indicesOrAliases[0].charAt(0) == '-') {
                 return true;
             }

+ 0 - 3
src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java

@@ -492,9 +492,6 @@ public class MetaDataMappingService extends AbstractComponent {
             public ClusterState execute(final ClusterState currentState) throws Exception {
                 List<String> indicesToClose = Lists.newArrayList();
                 try {
-                    if (request.indices().length == 0) {
-                        throw new IndexMissingException(new Index("_all"));
-                    }
                     for (String index : request.indices()) {
                         if (!currentState.metaData().hasIndex(index)) {
                             throw new IndexMissingException(new Index(index));

+ 3 - 6
src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java

@@ -112,13 +112,13 @@ public class PlainOperationRouting extends AbstractComponent implements Operatio
 
     @Override
     public int searchShardsCount(ClusterState clusterState, String[] indices, String[] concreteIndices, @Nullable Map<String, Set<String>> routing, @Nullable String preference) throws IndexMissingException {
-        final Set<IndexShardRoutingTable> shards = computeTargetedShards(clusterState, indices, concreteIndices, routing);
+        final Set<IndexShardRoutingTable> shards = computeTargetedShards(clusterState, concreteIndices, routing);
         return shards.size();
     }
 
     @Override
     public GroupShardsIterator searchShards(ClusterState clusterState, String[] indices, String[] concreteIndices, @Nullable Map<String, Set<String>> routing, @Nullable String preference) throws IndexMissingException {
-        final Set<IndexShardRoutingTable> shards = computeTargetedShards(clusterState, indices, concreteIndices, routing);
+        final Set<IndexShardRoutingTable> shards = computeTargetedShards(clusterState, concreteIndices, routing);
         final Set<ShardIterator> set = new HashSet<ShardIterator>(shards.size());
         for (IndexShardRoutingTable shard : shards) {
             ShardIterator iterator = preferenceActiveShardIterator(shard, clusterState.nodes().localNodeId(), clusterState.nodes(), preference);
@@ -131,10 +131,7 @@ public class PlainOperationRouting extends AbstractComponent implements Operatio
 
     private static final Map<String, Set<String>> EMPTY_ROUTING = Collections.emptyMap();
 
-    private Set<IndexShardRoutingTable> computeTargetedShards(ClusterState clusterState, String[] indices, String[] concreteIndices, @Nullable Map<String, Set<String>> routing) throws IndexMissingException {
-        if (concreteIndices == null || concreteIndices.length == 0) {
-            concreteIndices = clusterState.metaData().concreteAllOpenIndices();
-        }
+    private Set<IndexShardRoutingTable> computeTargetedShards(ClusterState clusterState, String[] concreteIndices, @Nullable Map<String, Set<String>> routing) throws IndexMissingException {
         routing = routing == null ? EMPTY_ROUTING : routing; // just use an empty map
         final Set<IndexShardRoutingTable> set = new HashSet<IndexShardRoutingTable>();
         // we use set here and not list since we might get duplicates

+ 8 - 0
src/main/java/org/elasticsearch/common/collect/ImmutableOpenMap.java

@@ -55,6 +55,14 @@ public final class ImmutableOpenMap<KType, VType> implements Iterable<ObjectObje
         return map.get(key);
     }
 
+    /**
+     * @return Returns the value associated with the given key or the provided default value if the
+     * key is not associated with any value.
+     */
+    public VType getOrDefault(KType key, VType defaultValue) {
+        return map.getOrDefault(key, defaultValue);
+    }
+
     /**
      * Returns <code>true</code> if this container has an association to a value for
      * the given key.

+ 1 - 11
src/main/java/org/elasticsearch/index/query/IndicesFilterParser.java

@@ -20,14 +20,12 @@
 package org.elasticsearch.index.query;
 
 import org.apache.lucene.search.Filter;
-import org.elasticsearch.action.support.IgnoreIndices;
 import org.elasticsearch.cluster.ClusterService;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.lucene.search.Queries;
 import org.elasticsearch.common.regex.Regex;
 import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.indices.IndexMissingException;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -147,15 +145,7 @@ public class IndicesFilterParser implements FilterParser {
     }
 
     protected boolean matchesIndices(String currentIndex, String... indices) {
-        final String[] concreteIndices;
-        try {
-            concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
-        } catch(IndexMissingException e) {
-            //Although we use IgnoreIndices.MISSING, according to MetaData#concreteIndices contract,
-            // we get IndexMissing either when we have a single index that is missing or when all indices are missing
-            return false;
-        }
-
+        final String[] concreteIndices = clusterService.state().metaData().concreteIndicesIgnoreMissing(indices);
         for (String index : concreteIndices) {
             if (Regex.simpleMatch(index, currentIndex)) {
                 return true;

+ 1 - 11
src/main/java/org/elasticsearch/index/query/IndicesQueryParser.java

@@ -20,14 +20,12 @@
 package org.elasticsearch.index.query;
 
 import org.apache.lucene.search.Query;
-import org.elasticsearch.action.support.IgnoreIndices;
 import org.elasticsearch.cluster.ClusterService;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.lucene.search.Queries;
 import org.elasticsearch.common.regex.Regex;
 import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.indices.IndexMissingException;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -145,15 +143,7 @@ public class IndicesQueryParser implements QueryParser {
     }
 
     protected boolean matchesIndices(String currentIndex, String... indices) {
-        final String[] concreteIndices;
-        try {
-            concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
-        } catch(IndexMissingException e) {
-            //Although we use IgnoreIndices.MISSING, according to MetaData#concreteIndices contract,
-            // we get IndexMissing either when we have a single index that is missing or when all indices are missing
-            return false;
-        }
-
+        final String[] concreteIndices = clusterService.state().metaData().concreteIndicesIgnoreMissing(indices);
         for (String index : concreteIndices) {
             if (Regex.simpleMatch(index, currentIndex)) {
                 return true;

+ 2 - 4
src/main/java/org/elasticsearch/rest/action/admin/cluster/shards/RestClusterSearchShardsAction.java

@@ -22,7 +22,7 @@ package org.elasticsearch.rest.action.admin.cluster.shards;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsRequest;
 import org.elasticsearch.action.admin.cluster.shards.ClusterSearchShardsResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.Requests;
 import org.elasticsearch.common.Strings;
@@ -62,9 +62,7 @@ public class RestClusterSearchShardsAction extends BaseRestHandler {
         clusterSearchShardsRequest.types(Strings.splitStringByCommaToArray(request.param("type")));
         clusterSearchShardsRequest.routing(request.param("routing"));
         clusterSearchShardsRequest.preference(request.param("preference"));
-        if (request.hasParam("ignore_indices")) {
-            clusterSearchShardsRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        clusterSearchShardsRequest.indicesOptions(IndicesOptions.fromRequest(request, clusterSearchShardsRequest.indicesOptions()));
 
         client.admin().cluster().searchShards(clusterSearchShardsRequest, new ActionListener<ClusterSearchShardsResponse>() {
             @Override

+ 2 - 5
src/main/java/org/elasticsearch/rest/action/admin/indices/alias/get/RestGetAliasesAction.java

@@ -23,7 +23,7 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
 import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.cluster.metadata.AliasMetaData;
 import org.elasticsearch.common.Strings;
@@ -59,10 +59,7 @@ public class RestGetAliasesAction extends BaseRestHandler {
         final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
         final GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases);
         getAliasesRequest.indices(indices);
-
-        if (request.hasParam("ignore_indices")) {
-            getAliasesRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions()));
 
         client.admin().indices().getAliases(getAliasesRequest, new ActionListener<GetAliasesResponse>() {
 

+ 2 - 5
src/main/java/org/elasticsearch/rest/action/admin/indices/alias/head/RestAliasesExistAction.java

@@ -23,7 +23,7 @@ import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.alias.exists.AliasesExistResponse;
 import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.inject.Inject;
@@ -51,10 +51,7 @@ public class RestAliasesExistAction extends BaseRestHandler {
         final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
         GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliases);
         getAliasesRequest.indices(indices);
-
-        if (request.hasParam("ignore_indices")) {
-            getAliasesRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        getAliasesRequest.indicesOptions(IndicesOptions.fromRequest(request, getAliasesRequest.indicesOptions()));
 
         client.admin().indices().aliasesExist(getAliasesRequest, new ActionListener<AliasesExistResponse>() {
 

+ 2 - 4
src/main/java/org/elasticsearch/rest/action/admin/indices/cache/clear/RestClearIndicesCacheAction.java

@@ -22,7 +22,7 @@ package org.elasticsearch.rest.action.admin.indices.cache.clear;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest;
 import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.broadcast.BroadcastOperationThreading;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
@@ -59,9 +59,7 @@ public class RestClearIndicesCacheAction extends BaseRestHandler {
     public void handleRequest(final RestRequest request, final RestChannel channel) {
         ClearIndicesCacheRequest clearIndicesCacheRequest = new ClearIndicesCacheRequest(Strings.splitStringByCommaToArray(request.param("index")));
         clearIndicesCacheRequest.listenerThreaded(false);
-        if (request.hasParam("ignore_indices")) {
-            clearIndicesCacheRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        clearIndicesCacheRequest.indicesOptions(IndicesOptions.fromRequest(request, clearIndicesCacheRequest.indicesOptions()));
         try {
             if (request.hasParam("filter")) {
                 clearIndicesCacheRequest.filterCache(request.paramAsBoolean("filter", clearIndicesCacheRequest.filterCache()));

+ 2 - 4
src/main/java/org/elasticsearch/rest/action/admin/indices/close/RestCloseIndexAction.java

@@ -21,7 +21,7 @@ package org.elasticsearch.rest.action.admin.indices.close;
 
 import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
 import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.inject.Inject;
@@ -46,9 +46,7 @@ public class RestCloseIndexAction extends BaseRestHandler {
         closeIndexRequest.listenerThreaded(false);
         closeIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", closeIndexRequest.masterNodeTimeout()));
         closeIndexRequest.timeout(request.paramAsTime("timeout", closeIndexRequest.timeout()));
-        if (request.hasParam("ignore_indices")) {
-            closeIndexRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        closeIndexRequest.indicesOptions(IndicesOptions.fromRequest(request, closeIndexRequest.indicesOptions()));
         client.admin().indices().close(closeIndexRequest, new AcknowledgedRestResponseActionListener<CloseIndexResponse>(request, channel, logger));
     }
 }

+ 2 - 0
src/main/java/org/elasticsearch/rest/action/admin/indices/delete/RestDeleteIndexAction.java

@@ -21,6 +21,7 @@ package org.elasticsearch.rest.action.admin.indices.delete;
 
 import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
 import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.inject.Inject;
@@ -45,6 +46,7 @@ public class RestDeleteIndexAction extends BaseRestHandler {
         deleteIndexRequest.listenerThreaded(false);
         deleteIndexRequest.timeout(request.paramAsTime("timeout", deleteIndexRequest.timeout()));
         deleteIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", deleteIndexRequest.masterNodeTimeout()));
+        deleteIndexRequest.indicesOptions(IndicesOptions.fromRequest(request, deleteIndexRequest.indicesOptions()));
         client.admin().indices().delete(deleteIndexRequest, new AcknowledgedRestResponseActionListener<DeleteIndexResponse>(request, channel, logger));
     }
 }

+ 2 - 0
src/main/java/org/elasticsearch/rest/action/admin/indices/exists/indices/RestIndicesExistsAction.java

@@ -23,6 +23,7 @@ import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.inject.Inject;
@@ -53,6 +54,7 @@ public class RestIndicesExistsAction extends BaseRestHandler {
     @Override
     public void handleRequest(final RestRequest request, final RestChannel channel) {
         IndicesExistsRequest indicesExistsRequest = new IndicesExistsRequest(Strings.splitStringByCommaToArray(request.param("index")));
+        indicesExistsRequest.indicesOptions(IndicesOptions.fromRequest(request, indicesExistsRequest.indicesOptions()));
         indicesExistsRequest.listenerThreaded(false);
         client.admin().indices().exists(indicesExistsRequest, new ActionListener<IndicesExistsResponse>() {
             @Override

+ 2 - 4
src/main/java/org/elasticsearch/rest/action/admin/indices/exists/types/RestTypesExistsAction.java

@@ -23,7 +23,7 @@ import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.exists.types.TypesExistsRequest;
 import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
-import org.elasticsearch.action.support.IgnoreIndices;
+import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.inject.Inject;
@@ -51,9 +51,7 @@ public class RestTypesExistsAction extends BaseRestHandler {
                 Strings.splitStringByCommaToArray(request.param("index")), Strings.splitStringByCommaToArray(request.param("type"))
         );
         typesExistsRequest.listenerThreaded(false);
-        if (request.hasParam("ignore_indices")) {
-            typesExistsRequest.ignoreIndices(IgnoreIndices.fromString(request.param("ignore_indices")));
-        }
+        typesExistsRequest.indicesOptions(IndicesOptions.fromRequest(request, typesExistsRequest.indicesOptions()));
         client.admin().indices().typesExists(typesExistsRequest, new ActionListener<TypesExistsResponse>() {
             @Override
             public void onResponse(TypesExistsResponse response) {

Some files were not shown because too many files changed in this diff