Skip to content

Commit df8fabd

Browse files
committed
refactor to use new resolveWriteIndex flag instead of IndicesOptions
1 parent 9e86921 commit df8fabd

File tree

9 files changed

+101
-104
lines changed

9 files changed

+101
-104
lines changed

modules/reindex/src/test/java/org/elasticsearch/index/reindex/ReindexSourceTargetValidationTests.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@
4646
*/
4747
public class ReindexSourceTargetValidationTests extends ESTestCase {
4848
private static final ClusterState STATE = ClusterState.builder(new ClusterName("test")).metaData(MetaData.builder()
49-
.put(index("target", "target_alias", "target_multi"), true)
50-
.put(index("target2", "target_multi"), true)
51-
.put(index("foo"), true)
52-
.put(index("bar"), true)
53-
.put(index("baz"), true)
54-
.put(index("source", "source_multi"), true)
55-
.put(index("source2", "source_multi"), true)).build();
49+
.put(index("target", false, "target_alias", "target_multi"), true)
50+
.put(index("target2", false, "target_multi"), true)
51+
.put(index("target3", true, "target_multi_with_write"), true)
52+
.put(index("target4", false, "target_multi_with_write"), true)
53+
.put(index("foo", false), true)
54+
.put(index("bar", false), true)
55+
.put(index("baz", false), true)
56+
.put(index("source", false, "source_multi"), true)
57+
.put(index("source2", false, "source_multi"), true)).build();
5658
private static final IndexNameExpressionResolver INDEX_NAME_EXPRESSION_RESOLVER = new IndexNameExpressionResolver(Settings.EMPTY);
5759
private static final AutoCreateIndex AUTO_CREATE_INDEX = new AutoCreateIndex(Settings.EMPTY,
5860
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), INDEX_NAME_EXPRESSION_RESOLVER);
@@ -80,7 +82,11 @@ public void testAliasesContainTarget() {
8082

8183
public void testTargetIsAlias() {
8284
Exception e = expectThrows(IllegalArgumentException.class, () -> succeeds("target_multi", "foo"));
83-
assertThat(e.getMessage(), containsString("Alias [target_multi] points to multiple indices"));
85+
assertThat(e.getMessage(), containsString("Alias [target_multi] has more than one indices associated with it [["));
86+
// The index names can come in either order
87+
assertThat(e.getMessage(), containsString("target"));
88+
assertThat(e.getMessage(), containsString("target2"));
89+
succeeds("target_multi_with_write", "foo"); // should this be allowed?
8490
}
8591

8692
public void testRemoteInfoSkipsValidation() {
@@ -106,7 +112,7 @@ private void succeeds(RemoteInfo remoteInfo, String target, String... sources) {
106112
INDEX_NAME_EXPRESSION_RESOLVER, AUTO_CREATE_INDEX, STATE);
107113
}
108114

109-
private static IndexMetaData index(String name, String... aliases) {
115+
private static IndexMetaData index(String name, boolean isWriteIndex, String... aliases) {
110116
IndexMetaData.Builder builder = IndexMetaData.builder(name).settings(Settings.builder()
111117
.put("index.version.created", Version.CURRENT.id)
112118
.put("index.number_of_shards", 1)

server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ Index getConcreteIndex(String indexOrAlias) {
474474
Index resolveIfAbsent(DocWriteRequest<?> request) {
475475
Index concreteIndex = indices.get(request.index());
476476
if (concreteIndex == null) {
477-
concreteIndex = indexNameExpressionResolver.concreteSingleIndex(state, request);
477+
concreteIndex = indexNameExpressionResolver.concreteWriteIndex(state, request);
478478
indices.put(request.index(), concreteIndex);
479479
}
480480
return concreteIndex;

server/src/main/java/org/elasticsearch/action/index/IndexRequest.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.elasticsearch.action.CompositeIndicesRequest;
2626
import org.elasticsearch.action.DocWriteRequest;
2727
import org.elasticsearch.action.RoutingMissingException;
28-
import org.elasticsearch.action.support.IndicesOptions;
2928
import org.elasticsearch.action.support.replication.ReplicatedWriteRequest;
3029
import org.elasticsearch.action.support.replication.ReplicationRequest;
3130
import org.elasticsearch.client.Requests;
@@ -189,11 +188,6 @@ public ActionRequestValidationException validate() {
189188
return validationException;
190189
}
191190

192-
@Override
193-
public IndicesOptions indicesOptions() {
194-
return IndicesOptions.strictAliasToWriteIndexNoExpandForbidClosed();
195-
}
196-
197191
/**
198192
* The content type. This will be used when generating a document from user provided objects like Maps and when parsing the
199193
* source at index time

server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ public enum Option {
7777
IGNORE_ALIASES,
7878
ALLOW_NO_INDICES,
7979
FORBID_ALIASES_TO_MULTIPLE_INDICES,
80-
FORBID_CLOSED_INDICES,
81-
REQUIRE_ALIASES_TO_WRITE_INDEX;
80+
FORBID_CLOSED_INDICES;
8281

8382
public static final EnumSet<Option> NONE = EnumSet.noneOf(Option.class);
8483
}
@@ -94,9 +93,6 @@ public enum Option {
9493
public static final IndicesOptions STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED =
9594
new IndicesOptions(EnumSet.of(Option.FORBID_ALIASES_TO_MULTIPLE_INDICES, Option.FORBID_CLOSED_INDICES),
9695
EnumSet.noneOf(WildcardStates.class));
97-
public static final IndicesOptions STRICT_ALIAS_TO_WRITE_INDEX_NO_EXPAND_FORBID_CLOSED =
98-
new IndicesOptions(EnumSet.of(Option.REQUIRE_ALIASES_TO_WRITE_INDEX, Option.FORBID_CLOSED_INDICES),
99-
EnumSet.noneOf(WildcardStates.class));
10096

10197
private final EnumSet<Option> options;
10298
private final EnumSet<WildcardStates> expandWildcards;
@@ -235,13 +231,6 @@ public boolean allowAliasesToMultipleIndices() {
235231
return options.contains(Option.FORBID_ALIASES_TO_MULTIPLE_INDICES) == false;
236232
}
237233

238-
/**
239-
* @return whether aliases pointing to a write index should resolve to that index
240-
*/
241-
public boolean requireAliasesToWriteIndex() {
242-
return options.contains(Option.REQUIRE_ALIASES_TO_WRITE_INDEX);
243-
}
244-
245234
/**
246235
* @return whether aliases should be ignored (when resolving a wildcard)
247236
*/
@@ -386,14 +375,6 @@ public static IndicesOptions strictSingleIndexNoExpandForbidClosed() {
386375
return STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED;
387376
}
388377

389-
/**
390-
* @return indices option that requires each specified index or alias to exist, doesn't expand wildcards and
391-
* throws error if any of the aliases resolves to multiple indices with none specified as a write-index
392-
*/
393-
public static IndicesOptions strictAliasToWriteIndexNoExpandForbidClosed() {
394-
return STRICT_ALIAS_TO_WRITE_INDEX_NO_EXPAND_FORBID_CLOSED;
395-
}
396-
397378
/**
398379
* @return indices options that ignores unavailable indices, expands wildcards only to open indices and
399380
* allows that no indices are resolved from wildcard expressions (not returning an error).
@@ -432,7 +413,6 @@ public String toString() {
432413
", allow_aliases_to_multiple_indices=" + allowAliasesToMultipleIndices() +
433414
", forbid_closed_indices=" + forbidClosedIndices() +
434415
", ignore_aliases=" + ignoreAliases() +
435-
", require_aliases_to_write_index=" + requireAliasesToWriteIndex() +
436416
']';
437417
}
438418
}

server/src/main/java/org/elasticsearch/action/support/replication/ReplicatedWriteRequest.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.elasticsearch.action.bulk.BulkShardRequest;
2323
import org.elasticsearch.action.delete.DeleteRequest;
2424
import org.elasticsearch.action.index.IndexRequest;
25-
import org.elasticsearch.action.support.IndicesOptions;
2625
import org.elasticsearch.action.support.WriteRequest;
2726
import org.elasticsearch.common.io.stream.StreamInput;
2827
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -59,11 +58,6 @@ public RefreshPolicy getRefreshPolicy() {
5958
return refreshPolicy;
6059
}
6160

62-
@Override
63-
public IndicesOptions indicesOptions() {
64-
return IndicesOptions.strictAliasToWriteIndexNoExpandForbidClosed();
65-
}
66-
6761
@Override
6862
public void readFrom(StreamInput in) throws IOException {
6963
super.readFrom(in);

server/src/main/java/org/elasticsearch/action/update/UpdateRequest.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.elasticsearch.action.DocWriteRequest;
2525
import org.elasticsearch.action.index.IndexRequest;
2626
import org.elasticsearch.action.support.ActiveShardCount;
27-
import org.elasticsearch.action.support.IndicesOptions;
2827
import org.elasticsearch.action.support.WriteRequest;
2928
import org.elasticsearch.action.support.replication.ReplicationRequest;
3029
import org.elasticsearch.action.support.single.instance.InstanceShardOperationRequest;
@@ -170,11 +169,6 @@ public ActionRequestValidationException validate() {
170169
return validationException;
171170
}
172171

173-
@Override
174-
public IndicesOptions indicesOptions() {
175-
return IndicesOptions.strictAliasToWriteIndexNoExpandForbidClosed();
176-
}
177-
178172
/**
179173
* The type of the indexed document.
180174
*/

server/src/main/java/org/elasticsearch/cluster/metadata/AliasOrIndex.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,13 @@ void addIndex(IndexMetaData indexMetaData) {
154154
}
155155

156156
public void computeAndValidateWriteIndex() {
157-
final List<IndexMetaData> writeIndices;
158-
if (referenceIndexMetaDatas.size() > 1) {
159-
writeIndices = referenceIndexMetaDatas.stream()
160-
.filter(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).writeIndex()))
161-
.collect(Collectors.toList());
162-
} else if(Boolean.FALSE.equals(referenceIndexMetaDatas.get(0).getAliases().get(aliasName).writeIndex()) == false) {
163-
writeIndices = Collections.singletonList(referenceIndexMetaDatas.get(0));
164-
} else {
165-
writeIndices = Collections.emptyList();
157+
List<IndexMetaData> writeIndices = referenceIndexMetaDatas.stream()
158+
.filter(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).writeIndex()))
159+
.collect(Collectors.toList());
160+
161+
if (writeIndices.isEmpty() && referenceIndexMetaDatas.size() == 1
162+
&& referenceIndexMetaDatas.get(0).getAliases().get(aliasName).writeIndex() == null) {
163+
writeIndices.add(referenceIndexMetaDatas.get(0));
166164
}
167165

168166
if (writeIndices.size() == 1) {

server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ public String[] concreteIndexNames(ClusterState state, IndicesOptions options, S
103103
return concreteIndexNames(context, indexExpressions);
104104
}
105105

106-
/**
106+
/**
107107
* Translates the provided index expression into actual concrete indices, properly deduplicated.
108108
*
109-
* @param state the cluster state containing all the data to resolve to expressions to concrete indices
110-
* @param options defines how the aliases or indices need to be resolved to concrete indices
109+
* @param state the cluster state containing all the data to resolve to expressions to concrete indices
110+
* @param options defines how the aliases or indices need to be resolved to concrete indices
111111
* @param indexExpressions expressions that can be resolved to alias or index names.
112112
* @return the resolved concrete indices based on the cluster state, indices options and index expressions
113113
* @throws IndexNotFoundException if one of the index expressions is pointing to a missing index or alias and the
@@ -117,7 +117,26 @@ public String[] concreteIndexNames(ClusterState state, IndicesOptions options, S
117117
* indices options in the context don't allow such a case.
118118
*/
119119
public Index[] concreteIndices(ClusterState state, IndicesOptions options, String... indexExpressions) {
120-
Context context = new Context(state, options);
120+
Context context = new Context(state, options, false, false);
121+
return concreteIndices(context, indexExpressions);
122+
}
123+
124+
/**
125+
* Translates the provided index expression into actual concrete indices, properly deduplicated.
126+
*
127+
* @param state the cluster state containing all the data to resolve to expressions to concrete indices
128+
* @param options defines how the aliases or indices need to be resolved to concrete indices
129+
* @param resolveToWriteIndex defines whether to require that aliases resolve to their respective write indices
130+
* @param indexExpressions expressions that can be resolved to alias or index names.
131+
* @return the resolved concrete indices based on the cluster state, indices options and index expressions
132+
* @throws IndexNotFoundException if one of the index expressions is pointing to a missing index or alias and the
133+
* provided indices options in the context don't allow such a case, or if the final result of the indices resolution
134+
* contains no indices and the indices options in the context don't allow such a case.
135+
* @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
136+
* indices options in the context don't allow such a case.
137+
*/
138+
public Index[] concreteIndices(ClusterState state, IndicesOptions options, boolean resolveToWriteIndex, String... indexExpressions) {
139+
Context context = new Context(state, options, false, resolveToWriteIndex);
121140
return concreteIndices(context, indexExpressions);
122141
}
123142

@@ -195,7 +214,7 @@ Index[] concreteIndices(Context context, String... indexExpressions) {
195214

196215
Collection<IndexMetaData> resolvedIndices = aliasOrIndex.getIndices();
197216

198-
if (aliasOrIndex.isAlias() && options.requireAliasesToWriteIndex()) {
217+
if (aliasOrIndex.isAlias() && context.isResolveToWriteIndex()) {
199218
AliasOrIndex.Alias alias = (AliasOrIndex.Alias) aliasOrIndex;
200219
IndexMetaData writeIndex = alias.getWriteIndex();
201220
if (writeIndex == null) {
@@ -269,6 +288,24 @@ public Index concreteSingleIndex(ClusterState state, IndicesRequest request) {
269288
return indices[0];
270289
}
271290

291+
/**
292+
* Utility method that allows to resolve an index expression to its corresponding single write index.
293+
*
294+
* @param state the cluster state containing all the data to resolve to expression to a concrete index
295+
* @param request The request that defines how the an alias or an index need to be resolved to a concrete index
296+
* and the expression that can be resolved to an alias or an index name.
297+
* @throws IllegalArgumentException if the index resolution does not lead to an index, or leads to more than one index
298+
* @return the write index obtained as a result of the index resolution
299+
*/
300+
public Index concreteWriteIndex(ClusterState state, IndicesRequest request) {
301+
String indexExpression = request.indices() != null && request.indices().length > 0 ? request.indices()[0] : null;
302+
Index[] indices = concreteIndices(state, request.indicesOptions(), true, indexExpression);
303+
if (indices.length != 1) {
304+
throw new IllegalArgumentException("unable to return a single index as the index and options provided got resolved to multiple indices");
305+
}
306+
return indices[0];
307+
}
308+
272309
/**
273310
* @return whether the specified alias or index exists. If the alias or index contains datemath then that is resolved too.
274311
*/
@@ -306,7 +343,7 @@ public String[] indexAliases(ClusterState state, String index, Predicate<AliasMe
306343
String... expressions) {
307344
// expand the aliases wildcard
308345
List<String> resolvedExpressions = expressions != null ? Arrays.asList(expressions) : Collections.emptyList();
309-
Context context = new Context(state, IndicesOptions.lenientExpandOpen(), true);
346+
Context context = new Context(state, IndicesOptions.lenientExpandOpen(), true, false);
310347
for (ExpressionResolver expressionResolver : expressionResolvers) {
311348
resolvedExpressions = expressionResolver.resolve(context, resolvedExpressions);
312349
}
@@ -526,24 +563,26 @@ static final class Context {
526563
private final IndicesOptions options;
527564
private final long startTime;
528565
private final boolean preserveAliases;
566+
private final boolean resolveToWriteIndex;
529567

530568
Context(ClusterState state, IndicesOptions options) {
531569
this(state, options, System.currentTimeMillis());
532570
}
533571

534-
Context(ClusterState state, IndicesOptions options, boolean preserveAliases) {
535-
this(state, options, System.currentTimeMillis(), preserveAliases);
572+
Context(ClusterState state, IndicesOptions options, boolean preserveAliases, boolean resolveToWriteIndex) {
573+
this(state, options, System.currentTimeMillis(), preserveAliases, resolveToWriteIndex);
536574
}
537575

538576
Context(ClusterState state, IndicesOptions options, long startTime) {
539-
this(state, options, startTime, false);
577+
this(state, options, startTime, false, false);
540578
}
541579

542-
Context(ClusterState state, IndicesOptions options, long startTime, boolean preserveAliases) {
580+
Context(ClusterState state, IndicesOptions options, long startTime, boolean preserveAliases, boolean resolveToWriteIndex) {
543581
this.state = state;
544582
this.options = options;
545583
this.startTime = startTime;
546584
this.preserveAliases = preserveAliases;
585+
this.resolveToWriteIndex = resolveToWriteIndex;
547586
}
548587

549588
public ClusterState getState() {
@@ -566,6 +605,15 @@ public long getStartTime() {
566605
boolean isPreserveAliases() {
567606
return preserveAliases;
568607
}
608+
609+
/**
610+
* This is used to require that aliases resolve to their write-index. It is currently not used in conjunction
611+
* with <code>preserveAliases</code>.
612+
*/
613+
614+
boolean isResolveToWriteIndex() {
615+
return resolveToWriteIndex;
616+
}
569617
}
570618

571619
private interface ExpressionResolver {

0 commit comments

Comments
 (0)