@@ -65,6 +65,7 @@ public class DataStreamLifecycle implements SimpleDiffable<DataStreamLifecycle>,
65
65
DataStreamLifecycle .INCLUDE_EFFECTIVE_RETENTION_PARAM_NAME ,
66
66
"true"
67
67
);
68
+ public static final Tuple <TimeValue , RetentionSource > INFINITE_RETENTION = Tuple .tuple (null , RetentionSource .DATA_STREAM_CONFIGURATION );
68
69
69
70
/**
70
71
* Check if {@link #DATA_STREAMS_LIFECYCLE_ONLY_SETTING_NAME} is present and set to {@code true}, indicating that
@@ -145,32 +146,37 @@ public boolean isEnabled() {
145
146
}
146
147
147
148
/**
148
- * The least amount of time data should be kept by elasticsearch. If a caller does not want the global retention considered (for
149
- * example, when evaluating the effective retention for a system data stream or a template) then null should be given for
150
- * globalRetention.
151
- * @param globalRetention The global retention, or null if global retention does not exist or should not be applied
149
+ * The least amount of time data should be kept by elasticsearch. The effective retention is a function with three parameters,
150
+ * the {@link DataStreamLifecycle#dataRetention}, the global retention and whether this lifecycle is associated with an internal
151
+ * data stream.
152
+ * @param globalRetention The global retention, or null if global retention does not exist.
153
+ * @param isInternalDataStream A flag denoting if this lifecycle is associated with an internal data stream or not
152
154
* @return the time period or null, null represents that data should never be deleted.
153
155
*/
154
156
@ Nullable
155
- public TimeValue getEffectiveDataRetention (@ Nullable DataStreamGlobalRetention globalRetention ) {
156
- return getEffectiveDataRetentionWithSource (globalRetention ).v1 ();
157
+ public TimeValue getEffectiveDataRetention (@ Nullable DataStreamGlobalRetention globalRetention , boolean isInternalDataStream ) {
158
+ return getEffectiveDataRetentionWithSource (globalRetention , isInternalDataStream ).v1 ();
157
159
}
158
160
159
161
/**
160
- * The least amount of time data should be kept by elasticsearch. If a caller does not want the global retention considered (for
161
- * example, when evaluating the effective retention for a system data stream or a template) then null should be given for
162
- * globalRetention.
163
- * @param globalRetention The global retention, or null if global retention does not exist or should not be applied
162
+ * The least amount of time data should be kept by elasticsearch.. The effective retention is a function with three parameters,
163
+ * the {@link DataStreamLifecycle#dataRetention}, the global retention and whether this lifecycle is associated with an internal
164
+ * data stream.
165
+ * @param globalRetention The global retention, or null if global retention does not exist.
166
+ * @param isInternalDataStream A flag denoting if this lifecycle is associated with an internal data stream or not
164
167
* @return A tuple containing the time period or null as v1 (where null represents that data should never be deleted), and the non-null
165
168
* retention source as v2.
166
169
*/
167
- public Tuple <TimeValue , RetentionSource > getEffectiveDataRetentionWithSource (@ Nullable DataStreamGlobalRetention globalRetention ) {
170
+ public Tuple <TimeValue , RetentionSource > getEffectiveDataRetentionWithSource (
171
+ @ Nullable DataStreamGlobalRetention globalRetention ,
172
+ boolean isInternalDataStream
173
+ ) {
168
174
// If lifecycle is disabled there is no effective retention
169
175
if (enabled == false ) {
170
- return Tuple . tuple ( null , RetentionSource . DATA_STREAM_CONFIGURATION ) ;
176
+ return INFINITE_RETENTION ;
171
177
}
172
178
var dataStreamRetention = getDataStreamRetention ();
173
- if (globalRetention == null ) {
179
+ if (globalRetention == null || isInternalDataStream ) {
174
180
return Tuple .tuple (dataStreamRetention , RetentionSource .DATA_STREAM_CONFIGURATION );
175
181
}
176
182
if (dataStreamRetention == null ) {
@@ -187,7 +193,7 @@ public Tuple<TimeValue, RetentionSource> getEffectiveDataRetentionWithSource(@Nu
187
193
188
194
/**
189
195
* The least amount of time data the data stream is requesting es to keep the data.
190
- * NOTE: this can be overridden by the {@link DataStreamLifecycle#getEffectiveDataRetention(DataStreamGlobalRetention)}.
196
+ * NOTE: this can be overridden by the {@link DataStreamLifecycle#getEffectiveDataRetention(DataStreamGlobalRetention,boolean )}.
191
197
* @return the time period or null, null represents that data should never be deleted.
192
198
*/
193
199
@ Nullable
@@ -199,12 +205,16 @@ public TimeValue getDataStreamRetention() {
199
205
* This method checks if the effective retention is matching what the user has configured; if the effective retention
200
206
* does not match then it adds a warning informing the user about the effective retention and the source.
201
207
*/
202
- public void addWarningHeaderIfDataRetentionNotEffective (@ Nullable DataStreamGlobalRetention globalRetention ) {
203
- if (globalRetention == null ) {
208
+ public void addWarningHeaderIfDataRetentionNotEffective (
209
+ @ Nullable DataStreamGlobalRetention globalRetention ,
210
+ boolean isInternalDataStream
211
+ ) {
212
+ if (globalRetention == null || isInternalDataStream ) {
204
213
return ;
205
214
}
206
215
Tuple <TimeValue , DataStreamLifecycle .RetentionSource > effectiveDataRetentionWithSource = getEffectiveDataRetentionWithSource (
207
- globalRetention
216
+ globalRetention ,
217
+ isInternalDataStream
208
218
);
209
219
if (effectiveDataRetentionWithSource .v1 () == null ) {
210
220
return ;
@@ -318,20 +328,22 @@ public String toString() {
318
328
319
329
@ Override
320
330
public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
321
- return toXContent (builder , params , null , null );
331
+ return toXContent (builder , params , null , null , false );
322
332
}
323
333
324
334
/**
325
335
* Converts the data stream lifecycle to XContent, enriches it with effective retention information when requested
326
336
* and injects the RolloverConditions if they exist.
327
337
* In order to request the effective retention you need to set {@link #INCLUDE_EFFECTIVE_RETENTION_PARAM_NAME} to true
328
338
* in the XContent params.
339
+ * NOTE: this is used for serialising user output and the result is never deserialised in elasticsearch.
329
340
*/
330
341
public XContentBuilder toXContent (
331
342
XContentBuilder builder ,
332
343
Params params ,
333
344
@ Nullable RolloverConfiguration rolloverConfiguration ,
334
- @ Nullable DataStreamGlobalRetention globalRetention
345
+ @ Nullable DataStreamGlobalRetention globalRetention ,
346
+ boolean isInternalDataStream
335
347
) throws IOException {
336
348
builder .startObject ();
337
349
builder .field (ENABLED_FIELD .getPreferredName (), enabled );
@@ -342,11 +354,14 @@ public XContentBuilder toXContent(
342
354
builder .field (DATA_RETENTION_FIELD .getPreferredName (), dataRetention .value ().getStringRep ());
343
355
}
344
356
}
357
+ Tuple <TimeValue , RetentionSource > effectiveDataRetentionWithSource = getEffectiveDataRetentionWithSource (
358
+ globalRetention ,
359
+ isInternalDataStream
360
+ );
345
361
if (params .paramAsBoolean (INCLUDE_EFFECTIVE_RETENTION_PARAM_NAME , false )) {
346
- Tuple <TimeValue , RetentionSource > effectiveRetention = getEffectiveDataRetentionWithSource (globalRetention );
347
- if (effectiveRetention .v1 () != null ) {
348
- builder .field (EFFECTIVE_RETENTION_FIELD .getPreferredName (), effectiveRetention .v1 ().getStringRep ());
349
- builder .field (RETENTION_SOURCE_FIELD .getPreferredName (), effectiveRetention .v2 ().displayName ());
362
+ if (effectiveDataRetentionWithSource .v1 () != null ) {
363
+ builder .field (EFFECTIVE_RETENTION_FIELD .getPreferredName (), effectiveDataRetentionWithSource .v1 ().getStringRep ());
364
+ builder .field (RETENTION_SOURCE_FIELD .getPreferredName (), effectiveDataRetentionWithSource .v2 ().displayName ());
350
365
}
351
366
}
352
367
@@ -356,12 +371,18 @@ public XContentBuilder toXContent(
356
371
}
357
372
if (rolloverConfiguration != null ) {
358
373
builder .field (ROLLOVER_FIELD .getPreferredName ());
359
- rolloverConfiguration .evaluateAndConvertToXContent (builder , params , getEffectiveDataRetention ( globalRetention ));
374
+ rolloverConfiguration .evaluateAndConvertToXContent (builder , params , effectiveDataRetentionWithSource . v1 ( ));
360
375
}
361
376
builder .endObject ();
362
377
return builder ;
363
378
}
364
379
380
+ /**
381
+ * This method deserialises XContent format as it was generated ONLY by {@link DataStreamLifecycle#toXContent(XContentBuilder, Params)}.
382
+ * It does not support the output of
383
+ * {@link DataStreamLifecycle#toXContent(XContentBuilder, Params, RolloverConfiguration, DataStreamGlobalRetention, boolean)} because
384
+ * this output is enriched with derived fields we do not handle in this deserialisation.
385
+ */
365
386
public static DataStreamLifecycle fromXContent (XContentParser parser ) throws IOException {
366
387
return PARSER .parse (parser , null );
367
388
}
0 commit comments