浏览代码

GA the data stream lifecycle (#98644)

This makes the data stream lifecycle generally available. This will allow
data streams to take advantage of a native simplified and resilient
lifecycle implementation.
Andrei Dan 2 年之前
父节点
当前提交
01ed7de99f
共有 53 个文件被更改,包括 84 次插入243 次删除
  1. 0 4
      docs/build.gradle
  2. 20 0
      docs/changelog/98644.yaml
  3. 0 10
      docs/reference/data-management.asciidoc
  4. 4 8
      docs/reference/data-streams/data-stream-apis.asciidoc
  5. 0 2
      docs/reference/data-streams/lifecycle/apis/delete-lifecycle.asciidoc
  6. 0 2
      docs/reference/data-streams/lifecycle/apis/explain-lifecycle.asciidoc
  7. 0 2
      docs/reference/data-streams/lifecycle/apis/get-lifecycle.asciidoc
  8. 0 2
      docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc
  9. 0 4
      docs/reference/data-streams/lifecycle/index.asciidoc
  10. 0 2
      docs/reference/data-streams/lifecycle/tutorial-manage-existing-data-stream.asciidoc
  11. 0 2
      docs/reference/data-streams/lifecycle/tutorial-manage-new-data-stream.asciidoc
  12. 0 24
      docs/reference/redirects.asciidoc
  13. 0 2
      docs/reference/settings/data-stream-lifecycle-settings.asciidoc
  14. 0 2
      docs/reference/setup.asciidoc
  15. 0 17
      modules/data-streams/build.gradle
  16. 0 2
      modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DisabledSecurityDataStreamTestCase.java
  17. 0 2
      modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecyclePermissionsRestIT.java
  18. 26 39
      modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java
  19. 1 3
      modules/data-streams/src/main/java/org/elasticsearch/datastreams/action/GetDataStreamsTransportAction.java
  20. 1 3
      modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/TransportExplainDataStreamLifecycleAction.java
  21. 1 3
      modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/TransportGetDataStreamLifecycleAction.java
  22. 1 4
      modules/data-streams/src/main/java/org/elasticsearch/datastreams/rest/RestGetDataStreamsAction.java
  23. 0 1
      qa/mixed-cluster/build.gradle
  24. 0 1
      qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java
  25. 1 1
      rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete_data_lifecycle.json
  26. 1 1
      rest-api-spec/src/main/resources/rest-api-spec/api/indices.explain_data_lifecycle.json
  27. 1 1
      rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_data_lifecycle.json
  28. 2 3
      rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_data_lifecycle.json
  29. 0 1
      rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java
  30. 0 2
      server/build.gradle
  31. 1 1
      server/src/main/java/org/elasticsearch/action/admin/indices/template/get/TransportGetComponentTemplateAction.java
  32. 1 1
      server/src/main/java/org/elasticsearch/action/admin/indices/template/get/TransportGetComposableIndexTemplateAction.java
  33. 2 2
      server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java
  34. 1 1
      server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateTemplateAction.java
  35. 3 9
      server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java
  36. 0 7
      server/src/main/java/org/elasticsearch/cluster/metadata/DataStreamLifecycle.java
  37. 1 1
      server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateDataStreamService.java
  38. 3 19
      server/src/main/java/org/elasticsearch/cluster/metadata/Template.java
  39. 1 1
      server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
  40. 1 4
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComponentTemplateAction.java
  41. 1 4
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComposableIndexTemplateAction.java
  42. 1 4
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestSimulateIndexTemplateAction.java
  43. 1 4
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestSimulateTemplateAction.java
  44. 1 2
      test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java
  45. 2 2
      x-pack/docs/en/security/authentication/internal-users.asciidoc
  46. 0 1
      x-pack/plugin/build.gradle
  47. 0 6
      x-pack/plugin/core/build.gradle
  48. 0 5
      x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/DataStreamLifecycleUsageTransportAction.java
  49. 1 2
      x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java
  50. 0 2
      x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java
  51. 0 8
      x-pack/plugin/ilm/build.gradle
  52. 4 6
      x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java
  53. 0 1
      x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java

+ 0 - 4
docs/build.gradle

@@ -100,7 +100,6 @@ testClusters.matching { it.name == "yamlRestTest"}.configureEach {
   systemProperty 'es.transport.cname_in_publish_address', 'true'
 
   requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
-  requiresFeature 'es.dlm_feature_flag_enabled', Version.fromString("8.8.0")
 
   // build the cluster with all plugins
   project.rootProject.subprojects.findAll { it.parent.path == ':plugins' }.each { subproj ->
@@ -122,9 +121,6 @@ tasks.named("yamlRestTest").configure {
   doFirst {
     delete("${buildDir}/cluster/shared/repo")
   }
-  if (BuildParams.isSnapshotBuild() == false) {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
 }
 
 tasks.named("forbiddenPatterns").configure {

+ 20 - 0
docs/changelog/98644.yaml

@@ -0,0 +1,20 @@
+pr: 98644
+summary: GA the data stream lifecycle
+area: Data streams
+type: feature
+issues: []
+highlight:
+  title: The data stream lifecycle is now generally available
+  body: |-
+    This makes the data stream lifecycle generaly available. Data streams will 
+    be able to take advantage of a built-in simplified and resilient
+    lifecycle implementation. Data streams with a configured lifecycle will
+    be automatically rolled over and tail merged (a forcemerge implementation 
+    that's lightweight and only merges the long tail of small segments instead 
+    of the whole shard). With the shard and index maintenance tasks being 
+    handled automatically to ensure optimum performance, and trade-off between
+    indexing and searching, you'll be able to focus on the business related 
+    lifecycle aspects like data retention. The automatic maintenance tasks will
+    automatically be available for any new data stream that's not managed by 
+    ILM.
+  notable: true

+ 0 - 10
docs/reference/data-management.asciidoc

@@ -20,20 +20,12 @@ so you can move it to less expensive, less performant hardware.
 For your oldest data, what matters is that you have access to the data. 
 It's ok if queries take longer to complete.
 
-ifeval::["{release-state}"=="unreleased"]
 To help you manage your data, {es} offers you:
 
 * <<index-lifecycle-management, {ilm-cap}>> ({ilm-init}) to manage both indices and data streams and it is fully customisable, and
 * <<data-stream-lifecycle, Data stream lifecycle>> which is the built-in lifecycle of data streams and addresses the most
 common lifecycle management needs.
 
-preview::["The built-in data stream lifecycle is in technical preview and may be changed or removed in a future release. Elastic will apply best effort to fix any issues, but this feature is not subject to the support SLA of official GA features."]
-endif::[]
-ifeval::["{release-state}"=="released"]
-To help you manage your data, {es} offers you <<index-lifecycle-management, {ilm-cap}>> ({ilm-init}) to manage both indices and data
-streams and it is fully customisable.
-endif::[]
-
 **{ilm-init}** can be used to manage both indices and data streams and it allows you to:
 
 * Define the retention period of your data. The retention period is the minimum time your data will be stored in {es}.
@@ -44,14 +36,12 @@ Data older than this period can be deleted by {es}.
 for your older indices while reducing operating costs and maintaining search performance.  
 * Perform <<async-search-intro, asynchronous searches>> of data stored on less-performant hardware.
 
-ifeval::["{release-state}"=="unreleased"]
 **Data stream lifecycle** is less feature rich but is focused on simplicity, so it allows you to easily:
 
 * Define the retention period of your data. The retention period is the minimum time your data will be stored in {es}.
 Data older than this period can be deleted by {es} at a later time.
 * Improve the performance of your data stream by performing background operations that will optimise the way your data
 stream is stored.
-endif::[]
 --
 
 include::ilm/index.asciidoc[]

+ 4 - 8
docs/reference/data-streams/data-stream-apis.asciidoc

@@ -12,15 +12,13 @@ The following APIs are available for managing <<data-streams,data streams>>:
 * <<promote-data-stream-api>>
 * <<modify-data-streams-api>>
 
-ifeval::["{release-state}"=="unreleased"]
 [[data-stream-lifecycle-api]]
 The following APIs are available for managing the built-in lifecycle of data streams:
 
-* <<data-streams-put-lifecycle,Update data stream lifecycle>> preview:[]
-* <<data-streams-get-lifecycle,Get data stream lifecycle>> preview:[]
-* <<data-streams-delete-lifecycle,Delete data stream lifecycle>> preview:[]
-* <<data-streams-explain-lifecycle,Explain data stream lifecycle>> preview:[]
-endif::[]
+* <<data-streams-put-lifecycle,Update data stream lifecycle>> 
+* <<data-streams-get-lifecycle,Get data stream lifecycle>> 
+* <<data-streams-delete-lifecycle,Delete data stream lifecycle>>
+* <<data-streams-explain-lifecycle,Explain data stream lifecycle>>
 
 The following API is available for <<tsds,time series data streams>>:
 
@@ -43,7 +41,6 @@ include::{es-repo-dir}/data-streams/promote-data-stream-api.asciidoc[]
 
 include::{es-repo-dir}/data-streams/modify-data-streams-api.asciidoc[]
 
-ifeval::["{release-state}"=="unreleased"]
 include::{es-repo-dir}/data-streams/lifecycle/apis/put-lifecycle.asciidoc[]
 
 include::{es-repo-dir}/data-streams/lifecycle/apis/get-lifecycle.asciidoc[]
@@ -51,6 +48,5 @@ include::{es-repo-dir}/data-streams/lifecycle/apis/get-lifecycle.asciidoc[]
 include::{es-repo-dir}/data-streams/lifecycle/apis/delete-lifecycle.asciidoc[]
 
 include::{es-repo-dir}/data-streams/lifecycle/apis/explain-lifecycle.asciidoc[]
-endif::[]
 
 include::{es-repo-dir}/indices/downsample-data-stream.asciidoc[]

+ 0 - 2
docs/reference/data-streams/lifecycle/apis/delete-lifecycle.asciidoc

@@ -4,8 +4,6 @@
 <titleabbrev>Delete Data Stream Lifecycle</titleabbrev>
 ++++
 
-preview::[]
-
 Deletes the lifecycle from a set of data streams.
 
 [[delete-lifecycle-api-prereqs]]

+ 0 - 2
docs/reference/data-streams/lifecycle/apis/explain-lifecycle.asciidoc

@@ -4,8 +4,6 @@
 <titleabbrev>Explain Data Stream Lifecycle</titleabbrev>
 ++++
 
-preview::[]
-
 Retrieves the current data stream lifecycle status for one or more data stream backing indices.
 
 [[explain-lifecycle-api-prereqs]]

+ 0 - 2
docs/reference/data-streams/lifecycle/apis/get-lifecycle.asciidoc

@@ -4,8 +4,6 @@
 <titleabbrev>Get Data Stream Lifecycle</titleabbrev>
 ++++
 
-preview::[]
-
 Gets the lifecycle of a set of data streams.
 
 [[get-lifecycle-api-prereqs]]

+ 0 - 2
docs/reference/data-streams/lifecycle/apis/put-lifecycle.asciidoc

@@ -4,8 +4,6 @@
 <titleabbrev>Put Data Stream Lifecycle</titleabbrev>
 ++++
 
-preview::[]
-
 Configures the data stream lifecycle for the targeted data streams.
 
 [[put-lifecycle-api-prereqs]]

+ 0 - 4
docs/reference/data-streams/lifecycle/index.asciidoc

@@ -1,10 +1,7 @@
 [role="xpack"]
 [[data-stream-lifecycle]]
-ifeval::["{release-state}"=="unreleased"]
 == Data stream lifecycle
 
-preview::[]
-
 A data stream lifecycle is the built-in mechanism data streams use to manage their lifecycle. It enables you to easily
 automate the management of your data streams according to your retention requirements. For example, you could configure
 the lifecycle to:
@@ -63,4 +60,3 @@ because it is applied on the data stream level and not on the individual backing
 include::tutorial-manage-new-data-stream.asciidoc[]
 
 include::tutorial-manage-existing-data-stream.asciidoc[]
-endif::[]

+ 0 - 2
docs/reference/data-streams/lifecycle/tutorial-manage-existing-data-stream.asciidoc

@@ -2,8 +2,6 @@
 [[tutorial-manage-existing-data-stream]]
 === Tutorial: Update existing data stream
 
-preview::[]
-
 To update the lifecycle of an existing data stream you do the following actions:
 
 . <<set-lifecycle>>

+ 0 - 2
docs/reference/data-streams/lifecycle/tutorial-manage-new-data-stream.asciidoc

@@ -2,8 +2,6 @@
 [[tutorial-manage-new-data-stream]]
 === Tutorial: Create a data stream with a lifecycle
 
-preview::[]
-
 To create a data stream with a built-in lifecycle, follow these steps:
 
 . <<create-index-template-with-lifecycle>>

+ 0 - 24
docs/reference/redirects.asciidoc

@@ -1885,47 +1885,23 @@ Refer to <<fix-watermark-errors>>.
 [role="exclude",id="dlm-delete-lifecycle"]
 === Delete the lifecycle of a data stream
 
-ifeval::["{release-state}"=="unreleased"]
 Refer to <<data-streams-delete-lifecycle,Delete data stream lifecycle API>>.
 
-endif::[]
-ifeval::["{release-state}"=="unreleased"]
-This feature has not been released yet
-endif::[]
-
 [role="exclude",id="dlm-explain-lifecycle"]
 === Explain the lifecycle of a data stream
 
-ifeval::["{release-state}"=="unreleased"]
 Refer to <<data-streams-explain-lifecycle,Explain data stream lifecycle API>>.
 
-endif::[]
-ifeval::["{release-state}"=="unreleased"]
-This feature has not been released yet
-endif::[]
-
 [role="exclude",id="dlm-get-lifecycle"]
 === Get the lifecycle of a data stream
 
-ifeval::["{release-state}"=="unreleased"]
 Refer to <<data-streams-get-lifecycle,Get data stream lifecycle API>>.
 
-endif::[]
-ifeval::["{release-state}"=="unreleased"]
-This feature has not been released yet
-endif::[]
-
 [role="exclude",id="dlm-put-lifecycle"]
 === Update the lifecycle of a data stream
 
-ifeval::["{release-state}"=="unreleased"]
 Refer to <<data-streams-delete-lifecycle,Update data stream lifecycle API>>.
 
-endif::[]
-ifeval::["{release-state}"=="unreleased"]
-This feature has not been released yet
-endif::[]
-
 [role="exclude",id="get-synonyms"]
 === Get synonyms set API
 

+ 0 - 2
docs/reference/settings/data-stream-lifecycle-settings.asciidoc

@@ -1,6 +1,5 @@
 [role="xpack"]
 [[data-stream-lifecycle-settings]]
-ifeval::["{release-state}"=="unreleased"]
 === Data stream lifecycle settings in {es}
 [subs="attributes"]
 ++++
@@ -50,4 +49,3 @@ If specified, this is the timestamp used to calculate the backing index generati
 setting if you create a backing index that contains older data and want to ensure that the retention period or
 other parts of the lifecycle will be applied based on the data's original timestamp and not the timestamp they got
 indexed. Specified as a Unix epoch value in milliseconds.
-endif::[]

+ 0 - 2
docs/reference/setup.asciidoc

@@ -54,9 +54,7 @@ include::settings/health-diagnostic-settings.asciidoc[]
 
 include::settings/ilm-settings.asciidoc[]
 
-ifeval::["{release-state}"=="unreleased"]
 include::settings/data-stream-lifecycle-settings.asciidoc[]
-endif::[]
 
 include::modules/indices/index_management.asciidoc[]
 

+ 0 - 17
modules/data-streams/build.gradle

@@ -1,4 +1,3 @@
-import org.elasticsearch.gradle.Version
 import org.elasticsearch.gradle.internal.info.BuildParams
 
 apply plugin: 'elasticsearch.test-with-dependencies'
@@ -31,7 +30,6 @@ testClusters.configureEach {
   setting 'xpack.security.enabled', 'true'
   keystore 'bootstrap.password', 'x-pack-test-password'
   user username: "x_pack_rest_user", password: "x-pack-test-password"
-  requiresFeature 'es.dlm_feature_flag_enabled', Version.fromString("8.8.0")
 }
 
 tasks.named('javaRestTest') {
@@ -51,18 +49,3 @@ if (BuildParams.inFipsJvm){
   tasks.named("javaRestTest").configure{enabled = false }
   tasks.named("yamlRestTest").configure{enabled = false }
 }
-
-if (BuildParams.isSnapshotBuild() == false) {
-  tasks.named("test").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-  tasks.named("internalClusterTest").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-  tasks.named("yamlRestTest").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-  tasks.named("javaRestTest").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-}

+ 0 - 2
modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DisabledSecurityDataStreamTestCase.java

@@ -12,7 +12,6 @@ import org.elasticsearch.common.settings.SecureString;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
 import org.elasticsearch.test.cluster.ElasticsearchCluster;
-import org.elasticsearch.test.cluster.FeatureFlag;
 import org.elasticsearch.test.cluster.local.distribution.DistributionType;
 import org.elasticsearch.test.rest.ESRestTestCase;
 import org.junit.ClassRule;
@@ -25,7 +24,6 @@ public abstract class DisabledSecurityDataStreamTestCase extends ESRestTestCase
 
     @ClassRule
     public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
-        .feature(FeatureFlag.DATA_STREAM_LIFECYCLE_ENABLED)
         .distribution(DistributionType.DEFAULT)
         .setting("xpack.security.enabled", "false")
         .setting("xpack.watcher.enabled", "false")

+ 0 - 2
modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/lifecycle/DataStreamLifecyclePermissionsRestIT.java

@@ -20,7 +20,6 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
 import org.elasticsearch.core.PathUtils;
 import org.elasticsearch.rest.RestStatus;
 import org.elasticsearch.test.cluster.ElasticsearchCluster;
-import org.elasticsearch.test.cluster.FeatureFlag;
 import org.elasticsearch.test.cluster.local.distribution.DistributionType;
 import org.elasticsearch.test.cluster.util.resource.Resource;
 import org.elasticsearch.test.rest.ESRestTestCase;
@@ -54,7 +53,6 @@ public class DataStreamLifecyclePermissionsRestIT extends ESRestTestCase {
 
     @ClassRule
     public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
-        .feature(FeatureFlag.DATA_STREAM_LIFECYCLE_ENABLED)
         .distribution(DistributionType.DEFAULT)
         .setting("xpack.watcher.enabled", "false")
         .setting("xpack.ml.enabled", "false")

+ 26 - 39
modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java

@@ -20,7 +20,6 @@ import org.elasticsearch.action.datastreams.ModifyDataStreamsAction;
 import org.elasticsearch.action.datastreams.PromoteDataStreamAction;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.client.internal.OriginSettingClient;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
 import org.elasticsearch.cluster.routing.allocation.AllocationService;
@@ -140,12 +139,9 @@ public class DataStreamsPlugin extends Plugin implements ActionPlugin {
         List<Setting<?>> pluginSettings = new ArrayList<>();
         pluginSettings.add(TIME_SERIES_POLL_INTERVAL);
         pluginSettings.add(LOOK_AHEAD_TIME);
-
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_LIFECYCLE_POLL_INTERVAL_SETTING);
-            pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FLOOR_SEGMENT_SETTING);
-            pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FACTOR_SETTING);
-        }
+        pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_LIFECYCLE_POLL_INTERVAL_SETTING);
+        pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FLOOR_SEGMENT_SETTING);
+        pluginSettings.add(DataStreamLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FACTOR_SETTING);
         return pluginSettings;
     }
 
@@ -171,24 +167,21 @@ public class DataStreamsPlugin extends Plugin implements ActionPlugin {
         var updateTimeSeriesRangeService = new UpdateTimeSeriesRangeService(environment.settings(), threadPool, clusterService);
         this.updateTimeSeriesRangeService.set(updateTimeSeriesRangeService);
         components.add(this.updateTimeSeriesRangeService.get());
-
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            errorStoreInitialisationService.set(new DataStreamLifecycleErrorStore());
-            dataLifecycleInitialisationService.set(
-                new DataStreamLifecycleService(
-                    settings,
-                    new OriginSettingClient(client, DATA_STREAM_LIFECYCLE_ORIGIN),
-                    clusterService,
-                    getClock(),
-                    threadPool,
-                    threadPool::absoluteTimeInMillis,
-                    errorStoreInitialisationService.get()
-                )
-            );
-            dataLifecycleInitialisationService.get().init();
-            components.add(errorStoreInitialisationService.get());
-            components.add(dataLifecycleInitialisationService.get());
-        }
+        errorStoreInitialisationService.set(new DataStreamLifecycleErrorStore());
+        dataLifecycleInitialisationService.set(
+            new DataStreamLifecycleService(
+                settings,
+                new OriginSettingClient(client, DATA_STREAM_LIFECYCLE_ORIGIN),
+                clusterService,
+                getClock(),
+                threadPool,
+                threadPool::absoluteTimeInMillis,
+                errorStoreInitialisationService.get()
+            )
+        );
+        dataLifecycleInitialisationService.get().init();
+        components.add(errorStoreInitialisationService.get());
+        components.add(dataLifecycleInitialisationService.get());
         return components;
     }
 
@@ -202,13 +195,10 @@ public class DataStreamsPlugin extends Plugin implements ActionPlugin {
         actions.add(new ActionHandler<>(MigrateToDataStreamAction.INSTANCE, MigrateToDataStreamTransportAction.class));
         actions.add(new ActionHandler<>(PromoteDataStreamAction.INSTANCE, PromoteDataStreamTransportAction.class));
         actions.add(new ActionHandler<>(ModifyDataStreamsAction.INSTANCE, ModifyDataStreamsTransportAction.class));
-
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            actions.add(new ActionHandler<>(PutDataStreamLifecycleAction.INSTANCE, TransportPutDataStreamLifecycleAction.class));
-            actions.add(new ActionHandler<>(GetDataStreamLifecycleAction.INSTANCE, TransportGetDataStreamLifecycleAction.class));
-            actions.add(new ActionHandler<>(DeleteDataStreamLifecycleAction.INSTANCE, TransportDeleteDataStreamLifecycleAction.class));
-            actions.add(new ActionHandler<>(ExplainDataStreamLifecycleAction.INSTANCE, TransportExplainDataStreamLifecycleAction.class));
-        }
+        actions.add(new ActionHandler<>(PutDataStreamLifecycleAction.INSTANCE, TransportPutDataStreamLifecycleAction.class));
+        actions.add(new ActionHandler<>(GetDataStreamLifecycleAction.INSTANCE, TransportGetDataStreamLifecycleAction.class));
+        actions.add(new ActionHandler<>(DeleteDataStreamLifecycleAction.INSTANCE, TransportDeleteDataStreamLifecycleAction.class));
+        actions.add(new ActionHandler<>(ExplainDataStreamLifecycleAction.INSTANCE, TransportExplainDataStreamLifecycleAction.class));
         return actions;
     }
 
@@ -234,13 +224,10 @@ public class DataStreamsPlugin extends Plugin implements ActionPlugin {
         handlers.add(new RestMigrateToDataStreamAction());
         handlers.add(new RestPromoteDataStreamAction());
         handlers.add(new RestModifyDataStreamsAction());
-
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            handlers.add(new RestPutDataStreamLifecycleAction());
-            handlers.add(new RestGetDataStreamLifecycleAction());
-            handlers.add(new RestDeleteDataStreamLifecycleAction());
-            handlers.add(new RestExplainDataStreamLifecycleAction());
-        }
+        handlers.add(new RestPutDataStreamLifecycleAction());
+        handlers.add(new RestGetDataStreamLifecycleAction());
+        handlers.add(new RestDeleteDataStreamLifecycleAction());
+        handlers.add(new RestExplainDataStreamLifecycleAction());
         return handlers;
     }
 

+ 1 - 3
modules/data-streams/src/main/java/org/elasticsearch/datastreams/action/GetDataStreamsTransportAction.java

@@ -180,9 +180,7 @@ public class GetDataStreamsTransportAction extends TransportMasterNodeReadAction
         }
         return new GetDataStreamAction.Response(
             dataStreamInfos,
-            request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()
-                ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING)
-                : null
+            request.includeDefaults() ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING) : null
         );
     }
 

+ 1 - 3
modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/TransportExplainDataStreamLifecycleAction.java

@@ -111,9 +111,7 @@ public class TransportExplainDataStreamLifecycleAction extends TransportMasterNo
         listener.onResponse(
             new ExplainDataStreamLifecycleAction.Response(
                 explainIndices,
-                request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()
-                    ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING)
-                    : null
+                request.includeDefaults() ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING) : null
             )
         );
     }

+ 1 - 3
modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/TransportGetDataStreamLifecycleAction.java

@@ -88,9 +88,7 @@ public class TransportGetDataStreamLifecycleAction extends TransportMasterNodeRe
                     )
                     .sorted(Comparator.comparing(GetDataStreamLifecycleAction.Response.DataStreamLifecycle::dataStreamName))
                     .toList(),
-                request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()
-                    ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING)
-                    : null
+                request.includeDefaults() ? clusterSettings.get(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING) : null
             )
         );
     }

+ 1 - 4
modules/data-streams/src/main/java/org/elasticsearch/datastreams/rest/RestGetDataStreamsAction.java

@@ -10,7 +10,6 @@ package org.elasticsearch.datastreams.rest;
 import org.elasticsearch.action.datastreams.GetDataStreamAction;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.node.NodeClient;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
@@ -40,9 +39,7 @@ public class RestGetDataStreamsAction extends BaseRestHandler {
         GetDataStreamAction.Request getDataStreamsRequest = new GetDataStreamAction.Request(
             Strings.splitStringByCommaToArray(request.param("name"))
         );
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            getDataStreamsRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
-        }
+        getDataStreamsRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
         getDataStreamsRequest.indicesOptions(IndicesOptions.fromRequest(request, getDataStreamsRequest.indicesOptions()));
         return channel -> client.execute(GetDataStreamAction.INSTANCE, getDataStreamsRequest, new RestToXContentListener<>(channel));
     }

+ 0 - 1
qa/mixed-cluster/build.gradle

@@ -38,7 +38,6 @@ BuildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
       setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}"
       setting 'xpack.security.enabled', 'false'
       requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
-      requiresFeature 'es.dlm_feature_flag_enabled', Version.fromString("8.9.0")
     }
 
     tasks.register("${baseName}#mixedClusterTest", StandaloneRestIntegTestTask) {

+ 0 - 1
qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java

@@ -32,7 +32,6 @@ public class SmokeTestMultiNodeClientYamlTestSuiteIT extends ESClientYamlSuiteTe
         // The first node does not have the ingest role so we're sure ingest requests are forwarded:
         .node(0, n -> n.setting("node.roles", "[master,data,ml,remote_cluster_client,transform]"))
         .feature(FeatureFlag.TIME_SERIES_MODE)
-        .feature(FeatureFlag.DATA_STREAM_LIFECYCLE_ENABLED)
         .build();
 
     public SmokeTestMultiNodeClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/api/indices.delete_data_lifecycle.json

@@ -4,7 +4,7 @@
       "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-delete-lifecycle.html",
       "description":"Deletes the data stream lifecycle of the selected data streams."
     },
-    "stability":"experimental",
+    "stability":"stable",
     "visibility":"public",
     "headers":{
       "accept": [ "application/json"]

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/api/indices.explain_data_lifecycle.json

@@ -4,7 +4,7 @@
       "url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams-explain-lifecycle.html",
       "description": "Retrieves information about the index's current data stream lifecycle, such as any potential encountered error, time since creation etc."
     },
-    "stability": "experimental",
+    "stability": "stable",
     "visibility": "public",
     "headers": {
       "accept": [

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_data_lifecycle.json

@@ -4,7 +4,7 @@
       "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-get-lifecycle.html",
       "description":"Returns the data stream lifecycle of the selected data streams."
     },
-    "stability":"experimental",
+    "stability":"stable",
     "visibility":"public",
     "headers":{
       "accept": [ "application/json"]

+ 2 - 3
rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_data_lifecycle.json

@@ -4,7 +4,7 @@
       "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/data-streams-put-lifecycle.html",
       "description":"Updates the data stream lifecycle of the selected data streams."
     },
-    "stability":"experimental",
+    "stability":"stable",
     "visibility":"public",
     "headers":{
       "accept": [ "application/json"]
@@ -48,8 +48,7 @@
       }
     },
     "body":{
-      "description":"The data stream lifecycle configuration that consist of the data retention",
-      "required":false
+      "description":"The data stream lifecycle configuration that consist of the data retention"
     }
   }
 }

+ 0 - 1
rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java

@@ -32,7 +32,6 @@ public class ClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
         .module("reindex")
         .module("analysis-common")
         .feature(FeatureFlag.TIME_SERIES_MODE)
-        .feature(FeatureFlag.DATA_STREAM_LIFECYCLE_ENABLED)
         .build();
 
     public ClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {

+ 0 - 2
server/build.gradle

@@ -141,11 +141,9 @@ sourceSets.main.compiledBy(generateModulesList, generatePluginsList)
 if (BuildParams.isSnapshotBuild() == false) {
     tasks.named("test").configure {
         systemProperty 'es.index_mode_feature_flag_registered', 'true'
-        systemProperty 'es.dlm_feature_flag_enabled', 'true'
     }
     tasks.named("internalClusterTest").configure {
         systemProperty 'es.index_mode_feature_flag_registered', 'true'
-        systemProperty 'es.dlm_feature_flag_enabled', 'true'
     }
 }
 

+ 1 - 1
server/src/main/java/org/elasticsearch/action/admin/indices/template/get/TransportGetComponentTemplateAction.java

@@ -91,7 +91,7 @@ public class TransportGetComponentTemplateAction extends TransportMasterNodeRead
 
             }
         }
-        if (request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()) {
+        if (request.includeDefaults()) {
             listener.onResponse(
                 new GetComponentTemplateAction.Response(
                     results,

+ 1 - 1
server/src/main/java/org/elasticsearch/action/admin/indices/template/get/TransportGetComposableIndexTemplateAction.java

@@ -89,7 +89,7 @@ public class TransportGetComposableIndexTemplateAction extends TransportMasterNo
                 throw new ResourceNotFoundException("index template matching [" + request.name() + "] not found");
             }
         }
-        if (request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()) {
+        if (request.includeDefaults()) {
             listener.onResponse(
                 new GetComposableIndexTemplateAction.Response(
                     results,

+ 2 - 2
server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateIndexTemplateAction.java

@@ -155,7 +155,7 @@ public class TransportSimulateIndexTemplateAction extends TransportMasterNodeRea
         overlapping.putAll(findConflictingV1Templates(tempClusterState, matchingTemplate, templateV2.indexPatterns()));
         overlapping.putAll(findConflictingV2Templates(tempClusterState, matchingTemplate, templateV2.indexPatterns()));
 
-        if (request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()) {
+        if (request.includeDefaults()) {
             listener.onResponse(
                 new SimulateIndexTemplateResponse(
                     template,
@@ -305,7 +305,7 @@ public class TransportSimulateIndexTemplateAction extends TransportMasterNodeRea
 
         Settings settings = Settings.builder().put(templateSettings).put(additionalSettings.build()).build();
         DataStreamLifecycle lifecycle = resolveLifecycle(simulatedState.metadata(), matchingTemplate);
-        if (DataStreamLifecycle.isFeatureEnabled() && template.getDataStreamTemplate() != null && lifecycle == null) {
+        if (template.getDataStreamTemplate() != null && lifecycle == null) {
             lifecycle = DataStreamLifecycle.DEFAULT;
         }
         return new Template(settings, mergedMapping, aliasesByName, lifecycle);

+ 1 - 1
server/src/main/java/org/elasticsearch/action/admin/indices/template/post/TransportSimulateTemplateAction.java

@@ -166,7 +166,7 @@ public class TransportSimulateTemplateAction extends TransportMasterNodeReadActi
             systemIndices,
             indexSettingProviders
         );
-        if (request.includeDefaults() && DataStreamLifecycle.isFeatureEnabled()) {
+        if (request.includeDefaults()) {
             listener.onResponse(
                 new SimulateIndexTemplateResponse(
                     template,

+ 3 - 9
server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java

@@ -152,7 +152,7 @@ public final class DataStream implements SimpleDiffable<DataStream>, ToXContentO
         this.system = system;
         this.allowCustomRouting = allowCustomRouting;
         this.indexMode = indexMode;
-        this.lifecycle = DataStreamLifecycle.isFeatureEnabled() ? lifecycle : null;
+        this.lifecycle = lifecycle;
         assert assertConsistent(this.indices);
     }
 
@@ -809,7 +809,7 @@ public final class DataStream implements SimpleDiffable<DataStream>, ToXContentO
             args[6] != null && (boolean) args[6],
             args[7] != null && (boolean) args[7],
             args[8] != null ? IndexMode.fromString((String) args[8]) : null,
-            DataStreamLifecycle.isFeatureEnabled() ? (DataStreamLifecycle) args[9] : null
+            (DataStreamLifecycle) args[9]
         )
     );
 
@@ -831,13 +831,7 @@ public final class DataStream implements SimpleDiffable<DataStream>, ToXContentO
         PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), SYSTEM_FIELD);
         PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), ALLOW_CUSTOM_ROUTING);
         PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), INDEX_MODE);
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            PARSER.declareObject(
-                ConstructingObjectParser.optionalConstructorArg(),
-                (p, c) -> DataStreamLifecycle.fromXContent(p),
-                LIFECYCLE
-            );
-        }
+        PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> DataStreamLifecycle.fromXContent(p), LIFECYCLE);
     }
 
     public static DataStream fromXContent(XContentParser parser) throws IOException {

+ 0 - 7
server/src/main/java/org/elasticsearch/cluster/metadata/DataStreamLifecycle.java

@@ -18,7 +18,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.Writeable;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.util.FeatureFlag;
 import org.elasticsearch.core.Nullable;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
@@ -59,8 +58,6 @@ public class DataStreamLifecycle implements SimpleDiffable<DataStreamLifecycle>,
 
     public static final DataStreamLifecycle DEFAULT = new DataStreamLifecycle();
 
-    private static final FeatureFlag DATA_STREAM_LIFECYCLE_FEATURE_FLAG = new FeatureFlag("dlm");
-
     public static final String DATA_STREAM_LIFECYCLE_ORIGIN = "data_stream_lifecycle";
 
     public static final ParseField ENABLED_FIELD = new ParseField("enabled");
@@ -93,10 +90,6 @@ public class DataStreamLifecycle implements SimpleDiffable<DataStreamLifecycle>,
         PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), ENABLED_FIELD);
     }
 
-    public static boolean isFeatureEnabled() {
-        return DATA_STREAM_LIFECYCLE_FEATURE_FLAG.isEnabled();
-    }
-
     @Nullable
     private final Retention dataRetention;
     @Nullable

+ 1 - 1
server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateDataStreamService.java

@@ -277,7 +277,7 @@ public class MetadataCreateDataStreamService {
             isSystem,
             template.getDataStreamTemplate().isAllowCustomRouting(),
             indexMode,
-            lifecycle == null && DataStreamLifecycle.isFeatureEnabled() ? DataStreamLifecycle.DEFAULT : lifecycle
+            lifecycle == null ? DataStreamLifecycle.DEFAULT : lifecycle
         );
         Metadata.Builder builder = Metadata.builder(currentState.metadata()).put(newDataStream);
 

+ 3 - 19
server/src/main/java/org/elasticsearch/cluster/metadata/Template.java

@@ -51,12 +51,7 @@ public class Template implements SimpleDiffable<Template>, ToXContentObject {
     public static final ConstructingObjectParser<Template, Void> PARSER = new ConstructingObjectParser<>(
         "template",
         false,
-        a -> new Template(
-            (Settings) a[0],
-            (CompressedXContent) a[1],
-            (Map<String, AliasMetadata>) a[2],
-            DataStreamLifecycle.isFeatureEnabled() ? (DataStreamLifecycle) a[3] : null
-        )
+        a -> new Template((Settings) a[0], (CompressedXContent) a[1], (Map<String, AliasMetadata>) a[2], (DataStreamLifecycle) a[3])
     );
 
     static {
@@ -81,14 +76,7 @@ public class Template implements SimpleDiffable<Template>, ToXContentObject {
             }
             return aliasMap;
         }, ALIASES);
-        // We adjust the parser to ensure that the error message will be consistent with that of an unknown field.
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            PARSER.declareObject(
-                ConstructingObjectParser.optionalConstructorArg(),
-                (p, c) -> DataStreamLifecycle.fromXContent(p),
-                LIFECYCLE
-            );
-        }
+        PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> DataStreamLifecycle.fromXContent(p), LIFECYCLE);
     }
 
     @Nullable
@@ -110,11 +98,7 @@ public class Template implements SimpleDiffable<Template>, ToXContentObject {
         this.settings = settings;
         this.mappings = mappings;
         this.aliases = aliases;
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            this.lifecycle = lifecycle;
-        } else {
-            this.lifecycle = null;
-        }
+        this.lifecycle = lifecycle;
     }
 
     public Template(@Nullable Settings settings, @Nullable CompressedXContent mappings, @Nullable Map<String, AliasMetadata> aliases) {

+ 1 - 1
server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java

@@ -571,7 +571,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
         RemoteClusterPortSettings.TCP_SEND_BUFFER_SIZE,
         HealthPeriodicLogger.POLL_INTERVAL_SETTING,
         HealthPeriodicLogger.ENABLED_SETTING,
-        DataStreamLifecycle.isFeatureEnabled() ? DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING : null,
+        DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING,
         IndicesClusterStateService.SHARD_LOCK_RETRY_INTERVAL_SETTING,
         IndicesClusterStateService.SHARD_LOCK_RETRY_TIMEOUT_SETTING,
         IngestSettings.GROK_WATCHDOG_INTERVAL,

+ 1 - 4
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComponentTemplateAction.java

@@ -10,7 +10,6 @@ package org.elasticsearch.rest.action.admin.indices;
 
 import org.elasticsearch.action.admin.indices.template.get.GetComponentTemplateAction;
 import org.elasticsearch.client.internal.node.NodeClient;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
@@ -49,9 +48,7 @@ public class RestGetComponentTemplateAction extends BaseRestHandler {
     public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
 
         final GetComponentTemplateAction.Request getRequest = new GetComponentTemplateAction.Request(request.param("name"));
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            getRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
-        }
+        getRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
         getRequest.local(request.paramAsBoolean("local", getRequest.local()));
         getRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getRequest.masterNodeTimeout()));
 

+ 1 - 4
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComposableIndexTemplateAction.java

@@ -10,7 +10,6 @@ package org.elasticsearch.rest.action.admin.indices;
 
 import org.elasticsearch.action.admin.indices.template.get.GetComposableIndexTemplateAction;
 import org.elasticsearch.client.internal.node.NodeClient;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
@@ -51,9 +50,7 @@ public class RestGetComposableIndexTemplateAction extends BaseRestHandler {
 
         getRequest.local(request.paramAsBoolean("local", getRequest.local()));
         getRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getRequest.masterNodeTimeout()));
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            getRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
-        }
+        getRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
         final boolean implicitAll = getRequest.name() == null;
 
         return channel -> client.execute(GetComposableIndexTemplateAction.INSTANCE, getRequest, new RestToXContentListener<>(channel) {

+ 1 - 4
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestSimulateIndexTemplateAction.java

@@ -13,7 +13,6 @@ import org.elasticsearch.action.admin.indices.template.post.SimulateIndexTemplat
 import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction;
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.Scope;
@@ -44,9 +43,7 @@ public class RestSimulateIndexTemplateAction extends BaseRestHandler {
         simulateIndexTemplateRequest.masterNodeTimeout(
             request.paramAsTime("master_timeout", simulateIndexTemplateRequest.masterNodeTimeout())
         );
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            simulateIndexTemplateRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
-        }
+        simulateIndexTemplateRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
         if (request.hasContent()) {
             PutComposableIndexTemplateAction.Request indexTemplateRequest = new PutComposableIndexTemplateAction.Request(
                 "simulating_template"

+ 1 - 4
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestSimulateTemplateAction.java

@@ -12,7 +12,6 @@ import org.elasticsearch.action.admin.indices.template.post.SimulateTemplateActi
 import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction;
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.Scope;
@@ -40,9 +39,7 @@ public class RestSimulateTemplateAction extends BaseRestHandler {
     protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
         SimulateTemplateAction.Request simulateRequest = new SimulateTemplateAction.Request();
         simulateRequest.templateName(request.param("name"));
-        if (DataStreamLifecycle.isFeatureEnabled()) {
-            simulateRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
-        }
+        simulateRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
         if (request.hasContent()) {
             PutComposableIndexTemplateAction.Request indexTemplateRequest = new PutComposableIndexTemplateAction.Request(
                 "simulating_template"

+ 1 - 2
test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java

@@ -15,8 +15,7 @@ import org.elasticsearch.test.cluster.util.Version;
  * to indicate that this feature is required and should be enabled when appropriate.
  */
 public enum FeatureFlag {
-    TIME_SERIES_MODE("es.index_mode_feature_flag_registered=true", Version.fromString("8.0.0"), null),
-    DATA_STREAM_LIFECYCLE_ENABLED("es.dlm_feature_flag_enabled=true", Version.fromString("8.8.0"), null);
+    TIME_SERIES_MODE("es.index_mode_feature_flag_registered=true", Version.fromString("8.0.0"), null);
 
     public final String systemProperty;
     public final Version from;

+ 2 - 2
x-pack/docs/en/security/authentication/internal-users.asciidoc

@@ -4,8 +4,8 @@
 
 NOTE: These users are designed for internal use by {es} only. Authenticating with these users is not supported.
 
-The {stack-security-features} use six _internal_ users (`_system`, `_xpack`,
-`_xpack_security`, `_async_search`, `_security_profile`, `_synonyms` and `_storage`),
+The {stack-security-features} use eight _internal_ users (`_system`, `_xpack`,
+`_xpack_security`, `_async_search`, `_security_profile`, `_data_stream_lifecycle`, `_synonyms` and `_storage`),
 which are responsible for the operations that take place inside an {es} cluster.
 
 These users are only used by requests that originate from within the cluster.

+ 0 - 1
x-pack/plugin/build.gradle

@@ -225,7 +225,6 @@ testClusters.configureEach {
 
   requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
   requiresFeature 'es.inference_rescorer_feature_flag_enabled', Version.fromString("8.10.0")
-  requiresFeature 'es.dlm_feature_flag_enabled', Version.fromString("8.9.0")
 }
 
 tasks.register('enforceApiSpecsConvention').configure {

+ 0 - 6
x-pack/plugin/core/build.gradle

@@ -153,9 +153,3 @@ if (BuildParams.inFipsJvm){
   // Test clusters run with security disabled
   tasks.named("javaRestTest").configure{enabled = false }
 }
-
-if (BuildParams.isSnapshotBuild() == false) {
-  tasks.named("internalClusterTest").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-}

+ 0 - 5
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/action/DataStreamLifecycleUsageTransportAction.java

@@ -53,11 +53,6 @@ public class DataStreamLifecycleUsageTransportAction extends XPackUsageFeatureTr
         ClusterState state,
         ActionListener<XPackUsageFeatureResponse> listener
     ) {
-        if (DataStreamLifecycle.isFeatureEnabled() == false) {
-            listener.onResponse(new XPackUsageFeatureResponse(DataStreamLifecycleFeatureSetUsage.DISABLED));
-            return;
-        }
-
         final Collection<DataStream> dataStreams = state.metadata().dataStreams().values();
         LongSummaryStatistics retentionStats = dataStreams.stream()
             .filter(ds -> ds.getLifecycle() != null && ds.getLifecycle().isEnabled())

+ 1 - 2
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilege.java

@@ -30,7 +30,6 @@ import org.elasticsearch.action.datastreams.GetDataStreamAction;
 import org.elasticsearch.action.datastreams.PromoteDataStreamAction;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesAction;
 import org.elasticsearch.action.search.SearchShardsAction;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.index.seqno.RetentionLeaseActions;
 import org.elasticsearch.xpack.core.ccr.action.ForgetFollowerAction;
@@ -211,7 +210,7 @@ public final class IndexPrivilege extends Privilege {
             entry("manage_follow_index", MANAGE_FOLLOW_INDEX),
             entry("manage_leader_index", MANAGE_LEADER_INDEX),
             entry("manage_ilm", MANAGE_ILM),
-            DataStreamLifecycle.isFeatureEnabled() ? entry("manage_data_stream_lifecycle", MANAGE_DATA_STREAM_LIFECYCLE) : null,
+            entry("manage_data_stream_lifecycle", MANAGE_DATA_STREAM_LIFECYCLE),
             entry("maintenance", MAINTENANCE),
             entry("auto_configure", AUTO_CONFIGURE),
             entry("cross_cluster_replication", CROSS_CLUSTER_REPLICATION),

+ 0 - 2
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/PrivilegeTests.java

@@ -15,7 +15,6 @@ import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
 import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
 import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesAction;
 import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
 import org.elasticsearch.common.util.set.Sets;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.transport.TransportRequest;
@@ -468,7 +467,6 @@ public class PrivilegeTests extends ESTestCase {
     }
 
     public void testDataStreamLifecyclePrivileges() {
-        assumeTrue("feature flag required", DataStreamLifecycle.isFeatureEnabled());
         {
             Predicate<String> predicate = IndexPrivilege.MANAGE_DATA_STREAM_LIFECYCLE.predicate();
             // check indices actions

+ 0 - 8
x-pack/plugin/ilm/build.gradle

@@ -1,5 +1,3 @@
-import org.elasticsearch.gradle.internal.info.BuildParams
-
 apply plugin: 'elasticsearch.internal-es-plugin'
 apply plugin: 'elasticsearch.internal-cluster-test'
 
@@ -25,9 +23,3 @@ dependencies {
 
 addQaCheckDependencies(project)
 
-if (BuildParams.isSnapshotBuild() == false) {
-  tasks.named("internalClusterTest").configure {
-    systemProperty 'es.dlm_feature_flag_enabled', 'true'
-  }
-}
-

+ 4 - 6
x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java

@@ -7,8 +7,6 @@
 
 package org.elasticsearch.xpack.security.operator;
 
-import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
-
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -431,10 +429,10 @@ public class Constants {
         "indices:admin/data_stream/migrate",
         "indices:admin/data_stream/modify",
         "indices:admin/data_stream/promote",
-        DataStreamLifecycle.isFeatureEnabled() ? "indices:admin/data_stream/lifecycle/delete" : null,
-        DataStreamLifecycle.isFeatureEnabled() ? "indices:admin/data_stream/lifecycle/get" : null,
-        DataStreamLifecycle.isFeatureEnabled() ? "indices:admin/data_stream/lifecycle/put" : null,
-        DataStreamLifecycle.isFeatureEnabled() ? "indices:admin/data_stream/lifecycle/explain" : null,
+        "indices:admin/data_stream/lifecycle/delete",
+        "indices:admin/data_stream/lifecycle/get",
+        "indices:admin/data_stream/lifecycle/put",
+        "indices:admin/data_stream/lifecycle/explain",
         "indices:admin/delete",
         "indices:admin/flush",
         "indices:admin/flush[s]",

+ 0 - 1
x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java

@@ -46,7 +46,6 @@ public class CoreWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTest
         .setting("xpack.security.autoconfiguration.enabled", "false")
         .user(USER, PASS)
         .feature(FeatureFlag.TIME_SERIES_MODE)
-        .feature(FeatureFlag.DATA_STREAM_LIFECYCLE_ENABLED)
         .build();
 
     public CoreWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {