mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-27 18:38:41 +00:00
Replaced _data_stream_timestamp meta field's 'path' option with 'enabled' option (#59727)
Backport #59503 to 7.x and adjusted exception messages. Relates to #59076
This commit is contained in:
parent
8fdaed0642
commit
0096238df1
@ -269,9 +269,10 @@ public class ComposableIndexTemplate extends AbstractDiffable<ComposableIndexTem
|
||||
/**
|
||||
* @return a mapping snippet for a backing index with `_data_stream_timestamp` meta field mapper properly configured.
|
||||
*/
|
||||
public Map<String, Object> getDataSteamMappingSnippet() {
|
||||
public Map<String, Object> getDataStreamMappingSnippet() {
|
||||
// _data_stream_timestamp meta fields default to @timestamp:
|
||||
return singletonMap(MapperService.SINGLE_MAPPING_NAME, singletonMap("_data_stream_timestamp",
|
||||
singletonMap("path", FIXED_TIMESTAMP_FIELD)));
|
||||
singletonMap("enabled", true)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -180,10 +180,11 @@ public class MetadataCreateDataStreamService {
|
||||
|
||||
Map<String, Object> parsedTemplateMapping =
|
||||
MapperService.parseMapping(NamedXContentRegistry.EMPTY, mapperService.documentMapper().mappingSource().string());
|
||||
String configuredPath = ObjectPath.eval("_doc._data_stream_timestamp.path", parsedTemplateMapping);
|
||||
if (timestampFieldName.equals(configuredPath) == false) {
|
||||
throw new IllegalArgumentException("[_data_stream_timestamp] meta field doesn't point to data stream timestamp field [" +
|
||||
timestampFieldName + "]");
|
||||
Boolean enabled = ObjectPath.eval("_doc._data_stream_timestamp.enabled", parsedTemplateMapping);
|
||||
// Sanity check: if this fails then somehow the mapping for _data_stream_timestamp has been overwritten and
|
||||
// that would be a bug.
|
||||
if (enabled == null || enabled == false) {
|
||||
throw new IllegalStateException("[_data_stream_timestamp] meta field has been disabled");
|
||||
}
|
||||
|
||||
// Sanity check (this validation logic should already have been executed when merging mappings):
|
||||
|
@ -958,7 +958,7 @@ public class MetadataIndexTemplateService {
|
||||
// Only if template has data stream definition this should be added and
|
||||
// adding this template last, since _timestamp field should have highest precedence:
|
||||
Optional.ofNullable(template.getDataStreamTemplate())
|
||||
.map(ComposableIndexTemplate.DataStreamTemplate::getDataSteamMappingSnippet)
|
||||
.map(ComposableIndexTemplate.DataStreamTemplate::getDataStreamMappingSnippet)
|
||||
.map(mapping -> {
|
||||
try (XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent())) {
|
||||
builder.value(mapping);
|
||||
|
@ -1556,11 +1556,11 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||
public MetadataFieldMapper.Builder<?> parse(String name,
|
||||
Map<String, Object> node,
|
||||
ParserContext parserContext) throws MapperParsingException {
|
||||
String path = (String) node.remove("path");
|
||||
Boolean enabled = (Boolean) node.remove("enabled");
|
||||
return new MetadataFieldMapper.Builder(name, new FieldType()) {
|
||||
@Override
|
||||
public MetadataFieldMapper build(Mapper.BuilderContext context) {
|
||||
return newInstance(path);
|
||||
return newInstance(enabled);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1570,7 +1570,7 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||
return newInstance(null);
|
||||
}
|
||||
|
||||
MetadataFieldMapper newInstance(String path) {
|
||||
MetadataFieldMapper newInstance(Boolean enabled) {
|
||||
FieldType fieldType = new FieldType();
|
||||
fieldType.freeze();
|
||||
MappedFieldType mappedFieldType =
|
||||
@ -1603,12 +1603,12 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (path == null) {
|
||||
if (enabled == null) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
builder.startObject(simpleName());
|
||||
builder.field("path", path);
|
||||
builder.field("enabled", enabled);
|
||||
return builder.endObject();
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public final class DataStreamTestHelper {
|
||||
public static String generateMapping(String timestampFieldName, String type) {
|
||||
return "{\n" +
|
||||
" \"_data_stream_timestamp\": {\n" +
|
||||
" \"path\": \"" + timestampFieldName + "\"\n" +
|
||||
" \"enabled\": true\n" +
|
||||
" }," +
|
||||
" \"properties\": {\n" +
|
||||
" \"" + timestampFieldName + "\": {\n" +
|
||||
|
@ -397,7 +397,7 @@ public class DataStreamIT extends ESIntegTestCase {
|
||||
);
|
||||
assertThat(
|
||||
e.getCause().getCause().getMessage(),
|
||||
equalTo("the configured timestamp field [@timestamp] is of type [keyword], but [date,date_nanos] is expected")
|
||||
equalTo("data stream timestamp field [@timestamp] is of type [keyword], but [date,date_nanos] is expected")
|
||||
);
|
||||
}
|
||||
|
||||
@ -632,7 +632,7 @@ public class DataStreamIT extends ESIntegTestCase {
|
||||
"properties",
|
||||
Map.of("@timestamp", Map.of("type", "date")),
|
||||
"_data_stream_timestamp",
|
||||
Map.of("path", "@timestamp")
|
||||
Map.of("enabled", true)
|
||||
);
|
||||
GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("logs-foobar").get();
|
||||
assertThat(getMappingsResponse.getMappings().size(), equalTo(2));
|
||||
@ -643,7 +643,7 @@ public class DataStreamIT extends ESIntegTestCase {
|
||||
"properties",
|
||||
Map.of("@timestamp", Map.of("type", "date"), "my_field", Map.of("type", "keyword")),
|
||||
"_data_stream_timestamp",
|
||||
Map.of("path", "@timestamp")
|
||||
Map.of("enabled", true)
|
||||
);
|
||||
client().admin()
|
||||
.indices()
|
||||
|
@ -15,6 +15,7 @@ import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
import org.elasticsearch.index.mapper.DateFieldMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentFieldMappers;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
@ -40,6 +41,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
public static final String NAME = "_data_stream_timestamp";
|
||||
private static final String DEFAULT_PATH = "@timestamp";
|
||||
|
||||
public static class Defaults {
|
||||
|
||||
@ -78,19 +80,19 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
public static class Builder extends MetadataFieldMapper.Builder<Builder> {
|
||||
|
||||
private String path;
|
||||
private boolean enabled;
|
||||
|
||||
public Builder() {
|
||||
super(NAME, Defaults.TIMESTAMP_FIELD_TYPE);
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataFieldMapper build(BuilderContext context) {
|
||||
return new DataStreamTimestampFieldMapper(fieldType, new TimestampFieldType(), path);
|
||||
return new DataStreamTimestampFieldMapper(fieldType, new TimestampFieldType(), enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,8 +106,8 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
String fieldName = entry.getKey();
|
||||
Object fieldNode = entry.getValue();
|
||||
if (fieldName.equals("path")) {
|
||||
builder.setPath((String) fieldNode);
|
||||
if (fieldName.equals("enabled")) {
|
||||
builder.setEnabled(XContentMapValues.nodeBooleanValue(fieldNode, name + ".enabled"));
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@ -114,32 +116,34 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
@Override
|
||||
public MetadataFieldMapper getDefault(MappedFieldType fieldType, ParserContext parserContext) {
|
||||
return new DataStreamTimestampFieldMapper(Defaults.TIMESTAMP_FIELD_TYPE, new TimestampFieldType(), null);
|
||||
return new DataStreamTimestampFieldMapper(Defaults.TIMESTAMP_FIELD_TYPE, new TimestampFieldType(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private final String path;
|
||||
private final boolean enabled;
|
||||
|
||||
private DataStreamTimestampFieldMapper(FieldType fieldType, MappedFieldType mappedFieldType, String path) {
|
||||
private DataStreamTimestampFieldMapper(FieldType fieldType, MappedFieldType mappedFieldType, boolean enabled) {
|
||||
super(fieldType, mappedFieldType);
|
||||
this.path = path;
|
||||
this.path = DEFAULT_PATH;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void validate(DocumentFieldMappers lookup) {
|
||||
if (path == null) {
|
||||
if (enabled == false) {
|
||||
// not configured, so skip the validation
|
||||
return;
|
||||
}
|
||||
|
||||
Mapper mapper = lookup.getMapper(path);
|
||||
if (mapper == null) {
|
||||
throw new IllegalArgumentException("the configured timestamp field [" + path + "] does not exist");
|
||||
throw new IllegalArgumentException("data stream timestamp field [" + path + "] does not exist");
|
||||
}
|
||||
|
||||
if (DateFieldMapper.CONTENT_TYPE.equals(mapper.typeName()) == false
|
||||
&& DateFieldMapper.DATE_NANOS_CONTENT_TYPE.equals(mapper.typeName()) == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"the configured timestamp field ["
|
||||
"data stream timestamp field ["
|
||||
+ path
|
||||
+ "] is of type ["
|
||||
+ mapper.typeName()
|
||||
@ -153,19 +157,19 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
DateFieldMapper dateFieldMapper = (DateFieldMapper) mapper;
|
||||
if (dateFieldMapper.fieldType().isSearchable() == false) {
|
||||
throw new IllegalArgumentException("the configured timestamp field [" + path + "] is not indexed");
|
||||
throw new IllegalArgumentException("data stream timestamp field [" + path + "] is not indexed");
|
||||
}
|
||||
if (dateFieldMapper.fieldType().hasDocValues() == false) {
|
||||
throw new IllegalArgumentException("the configured timestamp field [" + path + "] doesn't have doc values");
|
||||
throw new IllegalArgumentException("data stream timestamp field [" + path + "] doesn't have doc values");
|
||||
}
|
||||
if (dateFieldMapper.getNullValue() != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"the configured timestamp field [" + path + "] has disallowed [null_value] attribute specified"
|
||||
"data stream timestamp field [" + path + "] has disallowed [null_value] attribute specified"
|
||||
);
|
||||
}
|
||||
if (dateFieldMapper.getIgnoreMalformed().explicit()) {
|
||||
throw new IllegalArgumentException(
|
||||
"the configured timestamp field [" + path + "] has disallowed [ignore_malformed] attribute specified"
|
||||
"data stream timestamp field [" + path + "] has disallowed [ignore_malformed] attribute specified"
|
||||
);
|
||||
}
|
||||
|
||||
@ -185,7 +189,7 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
// All other configured attributes are not allowed:
|
||||
if (configuredSettings.isEmpty() == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"the configured timestamp field [@timestamp] has disallowed attributes: " + configuredSettings.keySet()
|
||||
"data stream timestamp field [@timestamp] has disallowed attributes: " + configuredSettings.keySet()
|
||||
);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -193,10 +197,6 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preParse(ParseContext context) throws IOException {}
|
||||
|
||||
@ -208,7 +208,7 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
@Override
|
||||
public void postParse(ParseContext context) throws IOException {
|
||||
if (path == null) {
|
||||
if (enabled == false) {
|
||||
// not configured, so skip the validation
|
||||
return;
|
||||
}
|
||||
@ -228,12 +228,12 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (path == null) {
|
||||
if (enabled == false) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
builder.startObject(simpleName());
|
||||
builder.field("path", path);
|
||||
builder.field("enabled", enabled);
|
||||
return builder.endObject();
|
||||
}
|
||||
|
||||
@ -255,8 +255,8 @@ public class DataStreamTimestampFieldMapper extends MetadataFieldMapper {
|
||||
@Override
|
||||
protected void mergeOptions(FieldMapper other, List<String> conflicts) {
|
||||
DataStreamTimestampFieldMapper otherTimestampFieldMapper = (DataStreamTimestampFieldMapper) other;
|
||||
if (Objects.equals(path, otherTimestampFieldMapper.path) == false) {
|
||||
conflicts.add("cannot update path setting for [_data_stream_timestamp]");
|
||||
if (Objects.equals(enabled, otherTimestampFieldMapper.enabled) == false) {
|
||||
conflicts.add("cannot update enabled setting for [_data_stream_timestamp]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -101,10 +101,10 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "non-existing-field")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
.startObject("my_date_field")
|
||||
.field("type", "date")
|
||||
.endObject()
|
||||
.endObject()
|
||||
@ -117,7 +117,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
() -> createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE)
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("the configured timestamp field [non-existing-field] does not exist"));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] does not exist"));
|
||||
}
|
||||
|
||||
public void testValidateInvalidFieldType() throws IOException {
|
||||
@ -126,7 +126,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -144,7 +144,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
);
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
equalTo("the configured timestamp field [@timestamp] is of type [keyword], but [date,date_nanos] is expected")
|
||||
equalTo("data stream timestamp field [@timestamp] is of type [keyword], but [date,date_nanos] is expected")
|
||||
);
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -171,7 +171,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
() -> createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE)
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("the configured timestamp field [@timestamp] is not indexed"));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] is not indexed"));
|
||||
}
|
||||
|
||||
public void testValidateNotDocValues() throws IOException {
|
||||
@ -180,7 +180,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -197,7 +197,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
() -> createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE)
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("the configured timestamp field [@timestamp] doesn't have doc values"));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] doesn't have doc values"));
|
||||
}
|
||||
|
||||
public void testValidateNullValue() throws IOException {
|
||||
@ -206,7 +206,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -223,7 +223,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
() -> createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE)
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("the configured timestamp field [@timestamp] has disallowed [null_value] attribute specified"));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] has disallowed [null_value] attribute specified"));
|
||||
}
|
||||
|
||||
public void testValidateIgnoreMalformed() throws IOException {
|
||||
@ -232,7 +232,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -251,7 +251,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
);
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
equalTo("the configured timestamp field [@timestamp] has disallowed [ignore_malformed] attribute specified")
|
||||
equalTo("data stream timestamp field [@timestamp] has disallowed [ignore_malformed] attribute specified")
|
||||
);
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_data_stream_timestamp")
|
||||
.field("path", "@timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.startObject("properties")
|
||||
.startObject("@timestamp")
|
||||
@ -278,65 +278,21 @@ public class DataStreamTimestampFieldMapperTests extends ESSingleNodeTestCase {
|
||||
() -> createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE)
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("the configured timestamp field [@timestamp] has disallowed attributes: [store]"));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] has disallowed attributes: [store]"));
|
||||
}
|
||||
|
||||
public void testCannotUpdateTimestampField() throws IOException {
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
String mapping1 =
|
||||
"{\"type\":{\"_data_stream_timestamp\":{\"path\":\"@timestamp\"}, \"properties\": {\"@timestamp\": {\"type\": \"date\"}}}}}";
|
||||
String mapping2 = "{\"type\":{\"_data_stream_timestamp\":{\"path\":\"@timestamp2\"}, \"properties\": {\"@timestamp2\": "
|
||||
"{\"type\":{\"_data_stream_timestamp\":{\"enabled\":false}, \"properties\": {\"@timestamp\": {\"type\": \"date\"}}}}}";
|
||||
String mapping2 = "{\"type\":{\"_data_stream_timestamp\":{\"enabled\":true}, \"properties\": {\"@timestamp2\": "
|
||||
+ "{\"type\": \"date\"},\"@timestamp\": {\"type\": \"date\"}}}})";
|
||||
assertConflicts(mapping1, mapping2, parser, "cannot update path setting for [_data_stream_timestamp]");
|
||||
assertConflicts(mapping1, mapping2, parser, "cannot update enabled setting for [_data_stream_timestamp]");
|
||||
|
||||
mapping1 = "{\"type\":{\"properties\":{\"@timestamp\": {\"type\": \"date\"}}}}}";
|
||||
mapping2 = "{\"type\":{\"_data_stream_timestamp\":{\"path\":\"@timestamp2\"}, \"properties\": "
|
||||
mapping2 = "{\"type\":{\"_data_stream_timestamp\":{\"enabled\":true}, \"properties\": "
|
||||
+ "{\"@timestamp2\": {\"type\": \"date\"},\"@timestamp\": {\"type\": \"date\"}}}})";
|
||||
assertConflicts(mapping1, mapping2, parser, "cannot update path setting for [_data_stream_timestamp]");
|
||||
}
|
||||
|
||||
public void testDifferentTSField() throws IOException {
|
||||
String mapping = "{\n"
|
||||
+ " \"_data_stream_timestamp\": {\n"
|
||||
+ " \"path\": \"event.my_timestamp\"\n"
|
||||
+ " },\n"
|
||||
+ " \"properties\": {\n"
|
||||
+ " \"event\": {\n"
|
||||
+ " \"properties\": {\n"
|
||||
+ " \"my_timestamp\": {\n"
|
||||
+ " \"type\": \"date\""
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }";
|
||||
DocumentMapper docMapper = createIndex("test").mapperService()
|
||||
.merge("type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
|
||||
ParsedDocument doc = docMapper.parse(
|
||||
new SourceToParse(
|
||||
"test",
|
||||
"type",
|
||||
"1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder().startObject().field("event.my_timestamp", "2020-12-12").endObject()),
|
||||
XContentType.JSON
|
||||
)
|
||||
);
|
||||
assertThat(doc.rootDoc().getFields("event.my_timestamp").length, equalTo(2));
|
||||
|
||||
Exception e = expectThrows(
|
||||
MapperException.class,
|
||||
() -> docMapper.parse(
|
||||
new SourceToParse(
|
||||
"test",
|
||||
"type",
|
||||
"1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder().startObject().field("event.timestamp", "2020-12-12").endObject()),
|
||||
XContentType.JSON
|
||||
)
|
||||
)
|
||||
);
|
||||
assertThat(e.getCause().getMessage(), equalTo("data stream timestamp field [event.my_timestamp] is missing"));
|
||||
assertConflicts(mapping1, mapping2, parser, "cannot update enabled setting for [_data_stream_timestamp]");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,20 +33,26 @@ public class MetadataCreateDataStreamServiceTests extends ESTestCase {
|
||||
|
||||
public void testValidateTimestampFieldMappingNoFieldMapping() {
|
||||
Exception e = expectThrows(
|
||||
IllegalArgumentException.class,
|
||||
IllegalStateException.class,
|
||||
() -> validateTimestampFieldMapping("@timestamp", createMapperService("{}"))
|
||||
);
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
equalTo("[_data_stream_timestamp] meta field doesn't point to data stream timestamp field [@timestamp]")
|
||||
);
|
||||
assertThat(e.getMessage(), equalTo("[_data_stream_timestamp] meta field has been disabled"));
|
||||
String mapping1 = "{\n"
|
||||
+ " \"_data_stream_timestamp\": {\n"
|
||||
+ " \"enabled\": false\n"
|
||||
+ " },"
|
||||
+ " \"properties\": {\n"
|
||||
+ " \"@timestamp\": {\n"
|
||||
+ " \"type\": \"date\"\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }";
|
||||
e = expectThrows(IllegalStateException.class, () -> validateTimestampFieldMapping("@timestamp", createMapperService(mapping1)));
|
||||
assertThat(e.getMessage(), equalTo("[_data_stream_timestamp] meta field has been disabled"));
|
||||
|
||||
String mapping = generateMapping("@timestamp2", "date");
|
||||
e = expectThrows(IllegalArgumentException.class, () -> validateTimestampFieldMapping("@timestamp", createMapperService(mapping)));
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
equalTo("[_data_stream_timestamp] meta field doesn't point to data stream timestamp field [@timestamp]")
|
||||
);
|
||||
String mapping2 = generateMapping("@timestamp2", "date");
|
||||
e = expectThrows(IllegalArgumentException.class, () -> validateTimestampFieldMapping("@timestamp", createMapperService(mapping2)));
|
||||
assertThat(e.getMessage(), equalTo("data stream timestamp field [@timestamp] does not exist"));
|
||||
}
|
||||
|
||||
public void testValidateTimestampFieldMappingInvalidFieldType() {
|
||||
@ -57,7 +63,7 @@ public class MetadataCreateDataStreamServiceTests extends ESTestCase {
|
||||
);
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
equalTo("the configured timestamp field [@timestamp] is of type [keyword], " + "but [date,date_nanos] is expected")
|
||||
equalTo("data stream timestamp field [@timestamp] is of type [keyword], " + "but [date,date_nanos] is expected")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -871,6 +871,7 @@ public class FullClusterRestartIT extends AbstractFullClusterRestartTestCase {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testDataStreams() throws Exception {
|
||||
assumeTrue("fail until #59503 is backported to 7.x and 7.9", false);
|
||||
assumeTrue("no data streams in versions before " + Version.V_7_9_0, getOldClusterVersion().onOrAfter(Version.V_7_9_0));
|
||||
if (isRunningAgainstOldCluster()) {
|
||||
createComposableTemplate(client(), "dst", "ds");
|
||||
|
@ -19,6 +19,7 @@ import static org.elasticsearch.upgrades.IndexingIT.assertCount;
|
||||
public class DataStreamsUpgradeIT extends AbstractUpgradeTestCase {
|
||||
|
||||
public void testDataStreams() throws IOException {
|
||||
assumeTrue("fail until #59503 is backported to 7.x and 7.9", false);
|
||||
assumeTrue("data streams supported from 7.9.0", UPGRADE_FROM_VERSION.onOrAfter(Version.V_7_9_0));
|
||||
if (CLUSTER_TYPE == ClusterType.OLD) {
|
||||
String requestBody = "{\n" +
|
||||
|
Loading…
x
Reference in New Issue
Block a user