33
33
import org .elasticsearch .common .settings .ClusterSettings ;
34
34
import org .elasticsearch .common .settings .Settings ;
35
35
import org .elasticsearch .common .util .concurrent .EsExecutors ;
36
+ import org .elasticsearch .core .Nullable ;
36
37
import org .elasticsearch .core .UpdateForV10 ;
37
38
import org .elasticsearch .index .IndexService ;
38
39
import org .elasticsearch .index .IndexSettingProvider ;
48
49
import org .elasticsearch .transport .TransportService ;
49
50
import org .elasticsearch .xcontent .NamedXContentRegistry ;
50
51
52
+ import java .io .IOException ;
51
53
import java .time .Instant ;
54
+ import java .util .ArrayList ;
52
55
import java .util .HashMap ;
53
56
import java .util .HashSet ;
54
57
import java .util .List ;
@@ -158,7 +161,6 @@ protected void localClusterStateOperation(
158
161
listener .onResponse (new SimulateIndexTemplateResponse (null , null ));
159
162
return ;
160
163
}
161
-
162
164
final ProjectMetadata tempProjectMetadata = resolveTemporaryState (matchingTemplate , request .getIndexName (), projectWithTemplate );
163
165
ComposableIndexTemplate templateV2 = tempProjectMetadata .templatesV2 ().get (matchingTemplate );
164
166
assert templateV2 != null : "the matched template must exist" ;
@@ -167,6 +169,7 @@ protected void localClusterStateOperation(
167
169
matchingTemplate ,
168
170
request .getIndexName (),
169
171
projectWithTemplate ,
172
+ state .metadata ().dataStreams ().get (request .getIndexName ()),
170
173
isDslOnlyMode ,
171
174
xContentRegistry ,
172
175
indicesService ,
@@ -233,44 +236,42 @@ public static ProjectMetadata resolveTemporaryState(
233
236
/**
234
237
* Take a template and index name as well as state where the template exists, and return a final
235
238
* {@link Template} that represents all the resolved Settings, Mappings, Aliases and Lifecycle
239
+ *
240
+ * @param matchingTemplate
241
+ * @param indexName
242
+ * @param simulatedProject
243
+ * @param dataStream Used to get any data stream mapping or settings overrides to merge into the returned template
244
+ * @param isDslOnlyMode
245
+ * @param xContentRegistry
246
+ * @param indicesService
247
+ * @param systemIndices
248
+ * @param indexSettingProviders
249
+ * @return
250
+ * @throws Exception
236
251
*/
237
252
public static Template resolveTemplate (
238
253
final String matchingTemplate ,
239
254
final String indexName ,
240
255
final ProjectMetadata simulatedProject ,
256
+ @ Nullable final DataStream dataStream ,
241
257
final boolean isDslOnlyMode ,
242
258
final NamedXContentRegistry xContentRegistry ,
243
259
final IndicesService indicesService ,
244
260
final SystemIndices systemIndices ,
245
261
Set <IndexSettingProvider > indexSettingProviders
246
262
) throws Exception {
247
- Settings templateSettings = resolveSettings (simulatedProject , matchingTemplate );
248
-
249
263
List <Map <String , AliasMetadata >> resolvedAliases = MetadataIndexTemplateService .resolveAliases (simulatedProject , matchingTemplate );
250
264
251
265
ComposableIndexTemplate template = simulatedProject .templatesV2 ().get (matchingTemplate );
266
+ Settings templateSettings = collectSettings (simulatedProject , dataStream , matchingTemplate , template );
252
267
// create the index with dummy settings in the cluster state so we can parse and validate the aliases
253
268
Settings .Builder dummySettings = Settings .builder ()
254
269
.put (IndexMetadata .SETTING_VERSION_CREATED , IndexVersion .current ())
255
270
.put (IndexMetadata .SETTING_NUMBER_OF_SHARDS , 1 )
256
271
.put (IndexMetadata .SETTING_NUMBER_OF_REPLICAS , 0 )
257
272
.put (IndexMetadata .SETTING_INDEX_UUID , UUIDs .randomBase64UUID ());
258
273
259
- /*
260
- * If the index name doesn't look like a data stream backing index, then MetadataCreateIndexService.collectV2Mappings() won't
261
- * include data stream specific mappings in its response.
262
- */
263
- String simulatedIndexName = template .getDataStreamTemplate () != null
264
- && indexName .startsWith (DataStream .BACKING_INDEX_PREFIX ) == false
265
- ? DataStream .getDefaultBackingIndexName (indexName , 1 )
266
- : indexName ;
267
- List <CompressedXContent > mappings = MetadataCreateIndexService .collectV2Mappings (
268
- null , // empty request mapping as the user can't specify any explicit mappings via the simulate api
269
- simulatedProject ,
270
- template ,
271
- xContentRegistry ,
272
- simulatedIndexName
273
- );
274
+ List <CompressedXContent > mappings = collectMappings (simulatedProject , dataStream , template , indexName , xContentRegistry );
274
275
275
276
// First apply settings sourced from index settings providers
276
277
final var now = Instant .now ();
@@ -360,6 +361,73 @@ public static Template resolveTemplate(
360
361
);
361
362
}
362
363
364
+ /**
365
+ * This method collects the mappings from the given template, pulling them from the given simulatedProject. If the template is a data
366
+ * stream template and the given dataStream is not null, this method also appends any mapping overrides from the data stream itself.
367
+ * @param simulatedProject Used to fetch the component templates referenced from the template
368
+ * @param dataStream Used to fetch any mappings explicitly set on the data stream
369
+ * @param template The template matching the index, used to fetch mappings
370
+ * @param indexName The name of the index whose templates we are fetching
371
+ * @param xContentRegistry Used to parse mappings if necessary
372
+ * @return A list of matching mappings in ascending priority order
373
+ * @throws IOException
374
+ */
375
+ private static List <CompressedXContent > collectMappings (
376
+ ProjectMetadata simulatedProject ,
377
+ @ Nullable DataStream dataStream ,
378
+ ComposableIndexTemplate template ,
379
+ String indexName ,
380
+ NamedXContentRegistry xContentRegistry
381
+ ) throws IOException {
382
+ /*
383
+ * If the index name doesn't look like a data stream backing index, then MetadataCreateIndexService.collectV2Mappings() won't
384
+ * include data stream specific mappings in its response.
385
+ */
386
+ String simulatedIndexName = template .getDataStreamTemplate () != null
387
+ && indexName .startsWith (DataStream .BACKING_INDEX_PREFIX ) == false
388
+ ? DataStream .getDefaultBackingIndexName (indexName , 1 )
389
+ : indexName ;
390
+ List <CompressedXContent > mappings = MetadataCreateIndexService .collectV2Mappings (
391
+ null , // empty request mapping as the user can't specify any explicit mappings via the simulate api
392
+ simulatedProject ,
393
+ template ,
394
+ xContentRegistry , // This is never used since requestMappings is always null, but it is not marked explicitly as @Nullable
395
+ simulatedIndexName
396
+ );
397
+ if (template .getDataStreamTemplate () != null && dataStream != null ) {
398
+ CompressedXContent dataStreamMappingOverrides = dataStream .getMappings ();
399
+ if (ComposableIndexTemplate .EMPTY_MAPPINGS .equals (dataStreamMappingOverrides ) == false ) {
400
+ // The data stream has had mapping overrides applied, so include these
401
+ mappings = new ArrayList <>(mappings );
402
+ mappings .add (dataStreamMappingOverrides );
403
+ }
404
+ }
405
+ return mappings ;
406
+ }
407
+
408
+ /**
409
+ * This method collects the settings from the given template using the given simulatedProjcet. If dataStream is not null, it also merges
410
+ * in any settings overrides on the data stream itself.
411
+ * @param simulatedProject The project metadata used to get the settings
412
+ * @param dataStream If not null, this is used to get data stream settings overrides
413
+ * @param templateName The name of the template
414
+ * @param template The template, used to check whether this is a data strema template
415
+ * @return The settings to be used
416
+ */
417
+ private static Settings collectSettings (
418
+ final ProjectMetadata simulatedProject ,
419
+ @ Nullable final DataStream dataStream ,
420
+ String templateName ,
421
+ ComposableIndexTemplate template
422
+ ) {
423
+ Settings templateSettings = resolveSettings (simulatedProject , templateName );
424
+ if (template .getDataStreamTemplate () != null && dataStream != null ) {
425
+ // The data stream has had settings overrides applied, so include them
426
+ templateSettings = templateSettings .merge (dataStream .getSettings ());
427
+ }
428
+ return templateSettings ;
429
+ }
430
+
363
431
private static IndexLongFieldRange getEventIngestedRange (String indexName , ProjectMetadata simulatedProject ) {
364
432
final IndexMetadata indexMetadata = simulatedProject .index (indexName );
365
433
return indexMetadata == null ? IndexLongFieldRange .NO_SHARDS : indexMetadata .getEventIngestedRange ();
0 commit comments