|
@@ -14,12 +14,14 @@ import org.elasticsearch.cluster.ClusterState;
|
|
|
import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
|
|
import org.elasticsearch.cluster.metadata.DataStream;
|
|
|
import org.elasticsearch.cluster.metadata.DataStreamAlias;
|
|
|
+import org.elasticsearch.cluster.metadata.DataStreamGlobalRetentionSettings;
|
|
|
import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
|
|
|
import org.elasticsearch.cluster.metadata.Metadata;
|
|
|
import org.elasticsearch.cluster.service.ClusterService;
|
|
|
import org.elasticsearch.common.bytes.BytesReference;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
|
|
+import org.elasticsearch.core.TimeValue;
|
|
|
import org.elasticsearch.core.Tuple;
|
|
|
import org.elasticsearch.index.Index;
|
|
|
import org.elasticsearch.index.IndexMode;
|
|
@@ -34,11 +36,13 @@ import org.elasticsearch.xcontent.XContentType;
|
|
|
import org.elasticsearch.xpack.core.XPackClientPlugin;
|
|
|
import org.junit.After;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collection;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
import java.util.function.Function;
|
|
|
|
|
@@ -64,24 +68,58 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
return clusterStateBuilder.build();
|
|
|
});
|
|
|
updateClusterSettings(
|
|
|
- Settings.builder().put(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING.getKey(), (String) null)
|
|
|
+ Settings.builder()
|
|
|
+ .putNull(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING.getKey())
|
|
|
+ .putNull(DataStreamGlobalRetentionSettings.DATA_STREAMS_DEFAULT_RETENTION_SETTING.getKey())
|
|
|
);
|
|
|
}
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public void testAction() throws Exception {
|
|
|
- assertUsageResults(0, 0, 0, 0.0, true);
|
|
|
- AtomicLong totalCount = new AtomicLong(0);
|
|
|
- AtomicLong countLifecycleWithRetention = new AtomicLong(0);
|
|
|
+ // test empty results
|
|
|
+ {
|
|
|
+ Map<String, Object> map = getLifecycleUsage();
|
|
|
+ assertThat(map.get("available"), equalTo(true));
|
|
|
+ assertThat(map.get("enabled"), equalTo(true));
|
|
|
+ assertThat(map.get("count"), equalTo(0));
|
|
|
+ assertThat(map.get("default_rollover_used"), equalTo(true));
|
|
|
+
|
|
|
+ Map<String, Object> dataRetentionMap = (Map<String, Object>) map.get("data_retention");
|
|
|
+ assertThat(dataRetentionMap.size(), equalTo(1));
|
|
|
+ assertThat(dataRetentionMap.get("configured_data_streams"), equalTo(0));
|
|
|
+
|
|
|
+ Map<String, Object> effectiveRetentionMap = (Map<String, Object>) map.get("effective_retention");
|
|
|
+ assertThat(effectiveRetentionMap.size(), equalTo(1));
|
|
|
+ assertThat(effectiveRetentionMap.get("retained_data_streams"), equalTo(0));
|
|
|
+
|
|
|
+ Map<String, Object> globalRetentionMap = (Map<String, Object>) map.get("global_retention");
|
|
|
+ assertThat(globalRetentionMap.get("max"), equalTo(Map.of("defined", false)));
|
|
|
+ assertThat(globalRetentionMap.get("default"), equalTo(Map.of("defined", false)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Keep track of the data streams created
|
|
|
+ AtomicInteger dataStreamsWithLifecycleCount = new AtomicInteger(0);
|
|
|
+ AtomicInteger dataStreamsWithRetentionCount = new AtomicInteger(0);
|
|
|
+ AtomicInteger dataStreamsWithDefaultRetentionCount = new AtomicInteger(0);
|
|
|
+
|
|
|
AtomicLong totalRetentionTimes = new AtomicLong(0);
|
|
|
AtomicLong minRetention = new AtomicLong(Long.MAX_VALUE);
|
|
|
AtomicLong maxRetention = new AtomicLong(Long.MIN_VALUE);
|
|
|
+
|
|
|
boolean useDefaultRolloverConfig = randomBoolean();
|
|
|
if (useDefaultRolloverConfig == false) {
|
|
|
updateClusterSettings(
|
|
|
Settings.builder().put(DataStreamLifecycle.CLUSTER_LIFECYCLE_DEFAULT_ROLLOVER_SETTING.getKey(), "min_docs=33")
|
|
|
);
|
|
|
}
|
|
|
+ TimeValue defaultRetention = TimeValue.timeValueDays(10);
|
|
|
+ boolean useDefaultRetention = randomBoolean();
|
|
|
+ if (useDefaultRetention) {
|
|
|
+ updateClusterSettings(
|
|
|
+ Settings.builder()
|
|
|
+ .put(DataStreamGlobalRetentionSettings.DATA_STREAMS_DEFAULT_RETENTION_SETTING.getKey(), defaultRetention.getStringRep())
|
|
|
+ );
|
|
|
+ }
|
|
|
/*
|
|
|
* We now add a number of simulated data streams to the cluster state. Some have lifecycles, some don't. The ones with lifecycles
|
|
|
* have varying retention periods. After adding them, we make sure the numbers add up.
|
|
@@ -89,19 +127,25 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
updateClusterState(clusterState -> {
|
|
|
Metadata.Builder metadataBuilder = Metadata.builder(clusterState.metadata());
|
|
|
Map<String, DataStream> dataStreamMap = new HashMap<>();
|
|
|
- for (int dataStreamCount = 0; dataStreamCount < randomInt(200); dataStreamCount++) {
|
|
|
- boolean hasLifecycle = randomBoolean();
|
|
|
+ boolean atLeastOne = false;
|
|
|
+ for (int dataStreamCount = 0; dataStreamCount < randomIntBetween(1, 200); dataStreamCount++) {
|
|
|
+ boolean hasLifecycle = randomBoolean() || atLeastOne == false;
|
|
|
DataStreamLifecycle lifecycle;
|
|
|
+ boolean systemDataStream = rarely();
|
|
|
if (hasLifecycle) {
|
|
|
if (randomBoolean()) {
|
|
|
lifecycle = new DataStreamLifecycle(null, null, null);
|
|
|
- totalCount.incrementAndGet();
|
|
|
+ dataStreamsWithLifecycleCount.incrementAndGet();
|
|
|
+ if (useDefaultRetention && systemDataStream == false) {
|
|
|
+ dataStreamsWithDefaultRetentionCount.incrementAndGet();
|
|
|
+ }
|
|
|
+ atLeastOne = true;
|
|
|
} else {
|
|
|
long retentionMillis = randomLongBetween(1000, 100000);
|
|
|
- boolean isEnabled = randomBoolean();
|
|
|
+ boolean isEnabled = randomBoolean() || atLeastOne == false;
|
|
|
if (isEnabled) {
|
|
|
- totalCount.incrementAndGet();
|
|
|
- countLifecycleWithRetention.incrementAndGet();
|
|
|
+ dataStreamsWithLifecycleCount.incrementAndGet();
|
|
|
+ dataStreamsWithRetentionCount.incrementAndGet();
|
|
|
totalRetentionTimes.addAndGet(retentionMillis);
|
|
|
|
|
|
if (retentionMillis < minRetention.get()) {
|
|
@@ -110,6 +154,7 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
if (retentionMillis > maxRetention.get()) {
|
|
|
maxRetention.set(retentionMillis);
|
|
|
}
|
|
|
+ atLeastOne = true;
|
|
|
}
|
|
|
lifecycle = DataStreamLifecycle.newBuilder().dataRetention(retentionMillis).enabled(isEnabled).build();
|
|
|
}
|
|
@@ -121,7 +166,6 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
Index index = new Index(randomAlphaOfLength(60), randomAlphaOfLength(60));
|
|
|
indices.add(index);
|
|
|
}
|
|
|
- boolean systemDataStream = randomBoolean();
|
|
|
boolean replicated = randomBoolean();
|
|
|
DataStream dataStream = new DataStream(
|
|
|
randomAlphaOfLength(50),
|
|
@@ -147,28 +191,59 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
clusterStateBuilder.metadata(metadataBuilder);
|
|
|
return clusterStateBuilder.build();
|
|
|
});
|
|
|
- int expectedMinimumRetention = minRetention.get() == Long.MAX_VALUE ? 0 : minRetention.intValue();
|
|
|
- int expectedMaximumRetention = maxRetention.get() == Long.MIN_VALUE ? 0 : maxRetention.intValue();
|
|
|
- double expectedAverageRetention = countLifecycleWithRetention.get() == 0
|
|
|
+
|
|
|
+ int retainedDataStreams = dataStreamsWithRetentionCount.get() + dataStreamsWithDefaultRetentionCount.get();
|
|
|
+
|
|
|
+ int expectedMinimumDataRetention = minRetention.get() == Long.MAX_VALUE ? 0 : minRetention.intValue();
|
|
|
+ int expectedMinimumEffectiveRetention = dataStreamsWithDefaultRetentionCount.get() > 0
|
|
|
+ ? (int) Math.min(minRetention.get(), defaultRetention.getMillis())
|
|
|
+ : expectedMinimumDataRetention;
|
|
|
+
|
|
|
+ int expectedMaximumDataRetention = maxRetention.get() == Long.MIN_VALUE ? 0 : maxRetention.intValue();
|
|
|
+ int expectedMaximumEffectiveRetention = dataStreamsWithDefaultRetentionCount.get() > 0
|
|
|
+ ? (int) Math.max(maxRetention.get(), defaultRetention.getMillis())
|
|
|
+ : expectedMaximumDataRetention;
|
|
|
+
|
|
|
+ double expectedAverageDataRetention = dataStreamsWithRetentionCount.get() == 0
|
|
|
? 0.0
|
|
|
- : totalRetentionTimes.doubleValue() / countLifecycleWithRetention.get();
|
|
|
- assertUsageResults(
|
|
|
- totalCount.intValue(),
|
|
|
- expectedMinimumRetention,
|
|
|
- expectedMaximumRetention,
|
|
|
- expectedAverageRetention,
|
|
|
- useDefaultRolloverConfig
|
|
|
- );
|
|
|
+ : totalRetentionTimes.doubleValue() / dataStreamsWithRetentionCount.get();
|
|
|
+ double expectedAverageEffectiveRetention = dataStreamsWithDefaultRetentionCount.get() > 0
|
|
|
+ ? (totalRetentionTimes.doubleValue() + dataStreamsWithDefaultRetentionCount.get() * defaultRetention.getMillis())
|
|
|
+ / retainedDataStreams
|
|
|
+ : expectedAverageDataRetention;
|
|
|
+
|
|
|
+ Map<String, Object> map = getLifecycleUsage();
|
|
|
+ assertThat(map.get("available"), equalTo(true));
|
|
|
+ assertThat(map.get("enabled"), equalTo(true));
|
|
|
+ assertThat(map.get("count"), equalTo(dataStreamsWithLifecycleCount.intValue()));
|
|
|
+ assertThat(map.get("default_rollover_used"), equalTo(useDefaultRolloverConfig));
|
|
|
+
|
|
|
+ Map<String, Object> dataRetentionMap = (Map<String, Object>) map.get("data_retention");
|
|
|
+ assertThat(dataRetentionMap.get("configured_data_streams"), equalTo(dataStreamsWithRetentionCount.get()));
|
|
|
+ if (dataStreamsWithRetentionCount.get() > 0) {
|
|
|
+ assertThat(dataRetentionMap.get("minimum_millis"), equalTo(expectedMinimumDataRetention));
|
|
|
+ assertThat(dataRetentionMap.get("maximum_millis"), equalTo(expectedMaximumDataRetention));
|
|
|
+ assertThat(dataRetentionMap.get("average_millis"), equalTo(expectedAverageDataRetention));
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> effectieRetentionMap = (Map<String, Object>) map.get("effective_retention");
|
|
|
+ assertThat(effectieRetentionMap.get("retained_data_streams"), equalTo(retainedDataStreams));
|
|
|
+ if (retainedDataStreams > 0) {
|
|
|
+ assertThat(effectieRetentionMap.get("minimum_millis"), equalTo(expectedMinimumEffectiveRetention));
|
|
|
+ assertThat(effectieRetentionMap.get("maximum_millis"), equalTo(expectedMaximumEffectiveRetention));
|
|
|
+ assertThat(effectieRetentionMap.get("average_millis"), equalTo(expectedAverageEffectiveRetention));
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Map<String, Object>> globalRetentionMap = (Map<String, Map<String, Object>>) map.get("global_retention");
|
|
|
+ assertThat(globalRetentionMap.get("max").get("defined"), equalTo(false));
|
|
|
+ assertThat(globalRetentionMap.get("default").get("defined"), equalTo(useDefaultRetention));
|
|
|
+ if (useDefaultRetention) {
|
|
|
+ assertThat(globalRetentionMap.get("default").get("affected_data_streams"), equalTo(dataStreamsWithDefaultRetentionCount.get()));
|
|
|
+ assertThat(globalRetentionMap.get("default").get("retention_millis"), equalTo((int) defaultRetention.getMillis()));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- private void assertUsageResults(
|
|
|
- int count,
|
|
|
- int minimumRetention,
|
|
|
- int maximumRetention,
|
|
|
- double averageRetention,
|
|
|
- boolean defaultRolloverUsed
|
|
|
- ) throws Exception {
|
|
|
+ private Map<String, Object> getLifecycleUsage() throws IOException {
|
|
|
XPackUsageFeatureResponse response = safeGet(client().execute(DATA_STREAM_LIFECYCLE, new XPackUsageRequest(SAFE_AWAIT_TIMEOUT)));
|
|
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
|
|
builder = response.getUsage().toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
@@ -177,17 +252,7 @@ public class DataStreamLifecycleUsageTransportActionIT extends ESIntegTestCase {
|
|
|
true,
|
|
|
XContentType.JSON
|
|
|
);
|
|
|
-
|
|
|
- Map<String, Object> map = tuple.v2();
|
|
|
- assertThat(map.get("available"), equalTo(true));
|
|
|
- assertThat(map.get("enabled"), equalTo(true));
|
|
|
- assertThat(map.get("count"), equalTo(count));
|
|
|
- assertThat(map.get("default_rollover_used"), equalTo(defaultRolloverUsed));
|
|
|
- Map<String, Object> retentionMap = (Map<String, Object>) map.get("retention");
|
|
|
- assertThat(retentionMap.size(), equalTo(3));
|
|
|
- assertThat(retentionMap.get("minimum_millis"), equalTo(minimumRetention));
|
|
|
- assertThat(retentionMap.get("maximum_millis"), equalTo(maximumRetention));
|
|
|
- assertThat(retentionMap.get("average_millis"), equalTo(averageRetention));
|
|
|
+ return tuple.v2();
|
|
|
}
|
|
|
|
|
|
/*
|