Skip to content

Commit 9eddd2b

Browse files
authored
[7.x] Add prefer_v2_templates flag and index setting (#55411) (#55476)
This commit adds a new querystring parameter on the following APIs: - Index - Update - Bulk - Create Index - Rollover These APIs now support a `?prefer_v2_templates=true|false` flag. This flag changes the preference creation to use either V2 index templates or V1 templates. This flag defaults to `false` and will be changed to `true` for 8.0+ in subsequent work. Additionally, setting this flag internally sets the `index.prefer_v2_templates` index-level setting. This setting is used so that actions that automatically create a new index (things like rollover initiated by ILM) will inherit the preference from the original index. This setting is dynamic so that a transition from v1 to v2 templates can occur for long-running indices grouped by an alias performing periodic rollover. This also adds support for sending this parameter to the High Level Rest Client. Relates to #53101
1 parent a0763d9 commit 9eddd2b

37 files changed

+530
-50
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ static Request createIndex(CreateIndexRequest createIndexRequest) throws IOExcep
116116
parameters.withTimeout(createIndexRequest.timeout());
117117
parameters.withMasterTimeout(createIndexRequest.masterNodeTimeout());
118118
parameters.withWaitForActiveShards(createIndexRequest.waitForActiveShards());
119+
if (createIndexRequest.preferV2Templates() != null) {
120+
parameters.putParam(IndexMetadata.PREFER_V2_TEMPLATES_FLAG, Boolean.toString(createIndexRequest.preferV2Templates()));
121+
}
119122
request.addParameters(parameters.asMap());
120123
request.setEntity(RequestConverters.createEntity(createIndexRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE));
121124
return request;

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.elasticsearch.client.security.RefreshPolicy;
5757
import org.elasticsearch.client.tasks.TaskId;
5858
import org.elasticsearch.cluster.health.ClusterHealthStatus;
59+
import org.elasticsearch.cluster.metadata.IndexMetadata;
5960
import org.elasticsearch.common.Nullable;
6061
import org.elasticsearch.common.Priority;
6162
import org.elasticsearch.common.Strings;
@@ -132,6 +133,9 @@ static Request bulk(BulkRequest bulkRequest) throws IOException {
132133
parameters.withRefreshPolicy(bulkRequest.getRefreshPolicy());
133134
parameters.withPipeline(bulkRequest.pipeline());
134135
parameters.withRouting(bulkRequest.routing());
136+
if (bulkRequest.preferV2Templates() != null) {
137+
parameters.putParam(IndexMetadata.PREFER_V2_TEMPLATES_FLAG, Boolean.toString(bulkRequest.preferV2Templates()));
138+
}
135139
// Bulk API only supports newline delimited JSON or Smile. Before executing
136140
// the bulk, we need to check that all requests have the same content-type
137141
// and this content-type is supported by the Bulk API.
@@ -345,6 +349,9 @@ static Request index(IndexRequest indexRequest) {
345349
parameters.withPipeline(indexRequest.getPipeline());
346350
parameters.withRefreshPolicy(indexRequest.getRefreshPolicy());
347351
parameters.withWaitForActiveShards(indexRequest.waitForActiveShards());
352+
if (indexRequest.preferV2Templates() != null) {
353+
parameters.putParam(IndexMetadata.PREFER_V2_TEMPLATES_FLAG, Boolean.toString(indexRequest.preferV2Templates()));
354+
}
348355

349356
BytesRef source = indexRequest.source().toBytesRef();
350357
ContentType contentType = createContentType(indexRequest.getContentType());
@@ -373,6 +380,9 @@ static Request update(UpdateRequest updateRequest) throws IOException {
373380
parameters.withRetryOnConflict(updateRequest.retryOnConflict());
374381
parameters.withVersion(updateRequest.version());
375382
parameters.withVersionType(updateRequest.versionType());
383+
if (updateRequest.preferV2Templates() != null) {
384+
parameters.putParam(IndexMetadata.PREFER_V2_TEMPLATES_FLAG, Boolean.toString(updateRequest.preferV2Templates()));
385+
}
376386

377387
// The Java API allows update requests with different content types
378388
// set for the partial document and the upsert document. This client

client/rest-high-level/src/main/java/org/elasticsearch/client/indices/CreateIndexRequest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.action.support.ActiveShardCount;
2626
import org.elasticsearch.client.TimedRequest;
2727
import org.elasticsearch.client.Validatable;
28+
import org.elasticsearch.common.Nullable;
2829
import org.elasticsearch.common.ParseField;
2930
import org.elasticsearch.common.Strings;
3031
import org.elasticsearch.common.bytes.BytesArray;
@@ -62,6 +63,7 @@ public class CreateIndexRequest extends TimedRequest implements Validatable, ToX
6263

6364
private BytesReference mappings;
6465
private XContentType mappingsXContentType;
66+
private Boolean preferV2Templates;
6567

6668
private final Set<Alias> aliases = new HashSet<>();
6769

@@ -265,6 +267,16 @@ public CreateIndexRequest aliases(Collection<Alias> aliases) {
265267
return this;
266268
}
267269

270+
public CreateIndexRequest preferV2Templates(Boolean preferV2Templates) {
271+
this.preferV2Templates = preferV2Templates;
272+
return this;
273+
}
274+
275+
@Nullable
276+
public Boolean preferV2Templates() {
277+
return this.preferV2Templates;
278+
}
279+
268280
/**
269281
* Sets the settings and mappings as a single source.
270282
*

docs/reference/api-conventions.asciidoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ Returns:
385385
"settings": {
386386
"index.number_of_replicas": "1",
387387
"index.number_of_shards": "1",
388+
"index.prefer_v2_templates": "false",
388389
"index.creation_date": "1474389951325",
389390
"index.uuid": "n6gzFZTgS664GUfx0Xrpjw",
390391
"index.version.created": ...,
@@ -421,7 +422,8 @@ Returns:
421422
"version": {
422423
"created": ...
423424
},
424-
"provided_name" : "twitter"
425+
"provided_name" : "twitter",
426+
"prefer_v2_templates": "false"
425427
}
426428
}
427429
}

rest-api-spec/src/main/resources/rest-api-spec/api/bulk.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@
8787
"pipeline":{
8888
"type":"string",
8989
"description":"The pipeline id to preprocess incoming documents with"
90+
},
91+
"prefer_v2_templates": {
92+
"type": "boolean",
93+
"description": "favor V2 templates instead of V1 templates during automatic index creation"
9094
}
9195
},
9296
"body":{

rest-api-spec/src/main/resources/rest-api-spec/api/create.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
"pipeline":{
9191
"type":"string",
9292
"description":"The pipeline id to preprocess incoming documents with"
93+
},
94+
"prefer_v2_templates": {
95+
"type": "boolean",
96+
"description": "favor V2 templates instead of V1 templates during automatic index creation"
9397
}
9498
},
9599
"body":{

rest-api-spec/src/main/resources/rest-api-spec/api/index.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
"pipeline":{
140140
"type":"string",
141141
"description":"The pipeline id to preprocess incoming documents with"
142+
},
143+
"prefer_v2_templates": {
144+
"type": "boolean",
145+
"description": "favor V2 templates instead of V1 templates during automatic index creation"
142146
}
143147
},
144148
"body":{

rest-api-spec/src/main/resources/rest-api-spec/api/indices.create.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
"master_timeout":{
3838
"type":"time",
3939
"description":"Specify timeout for connection to master"
40+
},
41+
"prefer_v2_templates": {
42+
"type": "boolean",
43+
"description": "favor V2 templates instead of V1 templates during index creation"
4044
}
4145
},
4246
"body":{

rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@
5757
"wait_for_active_shards":{
5858
"type":"string",
5959
"description":"Set the number of active shards to wait for on the newly created rollover index before the operation returns."
60+
},
61+
"prefer_v2_templates": {
62+
"type": "boolean",
63+
"description": "favor V2 templates instead of V1 templates during automatic index creation"
6064
}
6165
},
6266
"body":{

rest-api-spec/src/main/resources/rest-api-spec/api/update.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
"if_primary_term":{
100100
"type":"number",
101101
"description":"only perform the update operation if the last operation that has changed the document has the specified primary term"
102+
},
103+
"prefer_v2_templates": {
104+
"type": "boolean",
105+
"description": "favor V2 templates instead of V1 templates during automatic index creation"
102106
}
103107
},
104108
"body":{

rest-api-spec/src/main/resources/rest-api-spec/test/indices.put_index_template/15_composition.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
- do:
6262
indices.create:
6363
index: bar-baz
64+
prefer_v2_templates: true
6465
body:
6566
settings:
6667
index.priority: 17
@@ -120,6 +121,7 @@
120121

121122
- do:
122123
indices.create:
124+
prefer_v2_templates: true
123125
index: bar-baz
124126

125127
- do:
@@ -164,6 +166,7 @@
164166

165167
- do:
166168
indices.create:
169+
prefer_v2_templates: true
167170
index: bazfoo
168171

169172
- do:
@@ -193,10 +196,40 @@
193196

194197
- do:
195198
indices.create:
199+
prefer_v2_templates: true
196200
index: eggplant
197201

198202
- do:
199203
indices.get:
200204
index: eggplant
201205

202206
- match: {eggplant.settings.index.number_of_shards: "3"}
207+
208+
---
209+
"Version 1 templates are preferred if the flag is set":
210+
- skip:
211+
version: " - 7.7.99"
212+
reason: "index template v2 API unavailable before 7.8"
213+
features: allowed_warnings
214+
215+
- do:
216+
allowed_warnings:
217+
- "index template [my-template] has index patterns [eggplant] matching patterns from existing older templates [global] with patterns (global => [*]); this template [my-template] will take precedence during new index creation"
218+
indices.put_index_template:
219+
name: my-template
220+
body:
221+
index_patterns: ["eggplant"]
222+
template:
223+
settings:
224+
number_of_replicas: 2
225+
226+
- do:
227+
indices.create:
228+
prefer_v2_templates: false
229+
index: eggplant
230+
231+
- do:
232+
indices.get:
233+
index: eggplant
234+
235+
- match: {eggplant.settings.index.number_of_replicas: "1"}

server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexClusterStateUpdateRequest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.elasticsearch.cluster.ack.ClusterStateUpdateRequest;
2626
import org.elasticsearch.cluster.block.ClusterBlock;
2727
import org.elasticsearch.cluster.metadata.IndexMetadata;
28+
import org.elasticsearch.common.Nullable;
2829
import org.elasticsearch.common.settings.Settings;
2930
import org.elasticsearch.index.Index;
3031

@@ -44,6 +45,7 @@ public class CreateIndexClusterStateUpdateRequest extends ClusterStateUpdateRequ
4445
private Index recoverFrom;
4546
private ResizeType resizeType;
4647
private boolean copySettings;
48+
private Boolean preferV2Templates;
4749

4850
private Settings settings = Settings.Builder.EMPTY_SETTINGS;
4951

@@ -96,6 +98,11 @@ public CreateIndexClusterStateUpdateRequest copySettings(final boolean copySetti
9698
return this;
9799
}
98100

101+
public CreateIndexClusterStateUpdateRequest preferV2Templates(@Nullable Boolean preferV2Templates) {
102+
this.preferV2Templates = preferV2Templates;
103+
return this;
104+
}
105+
99106
public String cause() {
100107
return cause;
101108
}
@@ -147,4 +154,8 @@ public boolean copySettings() {
147154
return copySettings;
148155
}
149156

157+
@Nullable
158+
public Boolean preferV2Templates() {
159+
return preferV2Templates;
160+
}
150161
}

server/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.action.support.ActiveShardCount;
3030
import org.elasticsearch.action.support.IndicesOptions;
3131
import org.elasticsearch.action.support.master.AcknowledgedRequest;
32+
import org.elasticsearch.common.Nullable;
3233
import org.elasticsearch.common.ParseField;
3334
import org.elasticsearch.common.Strings;
3435
import org.elasticsearch.common.bytes.BytesArray;
@@ -83,6 +84,8 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
8384

8485
private final Map<String, String> mappings = new HashMap<>();
8586

87+
private Boolean preferV2Templates;
88+
8689
private final Set<Alias> aliases = new HashSet<>();
8790

8891
private ActiveShardCount waitForActiveShards = ActiveShardCount.DEFAULT;
@@ -118,6 +121,9 @@ public CreateIndexRequest(StreamInput in) throws IOException {
118121
in.readBoolean(); // updateAllTypes
119122
}
120123
waitForActiveShards = ActiveShardCount.readFrom(in);
124+
if (in.getVersion().onOrAfter(Version.V_7_8_0)) {
125+
preferV2Templates = in.readOptionalBoolean();
126+
}
121127
}
122128

123129
public CreateIndexRequest() {
@@ -169,6 +175,16 @@ public CreateIndexRequest index(String index) {
169175
return this;
170176
}
171177

178+
public CreateIndexRequest preferV2Templates(@Nullable Boolean preferV2Templates) {
179+
this.preferV2Templates = preferV2Templates;
180+
return this;
181+
}
182+
183+
@Nullable
184+
public Boolean preferV2Templates() {
185+
return this.preferV2Templates;
186+
}
187+
172188
/**
173189
* The settings to create the index with.
174190
*/
@@ -459,7 +475,7 @@ public CreateIndexRequest waitForActiveShards(ActiveShardCount waitForActiveShar
459475
public CreateIndexRequest waitForActiveShards(final int waitForActiveShards) {
460476
return waitForActiveShards(ActiveShardCount.from(waitForActiveShards));
461477
}
462-
478+
463479
@Override
464480
public void writeTo(StreamOutput out) throws IOException {
465481
super.writeTo(out);
@@ -483,6 +499,9 @@ public void writeTo(StreamOutput out) throws IOException {
483499
out.writeBoolean(true); // updateAllTypes
484500
}
485501
waitForActiveShards.writeTo(out);
502+
if (out.getVersion().onOrAfter(Version.V_7_8_0)) {
503+
out.writeOptionalBoolean(preferV2Templates);
504+
}
486505
}
487506

488507
@Override

server/src/main/java/org/elasticsearch/action/admin/indices/create/TransportCreateIndexAction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ protected void masterOperation(final CreateIndexRequest request, final ClusterSt
8181
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
8282
.settings(request.settings()).mappings(request.mappings())
8383
.aliases(request.aliases())
84+
.preferV2Templates(request.preferV2Templates())
8485
.waitForActiveShards(request.waitForActiveShards());
8586

8687
createIndexService.createIndex(updateRequest, ActionListener.map(listener, response ->

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ static CreateIndexClusterStateUpdateRequest prepareCreateIndexRequest(final Stri
140140
.settings(createIndexRequest.settings())
141141
.aliases(createIndexRequest.aliases())
142142
.waitForActiveShards(ActiveShardCount.NONE) // not waiting for shards here, will wait on the alias switch operation
143-
.mappings(createIndexRequest.mappings());
143+
.mappings(createIndexRequest.mappings())
144+
.preferV2Templates(createIndexRequest.preferV2Templates());
144145
}
145146

146147
/**

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.elasticsearch.common.Nullable;
4141
import org.elasticsearch.common.inject.Inject;
4242
import org.elasticsearch.common.io.stream.StreamInput;
43+
import org.elasticsearch.common.settings.Settings;
4344
import org.elasticsearch.common.unit.ByteSizeValue;
4445
import org.elasticsearch.index.shard.DocsStats;
4546
import org.elasticsearch.tasks.Task;
@@ -133,6 +134,13 @@ public void onResponse(IndicesStatsResponse statsResponse) {
133134
+ rolloverIndexName + "]", new ClusterStateUpdateTask() {
134135
@Override
135136
public ClusterState execute(ClusterState currentState) throws Exception {
137+
// If they haven't explicitly specified whether to use V2 or V1 templates, inherit their preference
138+
// from the existing index (the source index) settings.
139+
if (rolloverRequest.getCreateIndexRequest().preferV2Templates() == null) {
140+
Settings originalIndexSettings = currentState.metadata().index(sourceIndexName).getSettings();
141+
rolloverRequest.getCreateIndexRequest()
142+
.preferV2Templates(IndexMetadata.PREFER_V2_TEMPLATES_SETTING.get(originalIndexSettings));
143+
}
136144
MetadataRolloverService.RolloverResult rolloverResult = rolloverService.rolloverClusterState(currentState,
137145
rolloverRequest.getAlias(), rolloverRequest.getNewIndexName(), rolloverRequest.getCreateIndexRequest(),
138146
metConditions, false);

0 commit comments

Comments
 (0)