47
47
import org .elasticsearch .index .mapper .MapperService ;
48
48
import org .elasticsearch .index .mapper .MapperService .MergeReason ;
49
49
import org .elasticsearch .index .mapper .RoutingFieldMapper ;
50
- import org .elasticsearch .index .shard .IndexLongFieldRange ;
51
50
import org .elasticsearch .indices .IndexTemplateMissingException ;
52
51
import org .elasticsearch .indices .IndicesService ;
53
52
import org .elasticsearch .indices .InvalidIndexTemplateException ;
@@ -173,9 +172,12 @@ private abstract static class TemplateClusterStateUpdateTask implements ClusterS
173
172
}
174
173
175
174
public final ClusterState execute (ClusterState currentState ) throws Exception {
176
- ProjectMetadata metadata = currentState .metadata ().getProject (projectId );
177
- ProjectMetadata newMetadata = execute (metadata );
178
- return metadata == newMetadata ? currentState : ClusterState .builder (currentState ).putProjectMetadata (newMetadata ).build ();
175
+ ProjectMetadata currentProject = currentState .metadata ().getProject (projectId );
176
+ ProjectMetadata newProject = execute (currentProject );
177
+ if (currentProject == newProject ) {
178
+ return currentState ;
179
+ }
180
+ return ClusterState .builder (currentState ).metadata (currentState .metadata ().withUpdatedProject (newProject )).build ();
179
181
}
180
182
181
183
public abstract ProjectMetadata execute (ProjectMetadata currentProject ) throws Exception ;
@@ -384,19 +386,17 @@ public ProjectMetadata addComponentTemplate(
384
386
}
385
387
386
388
validateTemplate (finalSettings , wrappedMappings , indicesService );
387
- validate (name , finalComponentTemplate );
389
+ validate (name , finalComponentTemplate . template (), List . of (), null );
388
390
391
+ ProjectMetadata projectWithComponentTemplateAdded = ProjectMetadata .builder (project ).put (name , finalComponentTemplate ).build ();
389
392
// Validate all composable index templates that use this component template
390
- if (templatesUsingComponent .size () > 0 ) {
391
- ProjectMetadata tempProjectWithComponentTemplateAdded = ProjectMetadata .builder (project )
392
- .put (name , finalComponentTemplate )
393
- .build ();
393
+ if (templatesUsingComponent .isEmpty () == false ) {
394
394
Exception validationFailure = null ;
395
395
for (Map .Entry <String , ComposableIndexTemplate > entry : templatesUsingComponent .entrySet ()) {
396
396
final String composableTemplateName = entry .getKey ();
397
397
final ComposableIndexTemplate composableTemplate = entry .getValue ();
398
398
try {
399
- validateIndexTemplateV2 (tempProjectWithComponentTemplateAdded , composableTemplateName , composableTemplate );
399
+ validateIndexTemplateV2 (projectWithComponentTemplateAdded , composableTemplateName , composableTemplate );
400
400
} catch (Exception e ) {
401
401
if (validationFailure == null ) {
402
402
validationFailure = new IllegalArgumentException (
@@ -426,7 +426,7 @@ public ProjectMetadata addComponentTemplate(
426
426
}
427
427
428
428
logger .info ("{} component template [{}]" , existing == null ? "adding" : "updating" , name );
429
- return ProjectMetadata . builder ( project ). put ( name , finalComponentTemplate ). build () ;
429
+ return projectWithComponentTemplateAdded ;
430
430
}
431
431
432
432
/**
@@ -784,8 +784,9 @@ void validateIndexTemplateV2(ProjectMetadata projectMetadata, String name, Compo
784
784
var finalTemplate = indexTemplate .template ();
785
785
final var now = instantSource .instant ();
786
786
787
- final var combinedMappings = collectMappings (indexTemplate , projectMetadata .componentTemplates (), "tmp_idx" );
788
- final var combinedSettings = resolveSettings (indexTemplate , projectMetadata .componentTemplates ());
787
+ final var componentTemplates = projectMetadata .componentTemplates ();
788
+ final var combinedMappings = collectMappings (indexTemplate , componentTemplates , "tmp_idx" );
789
+ final var combinedSettings = resolveSettings (indexTemplate , componentTemplates );
789
790
var additionalSettingsBuilder = Settings .builder ();
790
791
ImmutableOpenMap .Builder <String , Map <String , String >> customMetadataBuilder = ImmutableOpenMap .builder ();
791
792
for (var provider : indexSettingProviders ) {
@@ -820,11 +821,11 @@ void validateIndexTemplateV2(ProjectMetadata projectMetadata, String name, Compo
820
821
821
822
validate (name , templateToValidate , additionalSettings );
822
823
validateDataStreamsStillReferenced (projectMetadata , name , templateToValidate );
823
- validateLifecycle (projectMetadata , name , templateToValidate , globalRetentionSettings .get (false ));
824
- validateDataStreamOptions (projectMetadata , name , templateToValidate , globalRetentionSettings .get (true ));
824
+ validateLifecycle (componentTemplates , name , templateToValidate , globalRetentionSettings .get (false ));
825
+ validateDataStreamOptions (componentTemplates , name , templateToValidate , globalRetentionSettings .get (true ));
825
826
826
827
if (templateToValidate .isDeprecated () == false ) {
827
- validateUseOfDeprecatedComponentTemplates (name , templateToValidate , projectMetadata . componentTemplates () );
828
+ validateUseOfDeprecatedComponentTemplates (name , templateToValidate , componentTemplates );
828
829
validateUseOfDeprecatedIngestPipelines (name , projectMetadata .custom (IngestMetadata .TYPE ), combinedSettings );
829
830
// TODO come up with a plan how to validate usage of deprecated ILM policies
830
831
// we don't have access to the core/main plugin here so we can't use the IndexLifecycleMetadata type
@@ -900,12 +901,12 @@ private void emitWarningIfPipelineIsDeprecated(String name, Map<String, Pipeline
900
901
901
902
// Visible for testing
902
903
static void validateLifecycle (
903
- ProjectMetadata project ,
904
+ Map < String , ComponentTemplate > componentTemplates ,
904
905
String indexTemplateName ,
905
906
ComposableIndexTemplate template ,
906
907
@ Nullable DataStreamGlobalRetention globalRetention
907
908
) {
908
- DataStreamLifecycle .Builder builder = resolveLifecycle (template , project . componentTemplates () );
909
+ DataStreamLifecycle .Builder builder = resolveLifecycle (template , componentTemplates );
909
910
if (builder != null ) {
910
911
if (template .getDataStreamTemplate () == null ) {
911
912
throw new IllegalArgumentException (
@@ -925,12 +926,12 @@ static void validateLifecycle(
925
926
926
927
// Visible for testing
927
928
static void validateDataStreamOptions (
928
- ProjectMetadata projectMetadata ,
929
+ Map < String , ComponentTemplate > componentTemplates ,
929
930
String indexTemplateName ,
930
931
ComposableIndexTemplate template ,
931
932
DataStreamGlobalRetention globalRetention
932
933
) {
933
- DataStreamOptions .Builder dataStreamOptionsBuilder = resolveDataStreamOptions (template , projectMetadata . componentTemplates () );
934
+ DataStreamOptions .Builder dataStreamOptionsBuilder = resolveDataStreamOptions (template , componentTemplates );
934
935
if (dataStreamOptionsBuilder != null ) {
935
936
if (template .getDataStreamTemplate () == null ) {
936
937
throw new IllegalArgumentException (
@@ -971,18 +972,18 @@ private static void validateDataStreamsStillReferenced(
971
972
.map (Map .Entry ::getKey )
972
973
.collect (Collectors .toSet ());
973
974
974
- Function <ProjectMetadata , Set <String >> findUnreferencedDataStreams = meta -> {
975
+ Function <Map < String , ComposableIndexTemplate >, Set <String >> findUnreferencedDataStreams = composableTemplates -> {
975
976
final Set <String > unreferenced = new HashSet <>();
976
977
// For each data stream that we have, see whether it's covered by a different
977
978
// template (which is great), or whether it's now uncovered by any template
978
979
for (String dataStream : dataStreams ) {
979
- final String matchingTemplate = findV2Template (meta , dataStream , false );
980
+ final String matchingTemplate = findV2Template (project , composableTemplates . entrySet (), dataStream , false , false );
980
981
if (matchingTemplate == null ) {
981
982
unreferenced .add (dataStream );
982
983
} else {
983
984
// We found a template that still matches, great! Buuuuttt... check whether it
984
985
// is a data stream template, as it's only useful if it has a data stream definition
985
- if (meta . templatesV2 () .get (matchingTemplate ).getDataStreamTemplate () == null ) {
986
+ if (composableTemplates .get (matchingTemplate ).getDataStreamTemplate () == null ) {
986
987
unreferenced .add (dataStream );
987
988
}
988
989
}
@@ -991,12 +992,13 @@ private static void validateDataStreamsStillReferenced(
991
992
};
992
993
993
994
// Find data streams that are currently unreferenced
994
- final Set <String > currentlyUnreferenced = findUnreferencedDataStreams .apply (project );
995
+ final Set <String > currentlyUnreferenced = findUnreferencedDataStreams .apply (project . templatesV2 () );
995
996
996
- // Generate a metadata as if the new template were actually in the cluster state
997
- final ProjectMetadata updatedMetadata = ProjectMetadata .builder (project ).put (templateName , newTemplate ).build ();
997
+ // Generate a map as if the new template were actually in the cluster state
998
+ final var updatedTemplatesMap = new HashMap <>(project .templatesV2 ());
999
+ updatedTemplatesMap .put (templateName , newTemplate );
998
1000
// Find the data streams that would be unreferenced now that the template is updated/added
999
- final Set <String > newlyUnreferenced = findUnreferencedDataStreams .apply (updatedMetadata );
1001
+ final Set <String > newlyUnreferenced = findUnreferencedDataStreams .apply (updatedTemplatesMap );
1000
1002
1001
1003
// If we found any data streams that used to be covered, but will no longer be covered by
1002
1004
// changing this template, then blow up with as much helpful information as we can muster
@@ -1226,7 +1228,7 @@ static Set<String> dataStreamsExclusivelyUsingTemplates(final ProjectMetadata pr
1226
1228
return candidates .stream ()
1227
1229
.noneMatch (
1228
1230
template -> templateNames .contains (template .v1 ()) == false
1229
- && isGlobalAndHasIndexHiddenSetting (projectMetadata , template .v2 (), template . v1 ()) == false
1231
+ && isGlobalAndHasIndexHiddenSetting (template .v2 (), projectMetadata . componentTemplates ()) == false
1230
1232
);
1231
1233
})
1232
1234
.map (DataStream ::getName )
@@ -1514,7 +1516,7 @@ private static String findV2Template(
1514
1516
// a restored index cluster state that modified a component template used by this global template such that it has this setting)
1515
1517
// we will fail and the user will have to update the index template and remove this setting or update the corresponding component
1516
1518
// template that contributes to the index template resolved settings
1517
- if (isGlobalAndHasIndexHiddenSetting (projectMetadata , winner , winnerName )) {
1519
+ if (isGlobalAndHasIndexHiddenSetting (winner , projectMetadata . componentTemplates () )) {
1518
1520
throw new IllegalStateException (
1519
1521
"global index template ["
1520
1522
+ winnerName
@@ -1586,12 +1588,11 @@ private static boolean areTemplatesSorted(Collection<Map.Entry<String, Composabl
1586
1588
// Checks if a global template specifies the `index.hidden` setting. This check is important because a global
1587
1589
// template shouldn't specify the `index.hidden` setting, we leave it up to the caller to handle this situation.
1588
1590
private static boolean isGlobalAndHasIndexHiddenSetting (
1589
- ProjectMetadata projectMetadata ,
1590
1591
ComposableIndexTemplate template ,
1591
- String templateName
1592
+ Map < String , ComponentTemplate > componentTemplates
1592
1593
) {
1593
1594
return anyMatch (template .indexPatterns (), Regex ::isMatchAllPattern )
1594
- && IndexMetadata .INDEX_HIDDEN_SETTING .exists (resolveSettings (projectMetadata , templateName ));
1595
+ && IndexMetadata .INDEX_HIDDEN_SETTING .exists (resolveSettings (template , componentTemplates ));
1595
1596
}
1596
1597
1597
1598
/**
@@ -1962,10 +1963,8 @@ private static void validateCompositeTemplate(
1962
1963
final NamedXContentRegistry xContentRegistry ,
1963
1964
final SystemIndices systemIndices
1964
1965
) throws Exception {
1965
- final ProjectMetadata projectMetadataWithTemplate = ProjectMetadata .builder (project ).put (templateName , template ).build ();
1966
-
1967
1966
final String temporaryIndexName = "validate-template-" + UUIDs .randomBase64UUID ().toLowerCase (Locale .ROOT );
1968
- Settings resolvedSettings = resolveSettings (projectMetadataWithTemplate , templateName );
1967
+ Settings resolvedSettings = resolveSettings (template , project . componentTemplates () );
1969
1968
1970
1969
// use the provided values, otherwise just pick valid dummy values
1971
1970
int dummyPartitionSize = IndexMetadata .INDEX_ROUTING_PARTITION_SIZE_SETTING .get (resolvedSettings );
@@ -1985,23 +1984,17 @@ private static void validateCompositeTemplate(
1985
1984
.build ();
1986
1985
1987
1986
// Validate index metadata (settings)
1988
- final ProjectMetadata projectMetadataWithIndex = ProjectMetadata .builder (projectMetadataWithTemplate )
1989
- .put (
1990
- IndexMetadata .builder (temporaryIndexName )
1991
- // necessary to pass asserts in ClusterState constructor
1992
- .eventIngestedRange (IndexLongFieldRange .UNKNOWN )
1993
- .settings (finalResolvedSettings )
1994
- .putCustom (customMetadata )
1995
- )
1987
+ final IndexMetadata tmpIndexMetadata = IndexMetadata .builder (temporaryIndexName )
1988
+ .settings (finalResolvedSettings )
1989
+ .putCustom (customMetadata )
1996
1990
.build ();
1997
- final IndexMetadata tmpIndexMetadata = projectMetadataWithIndex .index (temporaryIndexName );
1998
1991
indicesService .withTempIndexService (tmpIndexMetadata , tempIndexService -> {
1999
1992
// Validate aliases
2000
1993
MetadataCreateIndexService .resolveAndValidateAliases (
2001
1994
temporaryIndexName ,
2002
1995
Collections .emptySet (),
2003
- MetadataIndexTemplateService .resolveAliases (projectMetadataWithIndex , templateName ),
2004
- projectMetadataWithIndex ,
1996
+ MetadataIndexTemplateService .resolveAliases (project , template ),
1997
+ project ,
2005
1998
// the context is only used for validation so it's fine to pass fake values for the
2006
1999
// shard id and the current timestamp
2007
2000
xContentRegistry ,
@@ -2014,7 +2007,7 @@ private static void validateCompositeTemplate(
2014
2007
String indexName = DataStream .BACKING_INDEX_PREFIX + temporaryIndexName ;
2015
2008
// Parse mappings to ensure they are valid after being composed
2016
2009
2017
- List <CompressedXContent > mappings = collectMappings (projectMetadataWithIndex , templateName , indexName );
2010
+ List <CompressedXContent > mappings = collectMappings (template , project . componentTemplates () , indexName );
2018
2011
try {
2019
2012
MapperService mapperService = tempIndexService .mapperService ();
2020
2013
mapperService .merge (MapperService .SINGLE_MAPPING_NAME , mappings , MapperService .MergeReason .INDEX_TEMPLATE );
@@ -2061,10 +2054,6 @@ public static void validateTemplate(Settings validateSettings, CompressedXConten
2061
2054
});
2062
2055
}
2063
2056
2064
- public void validate (String name , ComponentTemplate template ) {
2065
- validate (name , template .template (), Collections .emptyList (), null );
2066
- }
2067
-
2068
2057
private void validate (String name , ComposableIndexTemplate template , @ Nullable Settings systemProvided ) {
2069
2058
validate (name , template .template (), template .indexPatterns (), systemProvided );
2070
2059
}
0 commit comments