Browse Source

Remove the lifecycle field in the PUT _lifecycle request (#95201)

This removes a redundant `lifecycle` field in the `PUT _lifecycle`
request.

Before we had
```
PUT _data_stream/logs-nginx/_lifecycle
{
    "lifecycle": {
        "data_retention": "7d"
    }
}
```

This changes the request to
```
PUT _data_stream/logs-nginx/_lifecycle
{
  "data_retention": "7d"
}
```
Andrei Dan 2 years ago
parent
commit
83402605ea

+ 1 - 3
docs/reference/dlm/apis/put-lifecycle.asciidoc

@@ -58,9 +58,7 @@ The following example sets the lifecycle of `my-data-stream`:
 --------------------------------------------------
 PUT _data_stream/my-data-stream/_lifecycle
 {
-  "lifecycle": {
-    "data_retention": "7d"
-  }
+  "data_retention": "7d"
 }
 --------------------------------------------------
 // TEST[setup:my_data_stream]

+ 4 - 1
modules/dlm/src/internalClusterTest/java/org/elasticsearch/dlm/CrudDataLifecycleIT.java

@@ -125,7 +125,10 @@ public class CrudDataLifecycleIT extends ESIntegTestCase {
         // Set lifecycle
         {
             DataLifecycle lifecycle = randomDataLifecycle();
-            PutDataLifecycleAction.Request putDataLifecycleRequest = new PutDataLifecycleAction.Request(new String[] { "*" }, lifecycle);
+            PutDataLifecycleAction.Request putDataLifecycleRequest = new PutDataLifecycleAction.Request(
+                new String[] { "*" },
+                lifecycle.getDataRetention()
+            );
             assertThat(client().execute(PutDataLifecycleAction.INSTANCE, putDataLifecycleRequest).get().isAcknowledged(), equalTo(true));
             GetDataLifecycleAction.Request getDataLifecycleRequest = new GetDataLifecycleAction.Request(new String[] { "my-data-stream" });
             GetDataLifecycleAction.Response response = client().execute(GetDataLifecycleAction.INSTANCE, getDataLifecycleRequest).get();

+ 0 - 1
modules/dlm/src/internalClusterTest/java/org/elasticsearch/dlm/CrudDataLifecycleSystemDataStreamIT.java

@@ -143,7 +143,6 @@ public class CrudDataLifecycleSystemDataStreamIT extends ESIntegTestCase {
                 Request putRequest = new Request("PUT", "/_data_stream/" + systemDataStream + "/_lifecycle");
                 putRequest.setJsonEntity("""
                     {
-                      "lifecycle": {}
                     }""");
                 // No header
                 ResponseException re = expectThrows(ResponseException.class, () -> restClient.performRequest(putRequest));

+ 4 - 4
modules/dlm/src/internalClusterTest/java/org/elasticsearch/dlm/DataLifecycleServiceIT.java

@@ -157,7 +157,7 @@ public class DataLifecycleServiceIT extends ESIntegTestCase {
             });
         }
         // Update the lifecycle of the data stream
-        updateLifecycle(dataStreamName, new DataLifecycle(TimeValue.timeValueMillis(1)));
+        updateLifecycle(dataStreamName, TimeValue.timeValueMillis(1));
         // Verify that the retention has changed for all backing indices
         assertBusy(() -> {
             GetDataStreamAction.Request getDataStreamRequest = new GetDataStreamAction.Request(new String[] { dataStreamName });
@@ -281,7 +281,7 @@ public class DataLifecycleServiceIT extends ESIntegTestCase {
         // mark the first generation index as read-only so deletion fails when we enable the retention configuration
         updateIndexSettings(Settings.builder().put(READ_ONLY.settingName(), true), firstGenerationIndex);
         try {
-            updateLifecycle(dataStreamName, new DataLifecycle(TimeValue.timeValueSeconds(1)));
+            updateLifecycle(dataStreamName, TimeValue.timeValueSeconds(1));
 
             assertBusy(() -> {
                 GetDataStreamAction.Request getDataStreamRequest = new GetDataStreamAction.Request(new String[] { dataStreamName });
@@ -382,10 +382,10 @@ public class DataLifecycleServiceIT extends ESIntegTestCase {
         client().execute(PutComposableIndexTemplateAction.INSTANCE, request).actionGet();
     }
 
-    static void updateLifecycle(String dataStreamName, DataLifecycle dataLifecycle) {
+    static void updateLifecycle(String dataStreamName, TimeValue dataRetention) {
         PutDataLifecycleAction.Request putDataLifecycleRequest = new PutDataLifecycleAction.Request(
             new String[] { dataStreamName },
-            dataLifecycle
+            dataRetention
         );
         AcknowledgedResponse putDataLifecycleResponse = client().execute(PutDataLifecycleAction.INSTANCE, putDataLifecycleRequest)
             .actionGet();

+ 20 - 5
modules/dlm/src/main/java/org/elasticsearch/dlm/action/PutDataLifecycleAction.java

@@ -17,15 +17,20 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse;
 import org.elasticsearch.cluster.metadata.DataLifecycle;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.core.Nullable;
+import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.xcontent.ConstructingObjectParser;
-import org.elasticsearch.xcontent.ParseField;
+import org.elasticsearch.xcontent.ObjectParser;
 import org.elasticsearch.xcontent.ToXContentObject;
 import org.elasticsearch.xcontent.XContentBuilder;
+import org.elasticsearch.xcontent.XContentParser;
 
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Objects;
 
+import static org.elasticsearch.cluster.metadata.DataLifecycle.DATA_RETENTION_FIELD;
+
 /**
  * Sets the data lifecycle that was provided in the request to the requested data streams.
  */
@@ -42,10 +47,20 @@ public class PutDataLifecycleAction extends ActionType<AcknowledgedResponse> {
 
         public static final ConstructingObjectParser<Request, Void> PARSER = new ConstructingObjectParser<>(
             "put_data_stream_lifecycle_request",
-            args -> new Request(null, ((DataLifecycle) args[0]))
+            args -> new Request(null, ((TimeValue) args[0]))
         );
+
         static {
-            PARSER.declareObject(ConstructingObjectParser.constructorArg(), DataLifecycle.PARSER, new ParseField("lifecycle"));
+            PARSER.declareField(
+                ConstructingObjectParser.optionalConstructorArg(),
+                (p, c) -> TimeValue.parseTimeValue(p.textOrNull(), DATA_RETENTION_FIELD.getPreferredName()),
+                DATA_RETENTION_FIELD,
+                ObjectParser.ValueType.STRING_OR_NULL
+            );
+        }
+
+        public static Request parseRequest(XContentParser parser) {
+            return PARSER.apply(parser, null);
         }
 
         private String[] names;
@@ -67,9 +82,9 @@ public class PutDataLifecycleAction extends ActionType<AcknowledgedResponse> {
             out.writeWriteable(lifecycle);
         }
 
-        public Request(String[] names, DataLifecycle lifecycle) {
+        public Request(String[] names, @Nullable TimeValue dataRetention) {
             this.names = names;
-            this.lifecycle = lifecycle;
+            this.lifecycle = new DataLifecycle(dataRetention);
         }
 
         public String[] getNames() {

+ 6 - 11
modules/dlm/src/main/java/org/elasticsearch/dlm/rest/RestPutDataLifecycleAction.java

@@ -9,7 +9,6 @@ package org.elasticsearch.dlm.rest;
 
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.node.NodeClient;
-import org.elasticsearch.cluster.metadata.DataLifecycle;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.dlm.action.PutDataLifecycleAction;
 import org.elasticsearch.rest.BaseRestHandler;
@@ -39,17 +38,13 @@ public class RestPutDataLifecycleAction extends BaseRestHandler {
 
     @Override
     protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
-        DataLifecycle lifecycle;
         try (XContentParser parser = request.contentParser()) {
-            lifecycle = PutDataLifecycleAction.Request.PARSER.parse(parser, null).getLifecycle();
+            PutDataLifecycleAction.Request putLifecycleRequest = PutDataLifecycleAction.Request.parseRequest(parser);
+            putLifecycleRequest.indices(Strings.splitStringByCommaToArray(request.param("name")));
+            putLifecycleRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putLifecycleRequest.masterNodeTimeout()));
+            putLifecycleRequest.timeout(request.paramAsTime("timeout", putLifecycleRequest.timeout()));
+            putLifecycleRequest.indicesOptions(IndicesOptions.fromRequest(request, putLifecycleRequest.indicesOptions()));
+            return channel -> client.execute(PutDataLifecycleAction.INSTANCE, putLifecycleRequest, new RestToXContentListener<>(channel));
         }
-        PutDataLifecycleAction.Request putLifecycleRequest = new PutDataLifecycleAction.Request(
-            Strings.splitStringByCommaToArray(request.param("name")),
-            lifecycle
-        );
-        putLifecycleRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putLifecycleRequest.masterNodeTimeout()));
-        putLifecycleRequest.timeout(request.paramAsTime("timeout", putLifecycleRequest.timeout()));
-        putLifecycleRequest.indicesOptions(IndicesOptions.fromRequest(request, putLifecycleRequest.indicesOptions()));
-        return channel -> client.execute(PutDataLifecycleAction.INSTANCE, putLifecycleRequest, new RestToXContentListener<>(channel));
     }
 }

+ 2 - 4
modules/dlm/src/yamlRestTest/resources/rest-api-spec/test/dlm/20_basic.yml

@@ -55,8 +55,7 @@ setup:
       indices.put_data_lifecycle:
         name: "*"
         body:
-          lifecycle:
-            data_retention: '30d'
+          data_retention: '30d'
   - is_true: acknowledged
 
   - do:
@@ -87,8 +86,7 @@ setup:
       indices.put_data_lifecycle:
         name: "simple-data-stream1"
         body:
-          lifecycle:
-            data_retention: '30d'
+          data_retention: '30d'
   - is_true: acknowledged
 
   - do:

+ 1 - 2
modules/dlm/src/yamlRestTest/resources/rest-api-spec/test/dlm/30_not_found.yml

@@ -48,8 +48,7 @@ setup:
       indices.put_data_lifecycle:
         name: "my-data-stream-1,does-not-exist"
         body:
-          lifecycle:
-            data_retention: '30d'
+          data_retention: '30d'
   - match: { error.reason: "no such index [does-not-exist]" }
 
   - do:

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

@@ -46,7 +46,7 @@ public class DataLifecycle implements SimpleDiffable<DataLifecycle>, ToXContentO
     public static final DataLifecycle EMPTY = new DataLifecycle();
     public static final String DLM_ORIGIN = "data_lifecycle";
 
-    private static final ParseField DATA_RETENTION_FIELD = new ParseField("data_retention");
+    public static final ParseField DATA_RETENTION_FIELD = new ParseField("data_retention");
     private static final ParseField ROLLOVER_FIELD = new ParseField("rollover");
 
     public static final ConstructingObjectParser<DataLifecycle, Void> PARSER = new ConstructingObjectParser<>(