Skip to content
Open
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
37ae32a
Hash once to create routing hash and _tsid
felixbarny Aug 4, 2025
cffae3e
Merge branch 'main' into tsdb-hash-once
felixbarny Aug 8, 2025
41d0e28
[CI] Auto commit changes from spotless
Aug 8, 2025
3cbc3f3
Merge branch 'main' into tsdb-hash-once
felixbarny Aug 8, 2025
877de11
Add notice file for hash4j
felixbarny Aug 8, 2025
c71db07
Use optimized text
felixbarny Aug 7, 2025
0222d93
Fix DataStreamIndexSettingsProviderTests
felixbarny Aug 9, 2025
a1be48b
Update index.dimensions on mapping updates
felixbarny Aug 11, 2025
1734649
Apply spotless suggestions
felixbarny Aug 11, 2025
d449b79
Make index.dimensions a private setting
felixbarny Aug 11, 2025
8831b1d
Adjust TSDBPassthroughIndexingIT
felixbarny Aug 11, 2025
a915bcf
The index.dimensions settingn should be replicated
felixbarny Aug 11, 2025
2ff61f6
Fix IndexRoutingTests
felixbarny Aug 11, 2025
002fd43
Make downsampling aware of index.dimensions
felixbarny Aug 11, 2025
2ccc3c2
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 11, 2025
6282cd4
Fix rest compatibility tests by excluding test that make assertions o…
felixbarny Aug 11, 2025
fae55a5
Fix condition for system provided settings
felixbarny Aug 11, 2025
b41a88d
Adjust TsdbDataStreamRestIT
felixbarny Aug 11, 2025
5037489
Remove unnecessary index version
felixbarny Aug 11, 2025
dfc2d94
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 11, 2025
330aa94
[CI] Auto commit changes from spotless
Aug 11, 2025
a409a95
Allow the creation of downsampling indices to use the private index.d…
felixbarny Aug 12, 2025
3f8d05e
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 12, 2025
cfe59a7
[CI] Auto commit changes from spotless
Aug 12, 2025
23b9d6c
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 18, 2025
7da8667
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 19, 2025
3619db7
Only add IP dimensions if RoutingFields is not a noop
felixbarny Aug 19, 2025
8b51566
Address comments from review
felixbarny Aug 19, 2025
7cb545c
[CI] Auto commit changes from spotless
Aug 19, 2025
11a3c7e
Replace hash4j with BufferedMurmur3Hasher
felixbarny Aug 20, 2025
008fb9b
[CI] Auto commit changes from spotless
Aug 20, 2025
96e751d
Remove commented out method
felixbarny Aug 21, 2025
e0be278
Store dimensions in custom metadata rather than an index setting
felixbarny Aug 21, 2025
b42286f
Revert adding ability to set private settings when system-provided
felixbarny Aug 21, 2025
d29ce61
[CI] Auto commit changes from spotless
Aug 21, 2025
4424e60
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 22, 2025
f921643
Remove unused licenses
felixbarny Aug 22, 2025
5cd1c28
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 22, 2025
9aa7e50
Remove leftover reference to INDEX_DIMENSIONS
felixbarny Aug 22, 2025
440f5bc
Copy custom metadata to downsampling index
felixbarny Aug 23, 2025
1912155
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 23, 2025
5c6b2d1
Remove unnecessary interface
felixbarny Aug 24, 2025
fda4410
Add test for transferCustomMetadata
felixbarny Aug 24, 2025
a9cfee8
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 25, 2025
96b31e7
[CI] Auto commit changes from spotless
Aug 25, 2025
eb913fd
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 25, 2025
a7b80c7
Merge remote-tracking branch 'felixbarny/tsdb-hash-once' into tsdb-ha…
felixbarny Aug 25, 2025
84751e7
[CI] Auto commit changes from spotless
Aug 25, 2025
df95ce7
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 25, 2025
a4d7cf6
Fix tests after merging
felixbarny Aug 25, 2025
905609e
Merge remote-tracking branch 'felixbarny/tsdb-hash-once' into tsdb-ha…
felixbarny Aug 25, 2025
6bf6b01
[CI] Auto commit changes from spotless
Aug 25, 2025
b9cc6d4
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 25, 2025
db8c8d8
Address review comments
felixbarny Aug 25, 2025
a29f38c
Fix index simulation
felixbarny Aug 26, 2025
bef7b1f
Fix tests
felixbarny Aug 26, 2025
e58eed4
[CI] Auto commit changes from spotless
Aug 26, 2025
b889fce
Fix copying of custom index metadata
felixbarny Aug 26, 2025
1de9d92
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 26, 2025
f081b9b
Merge remote-tracking branch 'felixbarny/tsdb-hash-once' into tsdb-ha…
felixbarny Aug 26, 2025
40e7ee7
[CI] Auto commit changes from spotless
Aug 26, 2025
a643443
Revert changes in IndexRequestBuilder
felixbarny Aug 26, 2025
a8fa403
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Aug 26, 2025
40ab041
Add index version
felixbarny Aug 26, 2025
556a00e
Merge remote-tracking branch 'origin/main' into tsdb-hash-once
felixbarny Sep 1, 2025
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
4 changes: 4 additions & 0 deletions modules/data-streams/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ tasks.named("yamlRestCompatTestTransform").configure({ task ->
task.skipTest("data_stream/30_auto_create_data_stream/Don't initialize failure store during data stream auto-creation on successful index", "Configuring the failure store via data stream templates is not supported anymore.")

task.skipTest("data_stream/150_tsdb/TSDB failures go to failure store", "Configuring the failure store via data stream templates is not supported anymore.")
// TODO remove these after removing exact _tsid assertions in 8.x
task.skipTest("data_stream/150_tsdb/dynamic templates", "The _tsid has changed in a new index version. This tests verifies the exact _tsid value with is too brittle for compatibility testing.")
task.skipTest("data_stream/150_tsdb/dynamic templates - conflicting aliases", "The _tsid has changed in a new index version. This tests verifies the exact _tsid value with is too brittle for compatibility testing.")
task.skipTest("data_stream/150_tsdb/dynamic templates with nesting", "The _tsid has changed in a new index version. This tests verifies the exact _tsid value with is too brittle for compatibility testing.")

task.skipTest("data_stream/170_modify_data_stream/Modify a data stream's failure store", "Configuring the failure store via data stream templates is not supported anymore.")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.TransportPutMappingAction;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
Expand All @@ -24,6 +26,7 @@
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.bulk.IndexDocFailureStoreStatus;
import org.elasticsearch.action.datastreams.CreateDataStreamAction;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
Expand All @@ -34,6 +37,7 @@
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.FormatNames;
Expand All @@ -44,7 +48,6 @@
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.ReindexAction;
import org.elasticsearch.index.reindex.ReindexRequest;
import org.elasticsearch.indices.InvalidIndexTemplateException;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.reindex.ReindexPlugin;
import org.elasticsearch.rest.RestStatus;
Expand All @@ -58,6 +61,7 @@
import java.time.temporal.ChronoUnit;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import static org.elasticsearch.test.MapMatcher.assertMap;
Expand Down Expand Up @@ -296,10 +300,10 @@ public void testInvalidTsdbTemplatesNoTimeSeriesDimensionAttribute() throws Exce
.build()
);
var e = expectThrows(
InvalidIndexTemplateException.class,
IllegalArgumentException.class,
() -> client().execute(TransportPutComposableIndexTemplateAction.TYPE, request).actionGet()
);
assertThat(e.getMessage(), containsString("[index.mode=time_series] requires a non-empty [index.routing_path]"));
assertThat(e.getCause().getMessage(), containsString("[index.mode=time_series] requires a non-empty [index.routing_path]"));
}
}

Expand All @@ -320,16 +324,12 @@ public void testTsdbTemplatesNoKeywordFieldType() throws Exception {
ComposableIndexTemplate.builder()
.indexPatterns(List.of("k8s*"))
.template(
new Template(
Settings.builder().put("index.mode", "time_series").put("index.routing_path", "metricset").build(),
new CompressedXContent(mappingTemplate),
null
)
new Template(Settings.builder().put("index.mode", "time_series").build(), new CompressedXContent(mappingTemplate), null)
)
.dataStreamTemplate(new ComposableIndexTemplate.DataStreamTemplate(false, false))
.build()
);
client().execute(TransportPutComposableIndexTemplateAction.TYPE, request).actionGet();
assertAcked(client().execute(TransportPutComposableIndexTemplateAction.TYPE, request));
}

public void testInvalidTsdbTemplatesMissingSettings() throws Exception {
Expand Down Expand Up @@ -621,6 +621,191 @@ public void testReindexing() throws Exception {
);
}

public void testAddDimensionToMapping() throws Exception {
String dataStreamName = "my-ds";
var putTemplateRequest = new TransportPutComposableIndexTemplateAction.Request("id");
putTemplateRequest.indexTemplate(
ComposableIndexTemplate.builder()
.indexPatterns(List.of(dataStreamName))
.template(
new Template(
Settings.builder().put("index.mode", "time_series").build(),
new CompressedXContent(MAPPING_TEMPLATE),
null
)
)
.dataStreamTemplate(new ComposableIndexTemplate.DataStreamTemplate(false, false))
.build()
);
assertAcked(client().execute(TransportPutComposableIndexTemplateAction.TYPE, putTemplateRequest));

// create data stream
CreateDataStreamAction.Request createDsRequest = new CreateDataStreamAction.Request(
TEST_REQUEST_TIMEOUT,
TEST_REQUEST_TIMEOUT,
"my-ds"
);
assertAcked(client().execute(CreateDataStreamAction.INSTANCE, createDsRequest));

assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of()));

// put mapping with k8s.pod.uid as another time series dimension
var putMappingRequest = new PutMappingRequest(dataStreamName).source("""
{
"properties": {
"k8s.pod.name": {
"type": "keyword",
"time_series_dimension": true
}
}
}
""", XContentType.JSON);
assertAcked(client().execute(TransportPutMappingAction.TYPE, putMappingRequest).actionGet());

assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of()));

indexWithPodNames(dataStreamName, Instant.now(), Map.of(), "dog", "cat");
}

public void testDynamicStringDimensions() throws Exception {
String dataStreamName = "my-ds";
var putTemplateRequest = new TransportPutComposableIndexTemplateAction.Request("id");
putTemplateRequest.indexTemplate(
ComposableIndexTemplate.builder()
.indexPatterns(List.of(dataStreamName))
.template(new Template(Settings.builder().put("index.mode", "time_series").build(), new CompressedXContent("""
{
"_doc": {
"dynamic_templates": [
{
"labels": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword",
"time_series_dimension": true
}
}
}
],
"properties": {
"@timestamp": {
"type": "date"
},
"metricset": {
"type": "keyword",
"time_series_dimension": true
}
}
}
}"""), null))
.dataStreamTemplate(new ComposableIndexTemplate.DataStreamTemplate(false, false))
.build()
);
assertAcked(client().execute(TransportPutComposableIndexTemplateAction.TYPE, putTemplateRequest));

CreateDataStreamAction.Request createDsRequest = new CreateDataStreamAction.Request(
TEST_REQUEST_TIMEOUT,
TEST_REQUEST_TIMEOUT,
"my-ds"
);
assertAcked(client().execute(CreateDataStreamAction.INSTANCE, createDsRequest));

// doesn't populate the time_series_dimensions custom metadata because the "labels" dynamic template doesn't have a path_math
assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of("metricset")));

// index doc
BulkResponse bulkResponse = client().prepareBulk()
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.add(
client().prepareIndex(dataStreamName)
.setOpType(DocWriteRequest.OpType.CREATE)
.setSource(DOC.replace("$time", formatInstant(Instant.now())), XContentType.JSON)
)
.get();
assertThat(bulkResponse.hasFailures(), is(false));

assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of("metricset")));
}

public void testDynamicDimensions() throws Exception {
String dataStreamName = "my-ds";
var putTemplateRequest = new TransportPutComposableIndexTemplateAction.Request("id");
putTemplateRequest.indexTemplate(
ComposableIndexTemplate.builder()
.indexPatterns(List.of(dataStreamName))
.template(new Template(Settings.builder().put("index.mode", "time_series").build(), new CompressedXContent("""

{
"_doc": {
"dynamic_templates": [
{
"label": {
"mapping": {
"type": "keyword",
"time_series_dimension": true
}
}
}
],
"properties": {
"@timestamp": {
"type": "date"
},
"metricset": {
"type": "keyword",
"time_series_dimension": true
}
}
}
}"""), null))
.dataStreamTemplate(new ComposableIndexTemplate.DataStreamTemplate(false, false))
.build()
);
assertAcked(client().execute(TransportPutComposableIndexTemplateAction.TYPE, putTemplateRequest));

CreateDataStreamAction.Request createDsRequest = new CreateDataStreamAction.Request(
TEST_REQUEST_TIMEOUT,
TEST_REQUEST_TIMEOUT,
"my-ds"
);
assertAcked(client().execute(CreateDataStreamAction.INSTANCE, createDsRequest));

// doesn't populate the time_series_dimensions custom metadata because the "label" dynamic template doesn't have a path_math
assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of("metricset")));

// index doc
indexWithPodNames(dataStreamName, Instant.now(), Map.of("k8s.pod.name", "label"), "dog", "cat");

assertThat(getSetting(dataStreamName, IndexMetadata.INDEX_ROUTING_PATH), equalTo(List.of("metricset")));
}

private void indexWithPodNames(String dataStreamName, Instant timestamp, Map<String, String> dynamicTemplates, String... podNames) {
// index doc
BulkRequestBuilder bulkRequestBuilder = client().prepareBulk();
bulkRequestBuilder.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
for (String podName : podNames) {
bulkRequestBuilder.add(
client().prepareIndex(dataStreamName)
.setOpType(DocWriteRequest.OpType.CREATE)
.setSource(DOC.replace("$time", formatInstant(timestamp)).replace("dog", podName), XContentType.JSON)
.request()
.setDynamicTemplates(dynamicTemplates)
);
}

BulkResponse bulkResponse = bulkRequestBuilder.get();
assertThat(bulkResponse.hasFailures(), is(false));
}

private <T> T getSetting(String dataStreamName, Setting<T> setting) {
GetIndexResponse getIndexResponse = safeGet(
indicesAdmin().getIndex(new GetIndexRequest(TEST_REQUEST_TIMEOUT).indices(dataStreamName))
);
assertThat(getIndexResponse.getIndices().length, equalTo(1));
Settings settings = getIndexResponse.getSettings().get(getIndexResponse.getIndices()[0]);
return setting.get(settings);
}

static String formatInstant(Instant instant) {
return DateFormatter.forPattern(FormatNames.STRICT_DATE_OPTIONAL_TIME.getName()).format(instant);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public void testIndexingGettingAndSearching() throws Exception {

// validate index:
var getIndexResponse = client().admin().indices().getIndex(new GetIndexRequest(TEST_REQUEST_TIMEOUT).indices(index)).actionGet();
assertThat(getIndexResponse.getSettings().get(index).get("index.routing_path"), equalTo("[attributes.*]"));
assertThat(getIndexResponse.getSettings().get(index).hasValue("index.routing_path"), equalTo(false));
// validate mapping
var mapping = getIndexResponse.mappings().get(index).getSourceAsMap();
assertMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.Set;

import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.backingIndexEqualTo;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -432,10 +431,7 @@ public void testSimulateTsdbDataStreamTemplate() throws Exception {
assertThat(ObjectPath.evaluate(responseBody, "template.settings.index.mode"), equalTo("time_series"));
assertThat(ObjectPath.evaluate(responseBody, "template.settings.index.time_series.start_time"), notNullValue());
assertThat(ObjectPath.evaluate(responseBody, "template.settings.index.time_series.end_time"), notNullValue());
assertThat(
ObjectPath.evaluate(responseBody, "template.settings.index.routing_path"),
containsInAnyOrder("metricset", "k8s.pod.uid", "pod.labels.*")
);
assertThat(ObjectPath.evaluate(responseBody, "template.settings.index.routing_path"), nullValue());
assertThat(ObjectPath.evaluate(responseBody, "overlapping"), empty());
}

Expand Down
Loading