Skip to content

Commit 2227ac5

Browse files
authored
[8.x][Failure store] Remove ::* selector (#121900) (#122433)
1 parent c6e82f9 commit 2227ac5

File tree

14 files changed

+130
-283
lines changed

14 files changed

+130
-283
lines changed

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static TransportVersion def(int id) {
179179
public static final TransportVersion INFERENCE_REQUEST_ADAPTIVE_RATE_LIMITING = def(8_839_0_00);
180180
public static final TransportVersion ML_INFERENCE_IBM_WATSONX_RERANK_ADDED = def(8_840_0_00);
181181
public static final TransportVersion COHERE_BIT_EMBEDDING_TYPE_SUPPORT_ADDED_BACKPORT_8_X = def(8_840_0_01);
182+
public static final TransportVersion REMOVE_ALL_APPLICABLE_SELECTOR_BACKPORT_8_X = def(8_840_0_02);
182183

183184
/*
184185
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -646,10 +646,6 @@ private static void enrichIndexAbstraction(
646646
: switch (resolvedExpression.selector()) {
647647
case DATA -> dataStream.getDataComponent().getIndices().stream();
648648
case FAILURES -> dataStream.getFailureIndices().stream();
649-
case ALL_APPLICABLE -> Stream.concat(
650-
dataStream.getIndices().stream(),
651-
dataStream.getFailureIndices().stream()
652-
);
653649
};
654650
String[] backingIndices = dataStreamIndices.map(Index::getName).toArray(String[]::new);
655651
dataStreams.add(new ResolvedDataStream(dataStream.getName(), backingIndices, DataStream.TIMESTAMP_FIELD_NAME));
@@ -670,13 +666,6 @@ private static Stream<Index> getAliasIndexStream(ResolvedExpression resolvedExpr
670666
assert ia.isDataStreamRelated() : "Illegal selector [failures] used on non data stream alias";
671667
yield ia.getFailureIndices(metadata).stream();
672668
}
673-
case ALL_APPLICABLE -> {
674-
if (ia.isDataStreamRelated()) {
675-
yield Stream.concat(ia.getIndices().stream(), ia.getFailureIndices(metadata).stream());
676-
} else {
677-
yield ia.getIndices().stream();
678-
}
679-
}
680669
};
681670
}
682671
return aliasIndices;

server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313
import org.elasticsearch.action.IndicesRequest;
1414
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
1515
import org.elasticsearch.action.support.ActiveShardCount;
16-
import org.elasticsearch.action.support.IndexComponentSelector;
1716
import org.elasticsearch.action.support.IndicesOptions;
1817
import org.elasticsearch.action.support.master.AcknowledgedRequest;
19-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
2018
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.SelectorResolver;
2119
import org.elasticsearch.common.io.stream.StreamInput;
2220
import org.elasticsearch.common.io.stream.StreamOutput;
2321
import org.elasticsearch.core.RestApiVersion;
2422
import org.elasticsearch.index.mapper.MapperService;
23+
import org.elasticsearch.indices.InvalidIndexNameException;
2524
import org.elasticsearch.tasks.CancellableTask;
2625
import org.elasticsearch.tasks.Task;
2726
import org.elasticsearch.tasks.TaskId;
@@ -149,14 +148,12 @@ public ActionRequestValidationException validate() {
149148
);
150149
}
151150

151+
// Ensure we have a valid selector in the request
152152
if (rolloverTarget != null) {
153-
ResolvedExpression resolvedExpression = SelectorResolver.parseExpression(rolloverTarget, indicesOptions);
154-
IndexComponentSelector selector = resolvedExpression.selector();
155-
if (IndexComponentSelector.ALL_APPLICABLE.equals(selector)) {
156-
validationException = addValidationError(
157-
"rollover cannot be applied to both regular and failure indices at the same time",
158-
validationException
159-
);
153+
try {
154+
SelectorResolver.parseExpression(rolloverTarget, indicesOptions);
155+
} catch (InvalidIndexNameException exception) {
156+
validationException = addValidationError(exception.getMessage(), validationException);
160157
}
161158
}
162159

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
package org.elasticsearch.action.support;
1111

12+
import org.elasticsearch.TransportVersions;
1213
import org.elasticsearch.common.io.stream.StreamInput;
1314
import org.elasticsearch.common.io.stream.StreamOutput;
1415
import org.elasticsearch.common.io.stream.Writeable;
@@ -23,14 +24,11 @@
2324
* We define as index components the two different sets of indices a data stream could consist of:
2425
* - DATA: represents the backing indices
2526
* - FAILURES: represent the failing indices
26-
* - ALL: represents all available in this expression components, meaning if it's a data stream both backing and failure indices and if it's
27-
* an index only the index itself.
2827
* Note: An index is its own DATA component, but it cannot have a FAILURE component.
2928
*/
3029
public enum IndexComponentSelector implements Writeable {
3130
DATA("data", (byte) 0),
32-
FAILURES("failures", (byte) 1),
33-
ALL_APPLICABLE("*", (byte) 2);
31+
FAILURES("failures", (byte) 1);
3432

3533
private final String key;
3634
private final byte id;
@@ -75,7 +73,13 @@ public static IndexComponentSelector getByKey(String key) {
7573
}
7674

7775
public static IndexComponentSelector read(StreamInput in) throws IOException {
78-
return getById(in.readByte());
76+
byte id = in.readByte();
77+
if (in.getTransportVersion().onOrAfter(TransportVersions.REMOVE_ALL_APPLICABLE_SELECTOR_BACKPORT_8_X)) {
78+
return getById(id);
79+
} else {
80+
// Legacy value ::*, converted to ::data
81+
return id == 2 ? DATA : getById(id);
82+
}
7983
}
8084

8185
// Visible for testing
@@ -95,10 +99,10 @@ public void writeTo(StreamOutput out) throws IOException {
9599
}
96100

97101
public boolean shouldIncludeData() {
98-
return this == ALL_APPLICABLE || this == DATA;
102+
return this == DATA;
99103
}
100104

101105
public boolean shouldIncludeFailures() {
102-
return this == ALL_APPLICABLE || this == FAILURES;
106+
return this == FAILURES;
103107
}
104108
}

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

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ && isIndexVisible(
8181
indexNameExpressionResolver,
8282
includeDataStreams
8383
)) {
84-
// Resolve any ::* suffixes on the expression. We need to resolve them all to their final valid selectors
85-
resolveSelectorsAndCombine(authorizedIndex, selectorString, indicesOptions, resolvedIndices, metadata);
84+
resolveSelectorsAndCollect(authorizedIndex, selectorString, indicesOptions, resolvedIndices, metadata);
8685
}
8786
}
8887
if (resolvedIndices.isEmpty()) {
@@ -98,9 +97,8 @@ && isIndexVisible(
9897
}
9998
}
10099
} else {
101-
// Resolve any ::* suffixes on the expression. We need to resolve them all to their final valid selectors
102100
Set<String> resolvedIndices = new HashSet<>();
103-
resolveSelectorsAndCombine(indexAbstraction, selectorString, indicesOptions, resolvedIndices, metadata);
101+
resolveSelectorsAndCollect(indexAbstraction, selectorString, indicesOptions, resolvedIndices, metadata);
104102
if (minus) {
105103
finalIndices.removeAll(resolvedIndices);
106104
} else if (indicesOptions.ignoreUnavailable() == false || isAuthorized.test(indexAbstraction)) {
@@ -114,7 +112,7 @@ && isIndexVisible(
114112
return finalIndices;
115113
}
116114

117-
private static void resolveSelectorsAndCombine(
115+
private static void resolveSelectorsAndCollect(
118116
String indexAbstraction,
119117
String selectorString,
120118
IndicesOptions indicesOptions,
@@ -132,19 +130,8 @@ private static void resolveSelectorsAndCombine(
132130
selectorString = IndexComponentSelector.DATA.getKey();
133131
}
134132

135-
if (Regex.isMatchAllPattern(selectorString)) {
136-
// Always accept data
137-
collect.add(IndexNameExpressionResolver.combineSelectorExpression(indexAbstraction, IndexComponentSelector.DATA.getKey()));
138-
// Only put failures on the expression if the abstraction supports it.
139-
if (acceptsAllSelectors) {
140-
collect.add(
141-
IndexNameExpressionResolver.combineSelectorExpression(indexAbstraction, IndexComponentSelector.FAILURES.getKey())
142-
);
143-
}
144-
} else {
145-
// A non-wildcard selector is always passed along as-is, it's validity for this kind of abstraction is tested later
146-
collect.add(IndexNameExpressionResolver.combineSelectorExpression(indexAbstraction, selectorString));
147-
}
133+
// A selector is always passed along as-is, it's validity for this kind of abstraction is tested later
134+
collect.add(IndexNameExpressionResolver.combineSelectorExpression(indexAbstraction, selectorString));
148135
} else {
149136
assert selectorString == null
150137
: "A selector string [" + selectorString + "] is present but selectors are disabled in this context";

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

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -364,21 +364,9 @@ protected static Collection<ResolvedExpression> resolveExpressionsToResources(Co
364364
}
365365
} else {
366366
if (isExclusion) {
367-
if (IndexComponentSelector.ALL_APPLICABLE.equals(selector)) {
368-
resources.remove(new ResolvedExpression(baseExpression, IndexComponentSelector.DATA));
369-
resources.remove(new ResolvedExpression(baseExpression, IndexComponentSelector.FAILURES));
370-
} else {
371-
resources.remove(new ResolvedExpression(baseExpression, selector));
372-
}
367+
resources.remove(new ResolvedExpression(baseExpression, selector));
373368
} else if (ensureAliasOrIndexExists(context, baseExpression, selector)) {
374-
if (IndexComponentSelector.ALL_APPLICABLE.equals(selector)) {
375-
resources.add(new ResolvedExpression(baseExpression, IndexComponentSelector.DATA));
376-
if (context.getState().getMetadata().getIndicesLookup().get(baseExpression).isDataStreamRelated()) {
377-
resources.add(new ResolvedExpression(baseExpression, IndexComponentSelector.FAILURES));
378-
}
379-
} else {
380-
resources.add(new ResolvedExpression(baseExpression, selector));
381-
}
369+
resources.add(new ResolvedExpression(baseExpression, selector));
382370
}
383371
}
384372
}
@@ -1046,8 +1034,7 @@ public String[] indexAliases(
10461034

10471035
private static boolean resolvedExpressionsContainsAbstraction(Set<ResolvedExpression> resolvedExpressions, String abstractionName) {
10481036
return resolvedExpressions.contains(new ResolvedExpression(abstractionName))
1049-
|| resolvedExpressions.contains(new ResolvedExpression(abstractionName, IndexComponentSelector.DATA))
1050-
|| resolvedExpressions.contains(new ResolvedExpression(abstractionName, IndexComponentSelector.ALL_APPLICABLE));
1037+
|| resolvedExpressions.contains(new ResolvedExpression(abstractionName, IndexComponentSelector.DATA));
10511038
}
10521039

10531040
/**
@@ -1342,8 +1329,7 @@ private static boolean ensureAliasOrIndexExists(Context context, String name, In
13421329
if (context.options.allowSelectors()) {
13431330
// Ensure that the selectors are present and that they are compatible with the abstractions they are used with
13441331
assert selector != null : "Earlier logic should have parsed selectors or added the default selectors already";
1345-
// Check if ::failures has been explicitly requested, since requesting ::* for non-data-stream abstractions would just
1346-
// return their data components.
1332+
// Check if ::failures has been explicitly requested
13471333
if (IndexComponentSelector.FAILURES.equals(selector) && indexAbstraction.isDataStreamRelated() == false) {
13481334
// If requested abstraction is not data stream related, then you cannot use ::failures
13491335
if (ignoreUnavailable) {
@@ -1700,9 +1686,9 @@ private static Set<ResolvedExpression> expandToOpenClosed(
17001686
final IndexMetadata.State excludeState = excludeState(context.getOptions());
17011687
Set<ResolvedExpression> resources = new HashSet<>();
17021688
if (context.isPreserveAliases() && indexAbstraction.getType() == Type.ALIAS) {
1703-
expandToApplicableSelectors(indexAbstraction, selector, resources);
1689+
resources.add(new ResolvedExpression(indexAbstraction.getName(), selector));
17041690
} else if (context.isPreserveDataStreams() && indexAbstraction.getType() == Type.DATA_STREAM) {
1705-
expandToApplicableSelectors(indexAbstraction, selector, resources);
1691+
resources.add(new ResolvedExpression(indexAbstraction.getName(), selector));
17061692
} else {
17071693
if (shouldIncludeRegularIndices(context.getOptions(), selector)) {
17081694
for (int i = 0, n = indexAbstraction.getIndices().size(); i < n; i++) {
@@ -1729,31 +1715,6 @@ private static Set<ResolvedExpression> expandToOpenClosed(
17291715
return resources;
17301716
}
17311717

1732-
/**
1733-
* Adds the abstraction and selector to the results when preserving data streams and aliases at wildcard resolution. If a selector
1734-
* is provided, the result is only added if the selector is applicable to the abstraction provided. If
1735-
* {@link IndexComponentSelector#ALL_APPLICABLE} is given, the selectors are expanded only to those which are applicable to the
1736-
* provided abstraction.
1737-
* @param indexAbstraction abstraction to add
1738-
* @param selector The selector to add
1739-
* @param resources Result collector which is updated with all applicable resolved expressions for a given abstraction and selector
1740-
* pair.
1741-
*/
1742-
private static void expandToApplicableSelectors(
1743-
IndexAbstraction indexAbstraction,
1744-
IndexComponentSelector selector,
1745-
Set<ResolvedExpression> resources
1746-
) {
1747-
if (IndexComponentSelector.ALL_APPLICABLE.equals(selector)) {
1748-
resources.add(new ResolvedExpression(indexAbstraction.getName(), IndexComponentSelector.DATA));
1749-
if (indexAbstraction.isDataStreamRelated()) {
1750-
resources.add(new ResolvedExpression(indexAbstraction.getName(), IndexComponentSelector.FAILURES));
1751-
}
1752-
} else if (selector == null || indexAbstraction.isDataStreamRelated() || selector.shouldIncludeFailures() == false) {
1753-
resources.add(new ResolvedExpression(indexAbstraction.getName(), selector));
1754-
}
1755-
}
1756-
17571718
private static List<ResolvedExpression> resolveEmptyOrTrivialWildcard(Context context, IndexComponentSelector selector) {
17581719
final String[] allIndices = resolveEmptyOrTrivialWildcardToAllIndices(
17591720
context.getOptions(),
@@ -2150,20 +2111,10 @@ private static <V> V splitSelectorExpression(String expression, BiFunction<Strin
21502111
String suffix = expression.substring(lastDoubleColon + SELECTOR_SEPARATOR.length());
21512112
IndexComponentSelector selector = IndexComponentSelector.getByKey(suffix);
21522113
if (selector == null) {
2153-
// Do some work to surface a helpful error message for likely errors
2154-
if (Regex.isSimpleMatchPattern(suffix)) {
2155-
throw new InvalidIndexNameException(
2156-
expression,
2157-
"Invalid usage of :: separator, ["
2158-
+ suffix
2159-
+ "] contains a wildcard, but only the match all wildcard [*] is supported in a selector"
2160-
);
2161-
} else {
2162-
throw new InvalidIndexNameException(
2163-
expression,
2164-
"Invalid usage of :: separator, [" + suffix + "] is not a recognized selector"
2165-
);
2166-
}
2114+
throw new InvalidIndexNameException(
2115+
expression,
2116+
"invalid usage of :: separator, [" + suffix + "] is not a recognized selector"
2117+
);
21672118
}
21682119
String expressionBase = expression.substring(0, lastDoubleColon);
21692120
ensureNoMoreSelectorSeparators(expressionBase, expression);

server/src/main/java/org/elasticsearch/transport/RemoteClusterAware.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,15 @@ protected Map<String, List<String>> groupClusterIndices(Set<String> remoteCluste
157157
if (indexName.equals("*") == false) {
158158
throw new IllegalArgumentException(
159159
Strings.format(
160-
"To exclude a cluster you must specify the '*' wildcard for " + "the index expression, but found: [%s]",
160+
"To exclude a cluster you must specify the '*' wildcard for the index expression, but found: [%s]",
161161
indexName
162162
)
163163
);
164164
}
165-
if (selectorString != null && selectorString.equals("*") == false) {
165+
if (selectorString != null) {
166166
throw new IllegalArgumentException(
167167
Strings.format(
168-
"To exclude a cluster you must specify the '::*' selector or leave it off, but found: [%s]",
168+
"To exclude a cluster you must not specify the a selector, but found selector: [%s]",
169169
selectorString
170170
)
171171
);

server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public void testValidation() {
256256
assertNotNull(validationException);
257257
assertEquals(1, validationException.validationErrors().size());
258258
assertEquals(
259-
"rollover cannot be applied to both regular and failure indices at the same time",
259+
"Invalid index name [alias-index::*], invalid usage of :: separator, [*] is not a recognized selector",
260260
validationException.validationErrors().get(0)
261261
);
262262
}

server/src/test/java/org/elasticsearch/action/support/IndexComponentSelectorTests.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class IndexComponentSelectorTests extends ESTestCase {
2020
public void testIndexComponentSelectorFromKey() {
2121
assertThat(IndexComponentSelector.getByKey("data"), equalTo(IndexComponentSelector.DATA));
2222
assertThat(IndexComponentSelector.getByKey("failures"), equalTo(IndexComponentSelector.FAILURES));
23-
assertThat(IndexComponentSelector.getByKey("*"), equalTo(IndexComponentSelector.ALL_APPLICABLE));
23+
assertThat(IndexComponentSelector.getByKey("*"), nullValue());
2424
assertThat(IndexComponentSelector.getByKey("d*ta"), nullValue());
2525
assertThat(IndexComponentSelector.getByKey("_all"), nullValue());
2626
assertThat(IndexComponentSelector.getByKey("**"), nullValue());
@@ -30,11 +30,10 @@ public void testIndexComponentSelectorFromKey() {
3030
public void testIndexComponentSelectorFromId() {
3131
assertThat(IndexComponentSelector.getById((byte) 0), equalTo(IndexComponentSelector.DATA));
3232
assertThat(IndexComponentSelector.getById((byte) 1), equalTo(IndexComponentSelector.FAILURES));
33-
assertThat(IndexComponentSelector.getById((byte) 2), equalTo(IndexComponentSelector.ALL_APPLICABLE));
34-
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> IndexComponentSelector.getById((byte) 3));
33+
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> IndexComponentSelector.getById((byte) 2));
3534
assertThat(
3635
exception.getMessage(),
37-
containsString("Unknown id of index component selector [3], available options are: {0=DATA, 1=FAILURES, 2=ALL_APPLICABLE}")
36+
containsString("Unknown id of index component selector [2], available options are: {0=DATA, 1=FAILURES}")
3837
);
3938
}
4039

0 commit comments

Comments
 (0)