Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for the data lifecycle to be explicitly nullified #95979

Merged
merged 38 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1045538
Allow for the data lifecycle to be explicitly nullified
gmarouli May 9, 2023
396ea5d
Update docs/changelog/95979.yaml
gmarouli May 10, 2023
bf85b5b
Bump compatibility version of DLM to account for the lifecycle format…
gmarouli May 10, 2023
68b5256
Merge branch 'main' into dlm-nullify-retention
gmarouli May 11, 2023
309a374
Merge branch 'main' into dlm-nullify-retention
gmarouli May 12, 2023
63625d9
Merge with main and composing lifecycle components
gmarouli May 16, 2023
bbe9101
Introduce "nullyfiable" retention
gmarouli May 17, 2023
19d69e7
Refactor test and add extra cases
gmarouli May 17, 2023
ff14831
Merge branch 'main' into dlm-nullify-retention
elasticmachine May 17, 2023
61a1b10
Do not include the nullified option in XContent testing
gmarouli May 18, 2023
9ca6712
Merge branch 'main' into dlm-nullify-retention
gmarouli May 18, 2023
2ff060d
Bump TransportVersion
gmarouli May 18, 2023
e0fe443
Fix format
gmarouli May 18, 2023
5c4b7c3
Upddate current TransportVersion
gmarouli May 18, 2023
caa592d
Merge with main and fix transport version
gmarouli May 23, 2023
b616f85
Explain better the distinct situations of DataLifecycle in the constants
gmarouli May 23, 2023
faf5f23
Write a dedicated mutate method
gmarouli May 23, 2023
47a4988
Add validation check for nullified lifecycle
gmarouli May 23, 2023
7846827
Merge branch 'main' into dlm-nullify-retention
gmarouli May 25, 2023
44013f6
Test for invalid lifecycle
gmarouli May 25, 2023
b337664
Update lifecycle composition tests
gmarouli May 25, 2023
8f31dd9
Fit CrudDataLifecycleIT put lifecycle test
gmarouli May 25, 2023
1d56fde
Merge branch 'main' into dlm-nullify-retention
gmarouli May 25, 2023
bccae25
Fix failing tests
gmarouli May 25, 2023
9b9e307
Merge with main and bump versions
gmarouli May 26, 2023
a2f6bf2
Merge branch 'main' into dlm-nullify-retention
elasticmachine May 29, 2023
713cfd7
Remove the nullified flag from the DataLifecycle
gmarouli May 29, 2023
dad5e59
Implement nullified lifecycle in the template level
gmarouli May 29, 2023
2165fe3
Handle backwards compatibility
gmarouli May 30, 2023
467ac2f
Review improvements
gmarouli May 30, 2023
a1458e9
Merge
gmarouli May 30, 2023
404a874
Update new telemetry code
gmarouli May 30, 2023
378805b
Merge branch 'main' into dlm-nullify-retention
elasticmachine May 30, 2023
ecf8a7f
Merge branch 'main' into dlm-nullify-retention
elasticmachine May 31, 2023
bfbaf19
Add Nullable annotation
gmarouli Jun 1, 2023
8db0537
Merge branch 'main' into dlm-nullify-retention
gmarouli Jun 1, 2023
9730ec3
Change equals to ==
gmarouli Jun 1, 2023
a74625f
Merge branch 'main' into dlm-nullify-retention
elasticmachine Jun 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/95979.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 95979
summary: Allow for the data lifecycle and the retention to be explicitly nullified
area: DLM
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.ComponentTemplate;
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
import org.elasticsearch.cluster.metadata.DataLifecycle;
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
import org.elasticsearch.cluster.metadata.MetadataIndexTemplateService;
import org.elasticsearch.cluster.metadata.Template;
Expand All @@ -32,11 +33,13 @@
import java.util.Set;

import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.generateTsdbMapping;
import static org.elasticsearch.cluster.metadata.MetadataIndexTemplateService.composeDataLifecycles;
import static org.elasticsearch.common.settings.Settings.builder;
import static org.elasticsearch.datastreams.MetadataDataStreamRolloverServiceTests.createSettingsProvider;
import static org.elasticsearch.indices.ShardLimitValidator.SETTING_CLUSTER_MAX_SHARDS_PER_NODE;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -140,6 +143,47 @@ public void testRequireRoutingPath() throws Exception {
}
}

public void testLifecycleComposition() {
// No lifecycles result to null
{
List<DataLifecycle> lifecycles = List.of();
assertThat(composeDataLifecycles(lifecycles), nullValue());
}
// One lifecycle results to this lifecycle as the final
{
DataLifecycle lifecycle = switch (randomInt(2)) {
case 0 -> new DataLifecycle();
case 1 -> new DataLifecycle(DataLifecycle.Retention.NULL);
default -> new DataLifecycle(randomMillisUpToYear9999());
};
List<DataLifecycle> lifecycles = List.of(lifecycle);
assertThat(composeDataLifecycles(lifecycles), equalTo(lifecycle));
}
// If the last lifecycle is missing a property we keep the latest from the previous ones
{
DataLifecycle lifecycleWithRetention = new DataLifecycle(randomMillisUpToYear9999());
List<DataLifecycle> lifecycles = List.of(lifecycleWithRetention, new DataLifecycle());
assertThat(
composeDataLifecycles(lifecycles).getEffectiveDataRetention(),
equalTo(lifecycleWithRetention.getEffectiveDataRetention())
);
}
// If both lifecycle have all properties, then the latest one overwrites all the others
{
DataLifecycle lifecycle1 = new DataLifecycle(randomMillisUpToYear9999());
DataLifecycle lifecycle2 = new DataLifecycle(randomMillisUpToYear9999());
List<DataLifecycle> lifecycles = List.of(lifecycle1, lifecycle2);
assertThat(composeDataLifecycles(lifecycles), equalTo(lifecycle2));
}
// If the last lifecycle is explicitly null, the result is also null
{
DataLifecycle lifecycle1 = new DataLifecycle(randomMillisUpToYear9999());
DataLifecycle lifecycle2 = new DataLifecycle(randomMillisUpToYear9999());
List<DataLifecycle> lifecycles = List.of(lifecycle1, lifecycle2, Template.NO_LIFECYCLE);
assertThat(composeDataLifecycles(lifecycles), nullValue());
}
}

private MetadataIndexTemplateService getMetadataIndexTemplateService() {
var indicesService = getInstanceFromNode(IndicesService.class);
var clusterService = getInstanceFromNode(ClusterService.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import org.elasticsearch.action.datastreams.CreateDataStreamAction;
import org.elasticsearch.cluster.metadata.DataLifecycle;
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.datastreams.DataStreamsPlugin;
import org.elasticsearch.dlm.action.DeleteDataLifecycleAction;
import org.elasticsearch.dlm.action.GetDataLifecycleAction;
Expand Down Expand Up @@ -65,11 +67,11 @@ public void testGetLifecycle() throws Exception {
GetDataLifecycleAction.Response response = client().execute(GetDataLifecycleAction.INSTANCE, getDataLifecycleRequest).get();
assertThat(response.getDataStreamLifecycles().size(), equalTo(3));
assertThat(response.getDataStreamLifecycles().get(0).dataStreamName(), equalTo("with-lifecycle-1"));
assertThat(response.getDataStreamLifecycles().get(0).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(response.getDataStreamLifecycles().get(0).lifecycle(), lifecycle);
assertThat(response.getDataStreamLifecycles().get(1).dataStreamName(), equalTo("with-lifecycle-2"));
assertThat(response.getDataStreamLifecycles().get(1).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(response.getDataStreamLifecycles().get(1).lifecycle(), lifecycle);
assertThat(response.getDataStreamLifecycles().get(2).dataStreamName(), equalTo("without-lifecycle"));
assertThat(response.getDataStreamLifecycles().get(2).lifecycle(), is(nullValue()));
assertThat(response.getDataStreamLifecycles().get(2).lifecycle(), nullValue());
assertThat(response.getRolloverConfiguration(), nullValue());
}

Expand All @@ -79,9 +81,9 @@ public void testGetLifecycle() throws Exception {
GetDataLifecycleAction.Response response = client().execute(GetDataLifecycleAction.INSTANCE, getDataLifecycleRequest).get();
assertThat(response.getDataStreamLifecycles().size(), equalTo(2));
assertThat(response.getDataStreamLifecycles().get(0).dataStreamName(), equalTo("with-lifecycle-1"));
assertThat(response.getDataStreamLifecycles().get(0).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(response.getDataStreamLifecycles().get(0).lifecycle(), lifecycle);
assertThat(response.getDataStreamLifecycles().get(1).dataStreamName(), equalTo("with-lifecycle-2"));
assertThat(response.getDataStreamLifecycles().get(1).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(response.getDataStreamLifecycles().get(1).lifecycle(), lifecycle);
assertThat(response.getRolloverConfiguration(), nullValue());
}

Expand All @@ -93,7 +95,7 @@ public void testGetLifecycle() throws Exception {
GetDataLifecycleAction.Response response = client().execute(GetDataLifecycleAction.INSTANCE, getDataLifecycleRequest).get();
assertThat(response.getDataStreamLifecycles().size(), equalTo(2));
assertThat(response.getDataStreamLifecycles().get(0).dataStreamName(), equalTo("with-lifecycle-1"));
assertThat(response.getDataStreamLifecycles().get(0).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(response.getDataStreamLifecycles().get(0).lifecycle(), lifecycle);
assertThat(response.getRolloverConfiguration(), nullValue());
}

Expand All @@ -106,14 +108,22 @@ public void testGetLifecycle() throws Exception {
).get();
assertThat(responseWithRollover.getDataStreamLifecycles().size(), equalTo(3));
assertThat(responseWithRollover.getDataStreamLifecycles().get(0).dataStreamName(), equalTo("with-lifecycle-1"));
assertThat(responseWithRollover.getDataStreamLifecycles().get(0).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(responseWithRollover.getDataStreamLifecycles().get(0).lifecycle(), lifecycle);
assertThat(responseWithRollover.getDataStreamLifecycles().get(1).dataStreamName(), equalTo("with-lifecycle-2"));
assertThat(responseWithRollover.getDataStreamLifecycles().get(1).lifecycle(), equalTo(lifecycle));
assertDataLifecycle(responseWithRollover.getDataStreamLifecycles().get(1).lifecycle(), lifecycle);
assertThat(responseWithRollover.getDataStreamLifecycles().get(2).dataStreamName(), equalTo("without-lifecycle"));
assertThat(responseWithRollover.getDataStreamLifecycles().get(2).lifecycle(), is(nullValue()));
assertThat(responseWithRollover.getRolloverConfiguration(), notNullValue());
}

private void assertDataLifecycle(DataLifecycle dataLifecycle, DataLifecycle expected) {
if (expected.equals(Template.NO_LIFECYCLE)) {
assertThat(dataLifecycle, nullValue());
} else {
assertThat(dataLifecycle, equalTo(expected));
}
}

public void testPutLifecycle() throws Exception {
putComposableIndexTemplate("id1", null, List.of("my-data-stream*"), null, null, null);
// Create index without a lifecycle
Expand All @@ -132,17 +142,17 @@ public void testPutLifecycle() throws Exception {

// Set lifecycle
{
DataLifecycle lifecycle = randomDataLifecycle();
TimeValue dataRetention = randomBoolean() ? null : TimeValue.timeValueMillis(randomMillisUpToYear9999());
PutDataLifecycleAction.Request putDataLifecycleRequest = new PutDataLifecycleAction.Request(
new String[] { "*" },
lifecycle.getDataRetention()
dataRetention
);
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();
assertThat(response.getDataStreamLifecycles().size(), equalTo(1));
assertThat(response.getDataStreamLifecycles().get(0).dataStreamName(), equalTo("my-data-stream"));
assertThat(response.getDataStreamLifecycles().get(0).lifecycle(), equalTo(lifecycle));
assertThat(response.getDataStreamLifecycles().get(0).lifecycle().getEffectiveDataRetention(), equalTo(dataRetention));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void testExplainLifecycle() throws Exception {
assertThat(explainIndex.isManagedByDLM(), is(true));
assertThat(explainIndex.getIndexCreationDate(), notNullValue());
assertThat(explainIndex.getLifecycle(), notNullValue());
assertThat(explainIndex.getLifecycle().getDataRetention(), nullValue());
assertThat(explainIndex.getLifecycle().getEffectiveDataRetention(), nullValue());
if (internalCluster().numDataNodes() > 1) {
// If the number of nodes is 1 then the cluster will be yellow so forcemerge will report an error if it has run
assertThat(explainIndex.getError(), nullValue());
Expand Down Expand Up @@ -208,7 +208,7 @@ public void testExplainLifecycleForIndicesWithErrors() throws Exception {
assertThat(explainIndex.isManagedByDLM(), is(true));
assertThat(explainIndex.getIndexCreationDate(), notNullValue());
assertThat(explainIndex.getLifecycle(), notNullValue());
assertThat(explainIndex.getLifecycle().getDataRetention(), nullValue());
assertThat(explainIndex.getLifecycle().getEffectiveDataRetention(), nullValue());
assertThat(explainIndex.getRolloverDate(), nullValue());
assertThat(explainIndex.getTimeSinceRollover(System::currentTimeMillis), nullValue());
// index has not been rolled over yet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ private void maybeExecuteRollover(ClusterState state, DataStream dataStream) {
RolloverRequest rolloverRequest = getDefaultRolloverRequest(
rolloverConfiguration,
dataStream.getName(),
dataStream.getLifecycle().getDataRetention()
dataStream.getLifecycle().getEffectiveDataRetention()
);
transportActionsDeduplicator.executeOnce(
rolloverRequest,
Expand Down Expand Up @@ -525,7 +525,7 @@ static TimeValue getRetentionConfiguration(DataStream dataStream) {
if (dataStream.getLifecycle() == null) {
return null;
}
return dataStream.getLifecycle().getDataRetention();
return dataStream.getLifecycle().getEffectiveDataRetention();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
import java.util.List;
import java.util.Map;

import static org.apache.lucene.tests.util.LuceneTestCase.rarely;
import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.newInstance;
import static org.elasticsearch.test.ESIntegTestCase.client;
import static org.elasticsearch.test.ESTestCase.randomInt;
import static org.elasticsearch.test.ESTestCase.randomIntBetween;
import static org.junit.Assert.assertTrue;

Expand Down Expand Up @@ -94,6 +94,11 @@ static void putComposableIndexTemplate(
}

static DataLifecycle randomDataLifecycle() {
return rarely() ? new DataLifecycle() : new DataLifecycle(TimeValue.timeValueDays(randomIntBetween(1, 365)));
return switch (randomInt(3)) {
case 0 -> new DataLifecycle();
case 1 -> new DataLifecycle(DataLifecycle.Retention.NULL);
case 2 -> Template.NO_LIFECYCLE;
default -> new DataLifecycle(TimeValue.timeValueDays(randomIntBetween(1, 365)));
};
}
}
3 changes: 2 additions & 1 deletion server/src/main/java/org/elasticsearch/TransportVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ private static TransportVersion registerTransportVersion(int id, String uniqueId
public static final TransportVersion V_8_500_004 = registerTransportVersion(8_500_004, "6a00db6a-fd66-42a9-97ea-f6cc53169110");
public static final TransportVersion V_8_500_005 = registerTransportVersion(8_500_005, "65370d2a-d936-4383-a2e0-8403f708129b");
public static final TransportVersion V_8_500_006 = registerTransportVersion(8_500_006, "7BB5621A-80AC-425F-BA88-75543C442F23");
public static final TransportVersion V_8_500_007 = registerTransportVersion(8_500_007, "77261d43-4149-40af-89c5-7e71e0454fce");

/**
* Reference to the most recent transport version.
* This should be the transport version with the highest id.
*/
public static final TransportVersion CURRENT = V_8_500_006;
public static final TransportVersion CURRENT = V_8_500_007;

/**
* Reference to the earliest compatible transport version to this version of the codebase.
Expand Down
Loading