4242
4343import java .util .ArrayList ;
4444import java .util .Arrays ;
45- import java .util .Collection ;
4645import java .util .Collections ;
4746import java .util .HashMap ;
4847import java .util .HashSet ;
@@ -103,7 +102,7 @@ public String[] concreteIndexNames(ClusterState state, IndicesOptions options, S
103102 return concreteIndexNames (context , indexExpressions );
104103 }
105104
106- /**
105+ /**
107106 * Translates the provided index expression into actual concrete indices, properly deduplicated.
108107 *
109108 * @param state the cluster state containing all the data to resolve to expressions to concrete indices
@@ -117,7 +116,7 @@ public String[] concreteIndexNames(ClusterState state, IndicesOptions options, S
117116 * indices options in the context don't allow such a case.
118117 */
119118 public Index [] concreteIndices (ClusterState state , IndicesOptions options , String ... indexExpressions ) {
120- Context context = new Context (state , options );
119+ Context context = new Context (state , options , false , false );
121120 return concreteIndices (context , indexExpressions );
122121 }
123122
@@ -193,30 +192,40 @@ Index[] concreteIndices(Context context, String... indexExpressions) {
193192 }
194193 }
195194
196- Collection <IndexMetaData > resolvedIndices = aliasOrIndex .getIndices ();
197- if (resolvedIndices .size () > 1 && !options .allowAliasesToMultipleIndices ()) {
198- String [] indexNames = new String [resolvedIndices .size ()];
199- int i = 0 ;
200- for (IndexMetaData indexMetaData : resolvedIndices ) {
201- indexNames [i ++] = indexMetaData .getIndex ().getName ();
195+ if (aliasOrIndex .isAlias () && context .isResolveToWriteIndex ()) {
196+ AliasOrIndex .Alias alias = (AliasOrIndex .Alias ) aliasOrIndex ;
197+ IndexMetaData writeIndex = alias .getWriteIndex ();
198+ if (writeIndex == null ) {
199+ throw new IllegalArgumentException ("no write index is defined for alias [" + alias .getAliasName () + "]." +
200+ " The write index may be explicitly disabled using is_write_index=false or the alias points to multiple" +
201+ " indices without one being designated as a write index" );
202202 }
203- throw new IllegalArgumentException ("Alias [" + expression + "] has more than one indices associated with it [" +
203+ concreteIndices .add (writeIndex .getIndex ());
204+ } else {
205+ if (aliasOrIndex .getIndices ().size () > 1 && !options .allowAliasesToMultipleIndices ()) {
206+ String [] indexNames = new String [aliasOrIndex .getIndices ().size ()];
207+ int i = 0 ;
208+ for (IndexMetaData indexMetaData : aliasOrIndex .getIndices ()) {
209+ indexNames [i ++] = indexMetaData .getIndex ().getName ();
210+ }
211+ throw new IllegalArgumentException ("Alias [" + expression + "] has more than one indices associated with it [" +
204212 Arrays .toString (indexNames ) + "], can't execute a single index op" );
205- }
213+ }
206214
207- for (IndexMetaData index : resolvedIndices ) {
208- if (index .getState () == IndexMetaData .State .CLOSE ) {
209- if (failClosed ) {
210- throw new IndexClosedException (index .getIndex ());
211- } else {
212- if (options .forbidClosedIndices () == false ) {
213- concreteIndices .add (index .getIndex ());
215+ for (IndexMetaData index : aliasOrIndex .getIndices ()) {
216+ if (index .getState () == IndexMetaData .State .CLOSE ) {
217+ if (failClosed ) {
218+ throw new IndexClosedException (index .getIndex ());
219+ } else {
220+ if (options .forbidClosedIndices () == false ) {
221+ concreteIndices .add (index .getIndex ());
222+ }
214223 }
224+ } else if (index .getState () == IndexMetaData .State .OPEN ) {
225+ concreteIndices .add (index .getIndex ());
226+ } else {
227+ throw new IllegalStateException ("index state [" + index .getState () + "] not supported" );
215228 }
216- } else if (index .getState () == IndexMetaData .State .OPEN ) {
217- concreteIndices .add (index .getIndex ());
218- } else {
219- throw new IllegalStateException ("index state [" + index .getState () + "] not supported" );
220229 }
221230 }
222231 }
@@ -255,6 +264,28 @@ public Index concreteSingleIndex(ClusterState state, IndicesRequest request) {
255264 return indices [0 ];
256265 }
257266
267+ /**
268+ * Utility method that allows to resolve an index expression to its corresponding single write index.
269+ *
270+ * @param state the cluster state containing all the data to resolve to expression to a concrete index
271+ * @param request The request that defines how the an alias or an index need to be resolved to a concrete index
272+ * and the expression that can be resolved to an alias or an index name.
273+ * @throws IllegalArgumentException if the index resolution does not lead to an index, or leads to more than one index
274+ * @return the write index obtained as a result of the index resolution
275+ */
276+ public Index concreteWriteIndex (ClusterState state , IndicesRequest request ) {
277+ if (request .indices () == null || (request .indices () != null && request .indices ().length != 1 )) {
278+ throw new IllegalArgumentException ("indices request must specify a single index expression" );
279+ }
280+ Context context = new Context (state , request .indicesOptions (), false , true );
281+ Index [] indices = concreteIndices (context , request .indices ()[0 ]);
282+ if (indices .length != 1 ) {
283+ throw new IllegalArgumentException ("The index expression [" + request .indices ()[0 ] +
284+ "] and options provided did not point to a single write-index" );
285+ }
286+ return indices [0 ];
287+ }
288+
258289 /**
259290 * @return whether the specified alias or index exists. If the alias or index contains datemath then that is resolved too.
260291 */
@@ -292,7 +323,7 @@ public String[] indexAliases(ClusterState state, String index, Predicate<AliasMe
292323 String ... expressions ) {
293324 // expand the aliases wildcard
294325 List <String > resolvedExpressions = expressions != null ? Arrays .asList (expressions ) : Collections .emptyList ();
295- Context context = new Context (state , IndicesOptions .lenientExpandOpen (), true );
326+ Context context = new Context (state , IndicesOptions .lenientExpandOpen (), true , false );
296327 for (ExpressionResolver expressionResolver : expressionResolvers ) {
297328 resolvedExpressions = expressionResolver .resolve (context , resolvedExpressions );
298329 }
@@ -512,24 +543,26 @@ static final class Context {
512543 private final IndicesOptions options ;
513544 private final long startTime ;
514545 private final boolean preserveAliases ;
546+ private final boolean resolveToWriteIndex ;
515547
516548 Context (ClusterState state , IndicesOptions options ) {
517549 this (state , options , System .currentTimeMillis ());
518550 }
519551
520- Context (ClusterState state , IndicesOptions options , boolean preserveAliases ) {
521- this (state , options , System .currentTimeMillis (), preserveAliases );
552+ Context (ClusterState state , IndicesOptions options , boolean preserveAliases , boolean resolveToWriteIndex ) {
553+ this (state , options , System .currentTimeMillis (), preserveAliases , resolveToWriteIndex );
522554 }
523555
524556 Context (ClusterState state , IndicesOptions options , long startTime ) {
525- this (state , options , startTime , false );
557+ this (state , options , startTime , false , false );
526558 }
527559
528- Context (ClusterState state , IndicesOptions options , long startTime , boolean preserveAliases ) {
560+ Context (ClusterState state , IndicesOptions options , long startTime , boolean preserveAliases , boolean resolveToWriteIndex ) {
529561 this .state = state ;
530562 this .options = options ;
531563 this .startTime = startTime ;
532564 this .preserveAliases = preserveAliases ;
565+ this .resolveToWriteIndex = resolveToWriteIndex ;
533566 }
534567
535568 public ClusterState getState () {
@@ -552,6 +585,14 @@ public long getStartTime() {
552585 boolean isPreserveAliases () {
553586 return preserveAliases ;
554587 }
588+
589+ /**
590+ * This is used to require that aliases resolve to their write-index. It is currently not used in conjunction
591+ * with <code>preserveAliases</code>.
592+ */
593+ boolean isResolveToWriteIndex () {
594+ return resolveToWriteIndex ;
595+ }
555596 }
556597
557598 private interface ExpressionResolver {
0 commit comments