Skip to content

Commit 008cdd5

Browse files
seanzatzdevelasticsearchmachine
andauthored
Add index mode to resolve index response. (#132858)
* Add index mode to resolve index response. * Add yaml rest test * Update docs/changelog/132858.yaml --------- Co-authored-by: elasticsearchmachine <[email protected]>
1 parent aaeb10f commit 008cdd5

File tree

11 files changed

+252
-30
lines changed

11 files changed

+252
-30
lines changed

docs/changelog/132858.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 132858
2+
summary: Add index mode to resolve index response
3+
area: Indices APIs
4+
type: feature
5+
issues: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
setup:
3+
- do:
4+
indices.delete:
5+
index: my-std-index
6+
ignore_unavailable: true
7+
- do:
8+
indices.delete:
9+
index: my-ts-index
10+
ignore_unavailable: true
11+
12+
# Only run this test if the cluster supports time series indexing.
13+
# If your project uses a different feature flag name, adjust it here.
14+
---
15+
"resolve index returns mode for standard and time_series indices":
16+
- requires:
17+
cluster_features: ["gte_v8.5.0", "resolve_index_returns_mode"]
18+
reason: "Requires time series indexing support introduced in v8.5.0 & Node must support returning 'mode' in indices.resolve_index response"
19+
20+
# Create a standard index
21+
- do:
22+
indices.create:
23+
index: my-std-index
24+
body:
25+
settings:
26+
number_of_shards: 1
27+
number_of_replicas: 0
28+
29+
# Create a time-series index
30+
- do:
31+
indices.create:
32+
index: my-ts-index
33+
body:
34+
settings:
35+
index.mode: time_series
36+
number_of_shards: 1
37+
number_of_replicas: 0
38+
index.routing_path: ["host"]
39+
mappings:
40+
properties:
41+
"@timestamp":
42+
type: date
43+
host:
44+
type: keyword
45+
time_series_dimension: true
46+
metric:
47+
type: keyword
48+
value:
49+
type: double
50+
51+
# Resolve standard index and verify mode
52+
- do:
53+
indices.resolve_index:
54+
name: my-std-index
55+
- match: { indices.0.name: "my-std-index" }
56+
- match: { indices.0.mode: "standard" }
57+
58+
# Resolve time-series index and verify mode
59+
- do:
60+
indices.resolve_index:
61+
name: my-ts-index
62+
- match: { indices.0.name: "my-ts-index" }
63+
- match: { indices.0.mode: "time_series" }
64+
65+
---
66+
teardown:
67+
- do:
68+
indices.delete:
69+
index: my-std-index
70+
ignore_unavailable: true
71+
- do:
72+
indices.delete:
73+
index: my-ts-index
74+
ignore_unavailable: true

server/src/main/java/module-info.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,8 @@
434434
org.elasticsearch.script.ScriptFeatures,
435435
org.elasticsearch.search.retriever.RetrieversFeatures,
436436
org.elasticsearch.action.admin.cluster.stats.ClusterStatsFeatures,
437-
org.elasticsearch.ingest.IngestFeatures;
437+
org.elasticsearch.ingest.IngestFeatures,
438+
org.elasticsearch.action.admin.indices.resolve.ResolveIndexFeatures;
438439

439440
uses org.elasticsearch.plugins.internal.SettingsExtension;
440441
uses RestExtension;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static TransportVersion def(int id) {
365365
public static final TransportVersion SIMULATE_INGEST_MAPPING_MERGE_TYPE = def(9_138_0_00);
366366
public static final TransportVersion ESQL_LOOKUP_JOIN_ON_MANY_FIELDS = def(9_139_0_00);
367367
public static final TransportVersion SIMULATE_INGEST_EFFECTIVE_MAPPING = def(9_140_0_00);
368+
public static final TransportVersion RESOLVE_INDEX_MODE_ADDED = def(9_141_0_00);
368369

369370
/*
370371
* STOP! READ THIS FIRST! No, really,

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

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

1010
package org.elasticsearch.action.admin.indices.resolve;
1111

12+
import org.elasticsearch.TransportVersions;
1213
import org.elasticsearch.action.ActionListener;
1314
import org.elasticsearch.action.ActionRequestValidationException;
1415
import org.elasticsearch.action.ActionResponse;
@@ -39,6 +40,7 @@
3940
import org.elasticsearch.common.util.concurrent.EsExecutors;
4041
import org.elasticsearch.core.Nullable;
4142
import org.elasticsearch.index.Index;
43+
import org.elasticsearch.index.IndexMode;
4244
import org.elasticsearch.injection.guice.Inject;
4345
import org.elasticsearch.search.SearchService;
4446
import org.elasticsearch.tasks.Task;
@@ -176,27 +178,35 @@ public static class ResolvedIndex extends ResolvedIndexAbstraction implements Wr
176178
static final ParseField ALIASES_FIELD = new ParseField("aliases");
177179
static final ParseField ATTRIBUTES_FIELD = new ParseField("attributes");
178180
static final ParseField DATA_STREAM_FIELD = new ParseField("data_stream");
181+
static final ParseField MODE_FIELD = new ParseField("mode");
179182

180183
private final String[] aliases;
181184
private final String[] attributes;
182185
private final String dataStream;
186+
private final IndexMode mode;
183187

184188
ResolvedIndex(StreamInput in) throws IOException {
185189
setName(in.readString());
186190
this.aliases = in.readStringArray();
187191
this.attributes = in.readStringArray();
188192
this.dataStream = in.readOptionalString();
193+
if (in.getTransportVersion().onOrAfter(TransportVersions.RESOLVE_INDEX_MODE_ADDED)) {
194+
this.mode = IndexMode.readFrom(in);
195+
} else {
196+
this.mode = null;
197+
}
189198
}
190199

191-
ResolvedIndex(String name, String[] aliases, String[] attributes, @Nullable String dataStream) {
200+
ResolvedIndex(String name, String[] aliases, String[] attributes, @Nullable String dataStream, IndexMode mode) {
192201
super(name);
193202
this.aliases = aliases;
194203
this.attributes = attributes;
195204
this.dataStream = dataStream;
205+
this.mode = mode;
196206
}
197207

198208
public ResolvedIndex copy(String newName) {
199-
return new ResolvedIndex(newName, aliases, attributes, dataStream);
209+
return new ResolvedIndex(newName, aliases, attributes, dataStream, mode);
200210
}
201211

202212
public String[] getAliases() {
@@ -211,12 +221,19 @@ public String getDataStream() {
211221
return dataStream;
212222
}
213223

224+
public IndexMode getMode() {
225+
return mode;
226+
}
227+
214228
@Override
215229
public void writeTo(StreamOutput out) throws IOException {
216230
out.writeString(getName());
217231
out.writeStringArray(aliases);
218232
out.writeStringArray(attributes);
219233
out.writeOptionalString(dataStream);
234+
if (out.getTransportVersion().onOrAfter(TransportVersions.RESOLVE_INDEX_MODE_ADDED)) {
235+
IndexMode.writeTo(mode, out);
236+
}
220237
}
221238

222239
@Override
@@ -230,6 +247,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
230247
if (Strings.isNullOrEmpty(dataStream) == false) {
231248
builder.field(DATA_STREAM_FIELD.getPreferredName(), dataStream);
232249
}
250+
if (mode != null) {
251+
builder.field(MODE_FIELD.getPreferredName(), mode.toString());
252+
}
233253
builder.endObject();
234254
return builder;
235255
}
@@ -242,12 +262,14 @@ public boolean equals(Object o) {
242262
return getName().equals(index.getName())
243263
&& Objects.equals(dataStream, index.dataStream)
244264
&& Arrays.equals(aliases, index.aliases)
245-
&& Arrays.equals(attributes, index.attributes);
265+
&& Arrays.equals(attributes, index.attributes)
266+
&& Objects.equals(mode, index.mode);
246267
}
247268

248269
@Override
249270
public int hashCode() {
250271
int result = Objects.hash(getName(), dataStream);
272+
result = 31 * result + Objects.hashCode(mode);
251273
result = 31 * result + Arrays.hashCode(aliases);
252274
result = 31 * result + Arrays.hashCode(attributes);
253275
return result;
@@ -639,7 +661,8 @@ private static void enrichIndexAbstraction(
639661
ia.getName(),
640662
aliasNames,
641663
attributes.stream().map(Enum::name).map(e -> e.toLowerCase(Locale.ROOT)).toArray(String[]::new),
642-
ia.getParentDataStream() == null ? null : ia.getParentDataStream().getName()
664+
ia.getParentDataStream() == null ? null : ia.getParentDataStream().getName(),
665+
writeIndex.getIndexMode() == null ? IndexMode.STANDARD : writeIndex.getIndexMode()
643666
)
644667
);
645668
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.action.admin.indices.resolve;
11+
12+
import org.elasticsearch.features.FeatureSpecification;
13+
import org.elasticsearch.features.NodeFeature;
14+
15+
import java.util.Set;
16+
17+
public class ResolveIndexFeatures implements FeatureSpecification {
18+
19+
// Feature published by nodes that return "mode" in indices.resolve_index responses.
20+
public static final NodeFeature RESOLVE_INDEX_RETURNS_MODE = new NodeFeature("resolve_index_returns_mode");
21+
22+
@Override
23+
public Set<NodeFeature> getFeatures() {
24+
return Set.of(RESOLVE_INDEX_RETURNS_MODE);
25+
}
26+
27+
@Override
28+
public Set<NodeFeature> getTestFeatures() {
29+
return Set.of(RESOLVE_INDEX_RETURNS_MODE);
30+
}
31+
32+
}

server/src/main/resources/META-INF/services/org.elasticsearch.features.FeatureSpecification

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ org.elasticsearch.script.ScriptFeatures
2020
org.elasticsearch.cluster.routing.RoutingFeatures
2121
org.elasticsearch.action.admin.cluster.stats.ClusterStatsFeatures
2222
org.elasticsearch.ingest.IngestFeatures
23+
org.elasticsearch.action.admin.indices.resolve.ResolveIndexFeatures

server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexResponseTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.Response;
1616
import org.elasticsearch.common.Strings;
1717
import org.elasticsearch.common.io.stream.Writeable;
18+
import org.elasticsearch.index.IndexMode;
1819
import org.elasticsearch.test.AbstractXContentSerializingTestCase;
1920
import org.elasticsearch.xcontent.ConstructingObjectParser;
2021
import org.elasticsearch.xcontent.XContentParser;
@@ -28,6 +29,7 @@
2829
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.ResolvedIndex.ALIASES_FIELD;
2930
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.ResolvedIndex.ATTRIBUTES_FIELD;
3031
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.ResolvedIndex.DATA_STREAM_FIELD;
32+
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.ResolvedIndex.MODE_FIELD;
3133
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.ResolvedIndexAbstraction.NAME_FIELD;
3234
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.Response.DATA_STREAMS_FIELD;
3335
import static org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction.Response.INDICES_FIELD;
@@ -76,8 +78,9 @@ private static ResolvedIndex createTestResolvedIndexInstance() {
7678
String[] aliases = randomStringArray(0, 5);
7779
String[] attributes = randomSubsetOf(List.of("open", "hidden", "frozen")).toArray(Strings.EMPTY_ARRAY);
7880
String dataStream = randomBoolean() ? randomAlphaOfLength(6) : null;
81+
IndexMode mode = randomFrom(IndexMode.values());
7982

80-
return new ResolvedIndex(name, aliases, attributes, dataStream);
83+
return new ResolvedIndex(name, aliases, attributes, dataStream, mode);
8184
}
8285

8386
private static ResolvedAlias createTestResolvedAliasInstance() {
@@ -109,7 +112,8 @@ static String[] randomStringArray(int minLength, int maxLength) {
109112
(String) args[0],
110113
args[1] != null ? ((List<String>) args[1]).toArray(Strings.EMPTY_ARRAY) : new String[0],
111114
((List<String>) args[2]).toArray(Strings.EMPTY_ARRAY),
112-
(String) args[3]
115+
(String) args[3],
116+
IndexMode.fromString((String) args[4])
113117
)
114118
);
115119
@SuppressWarnings("unchecked")
@@ -133,6 +137,7 @@ static String[] randomStringArray(int minLength, int maxLength) {
133137
INDEX_PARSER.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), ALIASES_FIELD);
134138
INDEX_PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), ATTRIBUTES_FIELD);
135139
INDEX_PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), DATA_STREAM_FIELD);
140+
INDEX_PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), MODE_FIELD);
136141
ALIAS_PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD);
137142
ALIAS_PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), INDICES_FIELD);
138143
RESPONSE_PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> indexFromXContent(p), INDICES_FIELD);

server/src/test/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexTests.java

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.elasticsearch.common.settings.Settings;
3333
import org.elasticsearch.common.time.DateFormatter;
3434
import org.elasticsearch.common.util.concurrent.ThreadContext;
35+
import org.elasticsearch.index.IndexMode;
3536
import org.elasticsearch.index.IndexNotFoundException;
3637
import org.elasticsearch.index.IndexVersion;
3738
import org.elasticsearch.indices.SystemIndexDescriptor;
@@ -68,14 +69,22 @@
6869
public class ResolveIndexTests extends ESTestCase {
6970

7071
private final Object[][] indices = new Object[][] {
71-
// name, isClosed, isHidden, isSystem, isFrozen, dataStream, aliases
72-
{ "logs-pgsql-prod-20200101", false, false, false, true, null, new String[] { "logs-pgsql-prod" } },
73-
{ "logs-pgsql-prod-20200102", false, false, false, true, null, new String[] { "logs-pgsql-prod", "one-off-alias" } },
74-
{ "logs-pgsql-prod-20200103", false, false, false, false, null, new String[] { "logs-pgsql-prod" } },
75-
{ "logs-pgsql-test-20200101", true, false, false, false, null, new String[] { "logs-pgsql-test" } },
76-
{ "logs-pgsql-test-20200102", false, false, false, false, null, new String[] { "logs-pgsql-test" } },
77-
{ "logs-pgsql-test-20200103", false, false, false, false, null, new String[] { "logs-pgsql-test" } },
78-
{ ".test-system-index", false, false, true, false, null, new String[] {} } };
72+
// name, isClosed, isHidden, isSystem, isFrozen, dataStream, aliases, mode
73+
{ "logs-pgsql-prod-20200101", false, false, false, true, null, new String[] { "logs-pgsql-prod" }, IndexMode.STANDARD },
74+
{
75+
"logs-pgsql-prod-20200102",
76+
false,
77+
false,
78+
false,
79+
true,
80+
null,
81+
new String[] { "logs-pgsql-prod", "one-off-alias" },
82+
IndexMode.TIME_SERIES },
83+
{ "logs-pgsql-prod-20200103", false, false, false, false, null, new String[] { "logs-pgsql-prod" }, IndexMode.STANDARD },
84+
{ "logs-pgsql-test-20200101", true, false, false, false, null, new String[] { "logs-pgsql-test" }, IndexMode.STANDARD },
85+
{ "logs-pgsql-test-20200102", false, false, false, false, null, new String[] { "logs-pgsql-test" }, IndexMode.STANDARD },
86+
{ "logs-pgsql-test-20200103", false, false, false, false, null, new String[] { "logs-pgsql-test" }, IndexMode.STANDARD },
87+
{ ".test-system-index", false, false, true, false, null, new String[] {}, IndexMode.STANDARD } };
7988

8089
private final Object[][] dataStreams = new Object[][] {
8190
// name, numBackingIndices
@@ -234,8 +243,8 @@ public void testResolveHiddenProperlyWithDateMath() {
234243
String tomorrowSuffix = dateFormatter.format(now.plus(Duration.ofDays(1L)));
235244
Object[][] indices = new Object[][] {
236245
// name, isClosed, isHidden, isFrozen, dataStream, aliases
237-
{ "logs-pgsql-prod-" + todaySuffix, false, true, false, false, null, Strings.EMPTY_ARRAY },
238-
{ "logs-pgsql-prod-" + tomorrowSuffix, false, true, false, false, null, Strings.EMPTY_ARRAY } };
246+
{ "logs-pgsql-prod-" + todaySuffix, false, true, false, false, null, Strings.EMPTY_ARRAY, IndexMode.STANDARD },
247+
{ "logs-pgsql-prod-" + tomorrowSuffix, false, true, false, false, null, Strings.EMPTY_ARRAY, IndexMode.STANDARD } };
239248
final ProjectMetadata project = buildProjectMetadata(randomProjectIdOrDefault(), new Object[][] {}, indices).build();
240249
String[] requestedIndex = new String[] { "<logs-pgsql-prod-{now/d}>" };
241250
Set<ResolvedExpression> resolvedIndices = resolver.resolveExpressions(
@@ -356,6 +365,7 @@ private void validateIndices(List<ResolvedIndex> resolvedIndices, String... expe
356365
assertThat(resolvedIndex.getAliases(), is(((String[]) indexInfo[6])));
357366
assertThat(resolvedIndex.getAttributes(), is(flagsToAttributes(indexInfo)));
358367
assertThat(resolvedIndex.getDataStream(), equalTo((String) indexInfo[5]));
368+
assertThat(resolvedIndex.getMode().toString(), equalTo(((IndexMode) indexInfo[7]).toString()));
359369
}
360370
}
361371

@@ -444,7 +454,8 @@ private ProjectMetadata.Builder buildProjectMetadata(ProjectId projectId, Object
444454
boolean hidden = (boolean) indexInfo[2];
445455
boolean system = (boolean) indexInfo[3];
446456
boolean frozen = (boolean) indexInfo[4];
447-
allIndices.add(createIndexMetadata(indexName, aliases, closed, hidden, system, frozen));
457+
IndexMode mode = (IndexMode) indexInfo[7];
458+
allIndices.add(createIndexMetadata(indexName, aliases, closed, hidden, system, frozen, mode));
448459
}
449460

450461
for (IndexMetadata index : allIndices) {
@@ -460,12 +471,14 @@ private static IndexMetadata createIndexMetadata(
460471
boolean closed,
461472
boolean hidden,
462473
boolean system,
463-
boolean frozen
474+
boolean frozen,
475+
IndexMode mode
464476
) {
465477
Settings.Builder settingsBuilder = Settings.builder()
466478
.put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())
467479
.put("index.hidden", hidden)
468-
.put("index.frozen", frozen);
480+
.put("index.frozen", frozen)
481+
.put("index.mode", mode.toString());
469482

470483
IndexMetadata.Builder indexBuilder = IndexMetadata.builder(name)
471484
.settings(settingsBuilder)
@@ -482,7 +495,7 @@ private static IndexMetadata createIndexMetadata(
482495
}
483496

484497
private static IndexMetadata createIndexMetadata(String name, boolean hidden) {
485-
return createIndexMetadata(name, Strings.EMPTY_ARRAY, false, true, false, false);
498+
return createIndexMetadata(name, Strings.EMPTY_ARRAY, false, true, false, false, IndexMode.STANDARD);
486499
}
487500

488501
private static Object[] findInfo(Object[][] indexSource, String indexName) {
@@ -507,7 +520,8 @@ private Object[] findBackingIndexInfo(Object[][] dataStreamSource, String indexN
507520
false,
508521
false,
509522
dataStreamName,
510-
Strings.EMPTY_ARRAY };
523+
Strings.EMPTY_ARRAY,
524+
IndexMode.STANDARD };
511525
}
512526
}
513527
}

0 commit comments

Comments
 (0)