mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
parent
312f8315d3
commit
fe7818af04
23 changed files with 163 additions and 135 deletions
|
@ -137,7 +137,7 @@ public abstract class RestCompatTestTransformTask extends DefaultTask {
|
||||||
// However, the folder can be arbitrarily nest so, a == a1/a2/a3, and the test name can include forward slashes, so c == c1/c2/c3
|
// However, the folder can be arbitrarily nest so, a == a1/a2/a3, and the test name can include forward slashes, so c == c1/c2/c3
|
||||||
// So we also need to support a1/a2/a3/b/c1/c2/c3
|
// So we also need to support a1/a2/a3/b/c1/c2/c3
|
||||||
|
|
||||||
String[] testParts = fullTestName.split("/");
|
String[] testParts = fullTestName.split("/", 3);
|
||||||
if (testParts.length < 3) {
|
if (testParts.length < 3) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"To skip tests, all 3 parts [folder/file/test name] must be defined. found [" + fullTestName + "]"
|
"To skip tests, all 3 parts [folder/file/test name] must be defined. found [" + fullTestName + "]"
|
||||||
|
|
10
docs/changelog/116689.yaml
Normal file
10
docs/changelog/116689.yaml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pr: 116689
|
||||||
|
summary: Deprecate `_source.mode` in mappings
|
||||||
|
area: Mapping
|
||||||
|
type: deprecation
|
||||||
|
issues: []
|
||||||
|
deprecation:
|
||||||
|
title: Deprecate `_source.mode` in mappings
|
||||||
|
area: Mapping
|
||||||
|
details: Configuring `_source.mode` in mappings is deprecated and will be removed in future versions. Use `index.mapping.source.mode` index setting instead.
|
||||||
|
impact: Use `index.mapping.source.mode` index setting instead
|
|
@ -17,7 +17,6 @@ import org.elasticsearch.client.RestClient;
|
||||||
import org.elasticsearch.common.network.InetAddresses;
|
import org.elasticsearch.common.network.InetAddresses;
|
||||||
import org.elasticsearch.common.time.DateFormatter;
|
import org.elasticsearch.common.time.DateFormatter;
|
||||||
import org.elasticsearch.common.time.FormatNames;
|
import org.elasticsearch.common.time.FormatNames;
|
||||||
import org.elasticsearch.test.MapMatcher;
|
|
||||||
import org.elasticsearch.test.cluster.ElasticsearchCluster;
|
import org.elasticsearch.test.cluster.ElasticsearchCluster;
|
||||||
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
|
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
|
@ -30,9 +29,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.elasticsearch.test.MapMatcher.assertMap;
|
|
||||||
import static org.elasticsearch.test.MapMatcher.matchesMap;
|
|
||||||
|
|
||||||
public class LogsIndexModeFullClusterRestartIT extends ParameterizedFullClusterRestartTestCase {
|
public class LogsIndexModeFullClusterRestartIT extends ParameterizedFullClusterRestartTestCase {
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
|
@ -169,22 +165,16 @@ public class LogsIndexModeFullClusterRestartIT extends ParameterizedFullClusterR
|
||||||
assertOK(bulkIndexResponse);
|
assertOK(bulkIndexResponse);
|
||||||
assertThat(entityAsMap(bulkIndexResponse).get("errors"), Matchers.is(false));
|
assertThat(entityAsMap(bulkIndexResponse).get("errors"), Matchers.is(false));
|
||||||
|
|
||||||
assertIndexMappingsAndSettings(0, Matchers.nullValue(), matchesMap().extraOk());
|
assertIndexSettings(0, Matchers.nullValue());
|
||||||
assertIndexMappingsAndSettings(
|
assertIndexSettings(1, Matchers.equalTo("logsdb"));
|
||||||
1,
|
|
||||||
Matchers.equalTo("logsdb"),
|
|
||||||
matchesMap().extraOk().entry("_source", Map.of("mode", "synthetic"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertIndexMappingsAndSettings(int backingIndex, final Matcher<Object> indexModeMatcher, final MapMatcher mappingsMatcher)
|
private void assertIndexSettings(int backingIndex, final Matcher<Object> indexModeMatcher) throws IOException {
|
||||||
throws IOException {
|
|
||||||
assertThat(
|
assertThat(
|
||||||
getSettings(client(), getWriteBackingIndex(client(), "logs-apache-production", backingIndex)).get("index.mode"),
|
getSettings(client(), getWriteBackingIndex(client(), "logs-apache-production", backingIndex)).get("index.mode"),
|
||||||
indexModeMatcher
|
indexModeMatcher
|
||||||
);
|
);
|
||||||
assertMap(getIndexMappingAsMap(getWriteBackingIndex(client(), "logs-apache-production", backingIndex)), mappingsMatcher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Request createDataStream(final String dataStreamName) {
|
private static Request createDataStream(final String dataStreamName) {
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.elasticsearch.client.RestClient;
|
||||||
import org.elasticsearch.common.network.InetAddresses;
|
import org.elasticsearch.common.network.InetAddresses;
|
||||||
import org.elasticsearch.common.time.DateFormatter;
|
import org.elasticsearch.common.time.DateFormatter;
|
||||||
import org.elasticsearch.common.time.FormatNames;
|
import org.elasticsearch.common.time.FormatNames;
|
||||||
import org.elasticsearch.test.MapMatcher;
|
|
||||||
import org.elasticsearch.test.cluster.ElasticsearchCluster;
|
import org.elasticsearch.test.cluster.ElasticsearchCluster;
|
||||||
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
|
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
|
@ -30,9 +29,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.elasticsearch.test.MapMatcher.assertMap;
|
|
||||||
import static org.elasticsearch.test.MapMatcher.matchesMap;
|
|
||||||
|
|
||||||
public class LogsIndexModeRollingUpgradeIT extends AbstractRollingUpgradeTestCase {
|
public class LogsIndexModeRollingUpgradeIT extends AbstractRollingUpgradeTestCase {
|
||||||
|
|
||||||
@ClassRule()
|
@ClassRule()
|
||||||
|
@ -160,14 +156,10 @@ public class LogsIndexModeRollingUpgradeIT extends AbstractRollingUpgradeTestCas
|
||||||
assertOK(bulkIndexResponse);
|
assertOK(bulkIndexResponse);
|
||||||
assertThat(entityAsMap(bulkIndexResponse).get("errors"), Matchers.is(false));
|
assertThat(entityAsMap(bulkIndexResponse).get("errors"), Matchers.is(false));
|
||||||
|
|
||||||
assertIndexMappingsAndSettings(0, Matchers.nullValue(), matchesMap().extraOk());
|
assertIndexSettings(0, Matchers.nullValue());
|
||||||
assertIndexMappingsAndSettings(1, Matchers.nullValue(), matchesMap().extraOk());
|
assertIndexSettings(1, Matchers.nullValue());
|
||||||
assertIndexMappingsAndSettings(2, Matchers.nullValue(), matchesMap().extraOk());
|
assertIndexSettings(2, Matchers.nullValue());
|
||||||
assertIndexMappingsAndSettings(
|
assertIndexSettings(3, Matchers.equalTo("logsdb"));
|
||||||
3,
|
|
||||||
Matchers.equalTo("logsdb"),
|
|
||||||
matchesMap().extraOk().entry("_source", Map.of("mode", "synthetic"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,13 +175,11 @@ public class LogsIndexModeRollingUpgradeIT extends AbstractRollingUpgradeTestCas
|
||||||
assertOK(client().performRequest(request));
|
assertOK(client().performRequest(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertIndexMappingsAndSettings(int backingIndex, final Matcher<Object> indexModeMatcher, final MapMatcher mappingsMatcher)
|
private void assertIndexSettings(int backingIndex, final Matcher<Object> indexModeMatcher) throws IOException {
|
||||||
throws IOException {
|
|
||||||
assertThat(
|
assertThat(
|
||||||
getSettings(client(), getWriteBackingIndex(client(), "logs-apache-production", backingIndex)).get("index.mode"),
|
getSettings(client(), getWriteBackingIndex(client(), "logs-apache-production", backingIndex)).get("index.mode"),
|
||||||
indexModeMatcher
|
indexModeMatcher
|
||||||
);
|
);
|
||||||
assertMap(getIndexMappingAsMap(getWriteBackingIndex(client(), "logs-apache-production", backingIndex)), mappingsMatcher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Request createDataStream(final String dataStreamName) {
|
private static Request createDataStream(final String dataStreamName) {
|
||||||
|
|
|
@ -60,4 +60,10 @@ tasks.named("yamlRestCompatTestTransform").configure ({ task ->
|
||||||
task.skipTest("cat.aliases/10_basic/Deprecated local parameter", "CAT APIs not covered by compatibility policy")
|
task.skipTest("cat.aliases/10_basic/Deprecated local parameter", "CAT APIs not covered by compatibility policy")
|
||||||
task.skipTest("cat.shards/10_basic/Help", "sync_id is removed in 9.0")
|
task.skipTest("cat.shards/10_basic/Help", "sync_id is removed in 9.0")
|
||||||
task.skipTest("search/500_date_range/from, to, include_lower, include_upper deprecated", "deprecated parameters are removed in 9.0")
|
task.skipTest("search/500_date_range/from, to, include_lower, include_upper deprecated", "deprecated parameters are removed in 9.0")
|
||||||
|
task.skipTest("tsdb/20_mapping/stored source is supported", "no longer serialize source_mode")
|
||||||
|
task.skipTest("tsdb/20_mapping/Synthetic source", "no longer serialize source_mode")
|
||||||
|
task.skipTest("logsdb/10_settings/create logs index", "no longer serialize source_mode")
|
||||||
|
task.skipTest("logsdb/20_source_mapping/stored _source mode is supported", "no longer serialize source_mode")
|
||||||
|
task.skipTest("logsdb/20_source_mapping/include/exclude is supported with stored _source", "no longer serialize source_mode")
|
||||||
|
task.skipTest("logsdb/20_source_mapping/synthetic _source is default", "no longer serialize source_mode")
|
||||||
})
|
})
|
||||||
|
|
|
@ -76,11 +76,6 @@ create logs index:
|
||||||
- is_true: test
|
- is_true: test
|
||||||
- match: { test.settings.index.mode: "logsdb" }
|
- match: { test.settings.index.mode: "logsdb" }
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.get_mapping:
|
|
||||||
index: test
|
|
||||||
- match: { test.mappings._source.mode: synthetic }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
using default timestamp field mapping:
|
using default timestamp field mapping:
|
||||||
- requires:
|
- requires:
|
||||||
|
|
|
@ -13,10 +13,10 @@ synthetic _source is default:
|
||||||
index:
|
index:
|
||||||
mode: logsdb
|
mode: logsdb
|
||||||
- do:
|
- do:
|
||||||
indices.get:
|
indices.get_settings:
|
||||||
index: test-default-source
|
index: test-default-source
|
||||||
|
- match: { test-default-source.settings.index.mode: logsdb }
|
||||||
- match: { test-default-source.mappings._source.mode: "synthetic" }
|
- match: { test-default-source.settings.index.mapping.source.mode: null }
|
||||||
|
|
||||||
---
|
---
|
||||||
stored _source mode is supported:
|
stored _source mode is supported:
|
||||||
|
@ -28,11 +28,12 @@ stored _source mode is supported:
|
||||||
index:
|
index:
|
||||||
mode: logsdb
|
mode: logsdb
|
||||||
mapping.source.mode: stored
|
mapping.source.mode: stored
|
||||||
- do:
|
|
||||||
indices.get:
|
|
||||||
index: test-stored-source
|
|
||||||
|
|
||||||
- match: { test-stored-source.mappings._source.mode: "stored" }
|
- do:
|
||||||
|
indices.get_settings:
|
||||||
|
index: test-stored-source
|
||||||
|
- match: { test-stored-source.settings.index.mode: logsdb }
|
||||||
|
- match: { test-stored-source.settings.index.mapping.source.mode: stored }
|
||||||
|
|
||||||
---
|
---
|
||||||
disabled _source is not supported:
|
disabled _source is not supported:
|
||||||
|
@ -110,7 +111,6 @@ include/exclude is supported with stored _source:
|
||||||
indices.get:
|
indices.get:
|
||||||
index: test-includes
|
index: test-includes
|
||||||
|
|
||||||
- match: { test-includes.mappings._source.mode: "stored" }
|
|
||||||
- match: { test-includes.mappings._source.includes: ["a"] }
|
- match: { test-includes.mappings._source.includes: ["a"] }
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -129,5 +129,4 @@ include/exclude is supported with stored _source:
|
||||||
indices.get:
|
indices.get:
|
||||||
index: test-excludes
|
index: test-excludes
|
||||||
|
|
||||||
- match: { test-excludes.mappings._source.mode: "stored" }
|
|
||||||
- match: { test-excludes.mappings._source.excludes: ["b"] }
|
- match: { test-excludes.mappings._source.excludes: ["b"] }
|
||||||
|
|
|
@ -450,11 +450,6 @@ nested fields:
|
||||||
type: long
|
type: long
|
||||||
time_series_metric: gauge
|
time_series_metric: gauge
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.get_mapping: {}
|
|
||||||
|
|
||||||
- match: {tsdb-synthetic.mappings._source.mode: synthetic}
|
|
||||||
|
|
||||||
---
|
---
|
||||||
stored source is supported:
|
stored source is supported:
|
||||||
- requires:
|
- requires:
|
||||||
|
@ -486,12 +481,6 @@ stored source is supported:
|
||||||
type: keyword
|
type: keyword
|
||||||
time_series_dimension: true
|
time_series_dimension: true
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.get:
|
|
||||||
index: tsdb_index
|
|
||||||
|
|
||||||
- match: { tsdb_index.mappings._source.mode: "stored" }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
disabled source is not supported:
|
disabled source is not supported:
|
||||||
- requires:
|
- requires:
|
||||||
|
|
|
@ -11,6 +11,7 @@ package org.elasticsearch.index;
|
||||||
|
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
||||||
import org.elasticsearch.cluster.metadata.Metadata;
|
import org.elasticsearch.cluster.metadata.Metadata;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.common.compress.CompressedXContent;
|
import org.elasticsearch.common.compress.CompressedXContent;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.core.CheckedFunction;
|
import org.elasticsearch.core.CheckedFunction;
|
||||||
|
@ -54,7 +55,7 @@ public interface IndexSettingProvider {
|
||||||
/**
|
/**
|
||||||
* Infrastructure class that holds services that can be used by {@link IndexSettingProvider} instances.
|
* Infrastructure class that holds services that can be used by {@link IndexSettingProvider} instances.
|
||||||
*/
|
*/
|
||||||
record Parameters(CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory) {
|
record Parameters(ClusterService clusterService, CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ public class IndexVersions {
|
||||||
public static final IndexVersion UPGRADE_TO_LUCENE_10_0_0 = def(9_000_00_0, Version.LUCENE_10_0_0);
|
public static final IndexVersion UPGRADE_TO_LUCENE_10_0_0 = def(9_000_00_0, Version.LUCENE_10_0_0);
|
||||||
public static final IndexVersion LOGSDB_DEFAULT_IGNORE_DYNAMIC_BEYOND_LIMIT = def(9_001_00_0, Version.LUCENE_10_0_0);
|
public static final IndexVersion LOGSDB_DEFAULT_IGNORE_DYNAMIC_BEYOND_LIMIT = def(9_001_00_0, Version.LUCENE_10_0_0);
|
||||||
public static final IndexVersion TIME_BASED_K_ORDERED_DOC_ID = def(9_002_00_0, Version.LUCENE_10_0_0);
|
public static final IndexVersion TIME_BASED_K_ORDERED_DOC_ID = def(9_002_00_0, Version.LUCENE_10_0_0);
|
||||||
|
public static final IndexVersion DEPRECATE_SOURCE_MODE_MAPPER = def(9_003_00_0, Version.LUCENE_10_0_0);
|
||||||
/*
|
/*
|
||||||
* STOP! READ THIS FIRST! No, really,
|
* STOP! READ THIS FIRST! No, really,
|
||||||
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
|
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.Explicit;
|
import org.elasticsearch.common.Explicit;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
import org.elasticsearch.common.logging.DeprecationCategory;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
|
@ -38,6 +39,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SourceFieldMapper extends MetadataFieldMapper {
|
public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
public static final NodeFeature SYNTHETIC_SOURCE_FALLBACK = new NodeFeature("mapper.source.synthetic_source_fallback");
|
public static final NodeFeature SYNTHETIC_SOURCE_FALLBACK = new NodeFeature("mapper.source.synthetic_source_fallback");
|
||||||
|
@ -68,6 +70,9 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
return indexMode.defaultSourceMode().name();
|
return indexMode.defaultSourceMode().name();
|
||||||
}, "index.mapping.source.mode", value -> {}, Setting.Property.Final, Setting.Property.IndexScope);
|
}, "index.mapping.source.mode", value -> {}, Setting.Property.Final, Setting.Property.IndexScope);
|
||||||
|
|
||||||
|
public static final String DEPRECATION_WARNING = "Configuring source mode in mappings is deprecated and will be removed "
|
||||||
|
+ "in future versions. Use [index.mapping.source.mode] index setting instead.";
|
||||||
|
|
||||||
/** The source mode */
|
/** The source mode */
|
||||||
public enum Mode {
|
public enum Mode {
|
||||||
DISABLED,
|
DISABLED,
|
||||||
|
@ -79,28 +84,32 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
null,
|
null,
|
||||||
Explicit.IMPLICIT_TRUE,
|
Explicit.IMPLICIT_TRUE,
|
||||||
Strings.EMPTY_ARRAY,
|
Strings.EMPTY_ARRAY,
|
||||||
Strings.EMPTY_ARRAY
|
Strings.EMPTY_ARRAY,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final SourceFieldMapper STORED = new SourceFieldMapper(
|
private static final SourceFieldMapper STORED = new SourceFieldMapper(
|
||||||
Mode.STORED,
|
Mode.STORED,
|
||||||
Explicit.IMPLICIT_TRUE,
|
Explicit.IMPLICIT_TRUE,
|
||||||
Strings.EMPTY_ARRAY,
|
Strings.EMPTY_ARRAY,
|
||||||
Strings.EMPTY_ARRAY
|
Strings.EMPTY_ARRAY,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final SourceFieldMapper SYNTHETIC = new SourceFieldMapper(
|
private static final SourceFieldMapper SYNTHETIC = new SourceFieldMapper(
|
||||||
Mode.SYNTHETIC,
|
Mode.SYNTHETIC,
|
||||||
Explicit.IMPLICIT_TRUE,
|
Explicit.IMPLICIT_TRUE,
|
||||||
Strings.EMPTY_ARRAY,
|
Strings.EMPTY_ARRAY,
|
||||||
Strings.EMPTY_ARRAY
|
Strings.EMPTY_ARRAY,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final SourceFieldMapper DISABLED = new SourceFieldMapper(
|
private static final SourceFieldMapper DISABLED = new SourceFieldMapper(
|
||||||
Mode.DISABLED,
|
Mode.DISABLED,
|
||||||
Explicit.IMPLICIT_TRUE,
|
Explicit.IMPLICIT_TRUE,
|
||||||
Strings.EMPTY_ARRAY,
|
Strings.EMPTY_ARRAY,
|
||||||
Strings.EMPTY_ARRAY
|
Strings.EMPTY_ARRAY,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
public static class Defaults {
|
public static class Defaults {
|
||||||
|
@ -134,16 +143,7 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
* The default mode for TimeSeries is left empty on purpose, so that mapping printings include the synthetic
|
* The default mode for TimeSeries is left empty on purpose, so that mapping printings include the synthetic
|
||||||
* source mode.
|
* source mode.
|
||||||
*/
|
*/
|
||||||
private final Parameter<Mode> mode = new Parameter<>(
|
private final Parameter<Mode> mode;
|
||||||
"mode",
|
|
||||||
true,
|
|
||||||
() -> null,
|
|
||||||
(n, c, o) -> Mode.valueOf(o.toString().toUpperCase(Locale.ROOT)),
|
|
||||||
m -> toType(m).enabled.explicit() ? null : toType(m).mode,
|
|
||||||
(b, n, v) -> b.field(n, v.toString().toLowerCase(Locale.ROOT)),
|
|
||||||
v -> v.toString().toLowerCase(Locale.ROOT)
|
|
||||||
).setMergeValidator((previous, current, conflicts) -> (previous == current) || current != Mode.STORED)
|
|
||||||
.setSerializerCheck((includeDefaults, isConfigured, value) -> value != null); // don't emit if `enabled` is configured
|
|
||||||
private final Parameter<List<String>> includes = Parameter.stringArrayParam(
|
private final Parameter<List<String>> includes = Parameter.stringArrayParam(
|
||||||
"includes",
|
"includes",
|
||||||
false,
|
false,
|
||||||
|
@ -158,15 +158,28 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
|
|
||||||
private final IndexMode indexMode;
|
private final IndexMode indexMode;
|
||||||
|
private boolean serializeMode;
|
||||||
|
|
||||||
private final boolean supportsNonDefaultParameterValues;
|
private final boolean supportsNonDefaultParameterValues;
|
||||||
|
|
||||||
public Builder(IndexMode indexMode, final Settings settings, boolean supportsCheckForNonDefaultParams) {
|
public Builder(IndexMode indexMode, final Settings settings, boolean supportsCheckForNonDefaultParams, boolean serializeMode) {
|
||||||
super(Defaults.NAME);
|
super(Defaults.NAME);
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.indexMode = indexMode;
|
this.indexMode = indexMode;
|
||||||
this.supportsNonDefaultParameterValues = supportsCheckForNonDefaultParams == false
|
this.supportsNonDefaultParameterValues = supportsCheckForNonDefaultParams == false
|
||||||
|| settings.getAsBoolean(LOSSY_PARAMETERS_ALLOWED_SETTING_NAME, true);
|
|| settings.getAsBoolean(LOSSY_PARAMETERS_ALLOWED_SETTING_NAME, true);
|
||||||
|
this.serializeMode = serializeMode;
|
||||||
|
this.mode = new Parameter<>(
|
||||||
|
"mode",
|
||||||
|
true,
|
||||||
|
() -> null,
|
||||||
|
(n, c, o) -> Mode.valueOf(o.toString().toUpperCase(Locale.ROOT)),
|
||||||
|
m -> toType(m).enabled.explicit() ? null : toType(m).mode,
|
||||||
|
(b, n, v) -> b.field(n, v.toString().toLowerCase(Locale.ROOT)),
|
||||||
|
v -> v.toString().toLowerCase(Locale.ROOT)
|
||||||
|
).setMergeValidator((previous, current, conflicts) -> (previous == current) || current != Mode.STORED)
|
||||||
|
// don't emit if `enabled` is configured
|
||||||
|
.setSerializerCheck((includeDefaults, isConfigured, value) -> serializeMode && value != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setSynthetic() {
|
public Builder setSynthetic() {
|
||||||
|
@ -219,21 +232,22 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
if (sourceMode == Mode.SYNTHETIC && (includes.getValue().isEmpty() == false || excludes.getValue().isEmpty() == false)) {
|
if (sourceMode == Mode.SYNTHETIC && (includes.getValue().isEmpty() == false || excludes.getValue().isEmpty() == false)) {
|
||||||
throw new IllegalArgumentException("filtering the stored _source is incompatible with synthetic source");
|
throw new IllegalArgumentException("filtering the stored _source is incompatible with synthetic source");
|
||||||
}
|
}
|
||||||
|
if (mode.isConfigured()) {
|
||||||
SourceFieldMapper sourceFieldMapper;
|
serializeMode = true;
|
||||||
if (isDefault()) {
|
}
|
||||||
|
final SourceFieldMapper sourceFieldMapper;
|
||||||
|
if (isDefault() && sourceMode == null) {
|
||||||
// Needed for bwc so that "mode" is not serialized in case of a standard index with stored source.
|
// Needed for bwc so that "mode" is not serialized in case of a standard index with stored source.
|
||||||
if (sourceMode == null) {
|
sourceFieldMapper = DEFAULT;
|
||||||
sourceFieldMapper = DEFAULT;
|
} else if (isDefault() && serializeMode == false && sourceMode != null) {
|
||||||
} else {
|
sourceFieldMapper = resolveStaticInstance(sourceMode);
|
||||||
sourceFieldMapper = resolveStaticInstance(sourceMode);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sourceFieldMapper = new SourceFieldMapper(
|
sourceFieldMapper = new SourceFieldMapper(
|
||||||
sourceMode,
|
sourceMode,
|
||||||
enabled.get(),
|
enabled.get(),
|
||||||
includes.getValue().toArray(Strings.EMPTY_ARRAY),
|
includes.getValue().toArray(Strings.EMPTY_ARRAY),
|
||||||
excludes.getValue().toArray(Strings.EMPTY_ARRAY)
|
excludes.getValue().toArray(Strings.EMPTY_ARRAY),
|
||||||
|
serializeMode
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (indexMode != null) {
|
if (indexMode != null) {
|
||||||
|
@ -283,15 +297,29 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
if (indexMode == IndexMode.STANDARD && settingSourceMode == Mode.STORED) {
|
if (indexMode == IndexMode.STANDARD && settingSourceMode == Mode.STORED) {
|
||||||
return DEFAULT;
|
return DEFAULT;
|
||||||
}
|
}
|
||||||
|
if (c.indexVersionCreated().onOrAfter(IndexVersions.DEPRECATE_SOURCE_MODE_MAPPER)) {
|
||||||
return resolveStaticInstance(settingSourceMode);
|
return resolveStaticInstance(settingSourceMode);
|
||||||
|
} else {
|
||||||
|
return new SourceFieldMapper(settingSourceMode, Explicit.IMPLICIT_TRUE, Strings.EMPTY_ARRAY, Strings.EMPTY_ARRAY, true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
c -> new Builder(
|
c -> new Builder(
|
||||||
c.getIndexSettings().getMode(),
|
c.getIndexSettings().getMode(),
|
||||||
c.getSettings(),
|
c.getSettings(),
|
||||||
c.indexVersionCreated().onOrAfter(IndexVersions.SOURCE_MAPPER_LOSSY_PARAMS_CHECK)
|
c.indexVersionCreated().onOrAfter(IndexVersions.SOURCE_MAPPER_LOSSY_PARAMS_CHECK),
|
||||||
|
c.indexVersionCreated().before(IndexVersions.DEPRECATE_SOURCE_MODE_MAPPER)
|
||||||
)
|
)
|
||||||
);
|
) {
|
||||||
|
@Override
|
||||||
|
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, MappingParserContext parserContext)
|
||||||
|
throws MapperParsingException {
|
||||||
|
assert name.equals(SourceFieldMapper.NAME) : name;
|
||||||
|
if (parserContext.indexVersionCreated().after(IndexVersions.DEPRECATE_SOURCE_MODE_MAPPER) && node.containsKey("mode")) {
|
||||||
|
deprecationLogger.critical(DeprecationCategory.MAPPINGS, "mapping_source_mode", SourceFieldMapper.DEPRECATION_WARNING);
|
||||||
|
}
|
||||||
|
return super.parse(name, node, parserContext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static final class SourceFieldType extends MappedFieldType {
|
static final class SourceFieldType extends MappedFieldType {
|
||||||
private final boolean enabled;
|
private final boolean enabled;
|
||||||
|
@ -330,8 +358,9 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nullable for bwc reasons
|
// nullable for bwc reasons - TODO: fold this into serializeMode
|
||||||
private final @Nullable Mode mode;
|
private final @Nullable Mode mode;
|
||||||
|
private final boolean serializeMode;
|
||||||
private final Explicit<Boolean> enabled;
|
private final Explicit<Boolean> enabled;
|
||||||
|
|
||||||
/** indicates whether the source will always exist and be complete, for use by features like the update API */
|
/** indicates whether the source will always exist and be complete, for use by features like the update API */
|
||||||
|
@ -341,7 +370,7 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
private final String[] excludes;
|
private final String[] excludes;
|
||||||
private final SourceFilter sourceFilter;
|
private final SourceFilter sourceFilter;
|
||||||
|
|
||||||
private SourceFieldMapper(Mode mode, Explicit<Boolean> enabled, String[] includes, String[] excludes) {
|
private SourceFieldMapper(Mode mode, Explicit<Boolean> enabled, String[] includes, String[] excludes, boolean serializeMode) {
|
||||||
super(new SourceFieldType((enabled.explicit() && enabled.value()) || (enabled.explicit() == false && mode != Mode.DISABLED)));
|
super(new SourceFieldType((enabled.explicit() && enabled.value()) || (enabled.explicit() == false && mode != Mode.DISABLED)));
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
|
@ -349,6 +378,7 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
this.includes = includes;
|
this.includes = includes;
|
||||||
this.excludes = excludes;
|
this.excludes = excludes;
|
||||||
this.complete = stored() && sourceFilter == null;
|
this.complete = stored() && sourceFilter == null;
|
||||||
|
this.serializeMode = serializeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SourceFilter buildSourceFilter(String[] includes, String[] excludes) {
|
private static SourceFilter buildSourceFilter(String[] includes, String[] excludes) {
|
||||||
|
@ -419,7 +449,7 @@ public class SourceFieldMapper extends MetadataFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldMapper.Builder getMergeBuilder() {
|
public FieldMapper.Builder getMergeBuilder() {
|
||||||
return new Builder(null, Settings.EMPTY, false).init(this);
|
return new Builder(null, Settings.EMPTY, false, serializeMode).init(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -820,7 +820,7 @@ class NodeConstruction {
|
||||||
.searchOperationListeners(searchOperationListeners)
|
.searchOperationListeners(searchOperationListeners)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final var parameters = new IndexSettingProvider.Parameters(indicesService::createIndexMapperServiceForValidation);
|
final var parameters = new IndexSettingProvider.Parameters(clusterService, indicesService::createIndexMapperServiceForValidation);
|
||||||
IndexSettingProviders indexSettingProviders = new IndexSettingProviders(
|
IndexSettingProviders indexSettingProviders = new IndexSettingProviders(
|
||||||
Sets.union(
|
Sets.union(
|
||||||
builtinIndexSettingProviders(),
|
builtinIndexSettingProviders(),
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class DynamicFieldsBuilderTests extends ESTestCase {
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, source);
|
XContentParser parser = createParser(JsonXContent.jsonXContent, source);
|
||||||
SourceToParse sourceToParse = new SourceToParse("test", new BytesArray(source), XContentType.JSON);
|
SourceToParse sourceToParse = new SourceToParse("test", new BytesArray(source), XContentType.JSON);
|
||||||
|
|
||||||
SourceFieldMapper sourceMapper = new SourceFieldMapper.Builder(null, Settings.EMPTY, false).setSynthetic().build();
|
SourceFieldMapper sourceMapper = new SourceFieldMapper.Builder(null, Settings.EMPTY, false, false).setSynthetic().build();
|
||||||
RootObjectMapper root = new RootObjectMapper.Builder("_doc", Optional.empty()).add(
|
RootObjectMapper root = new RootObjectMapper.Builder("_doc", Optional.empty()).add(
|
||||||
new PassThroughObjectMapper.Builder("labels").setPriority(0).setContainsDimensions().dynamic(ObjectMapper.Dynamic.TRUE)
|
new PassThroughObjectMapper.Builder("labels").setPriority(0).setContainsDimensions().dynamic(ObjectMapper.Dynamic.TRUE)
|
||||||
).build(MapperBuilderContext.root(false, false));
|
).build(MapperBuilderContext.root(false, false));
|
||||||
|
|
|
@ -247,14 +247,14 @@ public class SourceFieldMapperTests extends MetadataMapperTestCase {
|
||||||
});
|
});
|
||||||
DocumentMapper mapper = createTimeSeriesModeDocumentMapper(mapping);
|
DocumentMapper mapper = createTimeSeriesModeDocumentMapper(mapping);
|
||||||
assertTrue(mapper.sourceMapper().isSynthetic());
|
assertTrue(mapper.sourceMapper().isSynthetic());
|
||||||
assertEquals("{\"_source\":{\"mode\":\"synthetic\"}}", mapper.sourceMapper().toString());
|
assertEquals("{\"_source\":{}}", mapper.sourceMapper().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSyntheticSourceWithLogsIndexMode() throws IOException {
|
public void testSyntheticSourceWithLogsIndexMode() throws IOException {
|
||||||
XContentBuilder mapping = fieldMapping(b -> { b.field("type", "keyword"); });
|
XContentBuilder mapping = fieldMapping(b -> { b.field("type", "keyword"); });
|
||||||
DocumentMapper mapper = createLogsModeDocumentMapper(mapping);
|
DocumentMapper mapper = createLogsModeDocumentMapper(mapping);
|
||||||
assertTrue(mapper.sourceMapper().isSynthetic());
|
assertTrue(mapper.sourceMapper().isSynthetic());
|
||||||
assertEquals("{\"_source\":{\"mode\":\"synthetic\"}}", mapper.sourceMapper().toString());
|
assertEquals("{\"_source\":{}}", mapper.sourceMapper().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSupportsNonDefaultParameterValues() throws IOException {
|
public void testSupportsNonDefaultParameterValues() throws IOException {
|
||||||
|
|
|
@ -384,7 +384,7 @@ public class SearchExecutionContextTests extends ESTestCase {
|
||||||
|
|
||||||
public void testSyntheticSourceSearchLookup() throws IOException {
|
public void testSyntheticSourceSearchLookup() throws IOException {
|
||||||
// Build a mapping using synthetic source
|
// Build a mapping using synthetic source
|
||||||
SourceFieldMapper sourceMapper = new SourceFieldMapper.Builder(null, Settings.EMPTY, false).setSynthetic().build();
|
SourceFieldMapper sourceMapper = new SourceFieldMapper.Builder(null, Settings.EMPTY, false, false).setSynthetic().build();
|
||||||
RootObjectMapper root = new RootObjectMapper.Builder("_doc", Optional.empty()).add(
|
RootObjectMapper root = new RootObjectMapper.Builder("_doc", Optional.empty()).add(
|
||||||
new KeywordFieldMapper.Builder("cat", IndexVersion.current()).ignoreAbove(100)
|
new KeywordFieldMapper.Builder("cat", IndexVersion.current()).ignoreAbove(100)
|
||||||
).build(MapperBuilderContext.root(true, false));
|
).build(MapperBuilderContext.root(true, false));
|
||||||
|
|
|
@ -69,6 +69,7 @@ import org.elasticsearch.health.node.selection.HealthNode;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.index.IndexVersion;
|
import org.elasticsearch.index.IndexVersion;
|
||||||
import org.elasticsearch.index.IndexVersions;
|
import org.elasticsearch.index.IndexVersions;
|
||||||
|
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.seqno.ReplicationTracker;
|
import org.elasticsearch.index.seqno.ReplicationTracker;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
@ -112,6 +113,7 @@ import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -1827,8 +1829,9 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
|
|
||||||
if (settings != null && settings.getAsBoolean(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true) == false) {
|
if (settings != null && settings.getAsBoolean(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true) == false) {
|
||||||
expectSoftDeletesWarning(request, name);
|
expectSoftDeletesWarning(request, name);
|
||||||
|
} else if (isSyntheticSourceConfiguredInMapping(mapping)) {
|
||||||
|
request.setOptions(expectVersionSpecificWarnings(v -> v.compatible(SourceFieldMapper.DEPRECATION_WARNING)));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Response response = client.performRequest(request);
|
final Response response = client.performRequest(request);
|
||||||
try (var parser = responseAsParser(response)) {
|
try (var parser = responseAsParser(response)) {
|
||||||
return TestResponseParsers.parseCreateIndexResponse(parser);
|
return TestResponseParsers.parseCreateIndexResponse(parser);
|
||||||
|
@ -1872,6 +1875,27 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected static boolean isSyntheticSourceConfiguredInMapping(String mapping) {
|
||||||
|
if (mapping == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var mappings = XContentHelper.convertToMap(
|
||||||
|
JsonXContent.jsonXContent,
|
||||||
|
mapping.trim().startsWith("{") ? mapping : '{' + mapping + '}',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
if (mappings.containsKey("_doc")) {
|
||||||
|
mappings = (Map<String, Object>) mappings.get("_doc");
|
||||||
|
}
|
||||||
|
Map<String, Object> sourceMapper = (Map<String, Object>) mappings.get(SourceFieldMapper.NAME);
|
||||||
|
if (sourceMapper == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Object mode = sourceMapper.get("mode");
|
||||||
|
return mode != null && mode.toString().toLowerCase(Locale.ROOT).equals("synthetic");
|
||||||
|
}
|
||||||
|
|
||||||
protected static Map<String, Object> getIndexSettings(String index) throws IOException {
|
protected static Map<String, Object> getIndexSettings(String index) throws IOException {
|
||||||
Request request = new Request("GET", "/" + index + "/_settings");
|
Request request = new Request("GET", "/" + index + "/_settings");
|
||||||
request.addParameter("flat_settings", "true");
|
request.addParameter("flat_settings", "true");
|
||||||
|
@ -2269,7 +2293,7 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
*/
|
*/
|
||||||
protected static IndexVersion minimumIndexVersion() throws IOException {
|
protected static IndexVersion minimumIndexVersion() throws IOException {
|
||||||
final Request request = new Request("GET", "_nodes");
|
final Request request = new Request("GET", "_nodes");
|
||||||
request.addParameter("filter_path", "nodes.*.version,nodes.*.max_index_version");
|
request.addParameter("filter_path", "nodes.*.version,nodes.*.max_index_version,nodes.*.index_version");
|
||||||
|
|
||||||
final Response response = adminClient().performRequest(request);
|
final Response response = adminClient().performRequest(request);
|
||||||
final Map<String, Object> nodes = ObjectPath.createFromResponse(response).evaluate("nodes");
|
final Map<String, Object> nodes = ObjectPath.createFromResponse(response).evaluate("nodes");
|
||||||
|
@ -2277,10 +2301,13 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
IndexVersion minVersion = null;
|
IndexVersion minVersion = null;
|
||||||
for (Map.Entry<String, Object> node : nodes.entrySet()) {
|
for (Map.Entry<String, Object> node : nodes.entrySet()) {
|
||||||
Map<?, ?> nodeData = (Map<?, ?>) node.getValue();
|
Map<?, ?> nodeData = (Map<?, ?>) node.getValue();
|
||||||
String versionStr = (String) nodeData.get("max_index_version");
|
Object versionStr = nodeData.get("index_version");
|
||||||
|
if (versionStr == null) {
|
||||||
|
versionStr = nodeData.get("max_index_version");
|
||||||
|
}
|
||||||
// fallback on version if index version is not there
|
// fallback on version if index version is not there
|
||||||
IndexVersion indexVersion = versionStr != null
|
IndexVersion indexVersion = versionStr != null
|
||||||
? IndexVersion.fromId(Integer.parseInt(versionStr))
|
? IndexVersion.fromId(Integer.parseInt(versionStr.toString()))
|
||||||
: IndexVersion.fromId(
|
: IndexVersion.fromId(
|
||||||
parseLegacyVersion((String) nodeData.get("version")).map(Version::id).orElse(IndexVersions.MINIMUM_COMPATIBLE.id())
|
parseLegacyVersion((String) nodeData.get("version")).map(Version::id).orElse(IndexVersions.MINIMUM_COMPATIBLE.id())
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.logging.HeaderWarning;
|
import org.elasticsearch.common.logging.HeaderWarning;
|
||||||
import org.elasticsearch.core.Tuple;
|
import org.elasticsearch.core.Tuple;
|
||||||
import org.elasticsearch.core.UpdateForV9;
|
import org.elasticsearch.core.UpdateForV9;
|
||||||
|
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||||
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
|
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
||||||
|
@ -495,6 +496,8 @@ public class DoSection implements ExecutableSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unexpected.removeIf(s -> s.endsWith(SourceFieldMapper.DEPRECATION_WARNING + "\""));
|
||||||
|
|
||||||
if (unexpected.isEmpty() == false
|
if (unexpected.isEmpty() == false
|
||||||
|| unmatched.isEmpty() == false
|
|| unmatched.isEmpty() == false
|
||||||
|| missing.isEmpty() == false
|
|| missing.isEmpty() == false
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.index.mapper.DateFieldMapper;
|
import org.elasticsearch.index.mapper.DateFieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||||
import org.elasticsearch.repositories.fs.FsRepository;
|
import org.elasticsearch.repositories.fs.FsRepository;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
|
||||||
|
@ -366,8 +367,10 @@ public class FollowIndexIT extends ESCCRRestTestCase {
|
||||||
final String leaderIndexName = "synthetic_leader";
|
final String leaderIndexName = "synthetic_leader";
|
||||||
if ("leader".equals(targetCluster)) {
|
if ("leader".equals(targetCluster)) {
|
||||||
logger.info("Running against leader cluster");
|
logger.info("Running against leader cluster");
|
||||||
createIndex(adminClient(), leaderIndexName, Settings.EMPTY, """
|
Settings settings = Settings.builder()
|
||||||
"_source": {"mode": "synthetic"},
|
.put(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(), SourceFieldMapper.Mode.SYNTHETIC)
|
||||||
|
.build();
|
||||||
|
createIndex(adminClient(), leaderIndexName, settings, """
|
||||||
"properties": {"kwd": {"type": "keyword"}}}""", null);
|
"properties": {"kwd": {"type": "keyword"}}}""", null);
|
||||||
for (int i = 0; i < numDocs; i++) {
|
for (int i = 0; i < numDocs; i++) {
|
||||||
logger.info("Indexing doc [{}]", i);
|
logger.info("Indexing doc [{}]", i);
|
||||||
|
@ -392,7 +395,6 @@ public class FollowIndexIT extends ESCCRRestTestCase {
|
||||||
}
|
}
|
||||||
assertBusy(() -> {
|
assertBusy(() -> {
|
||||||
verifyDocuments(client(), followIndexName, numDocs);
|
verifyDocuments(client(), followIndexName, numDocs);
|
||||||
assertMap(getIndexMappingAsMap(followIndexName), matchesMap().extraOk().entry("_source", Map.of("mode", "synthetic")));
|
|
||||||
if (overrideNumberOfReplicas) {
|
if (overrideNumberOfReplicas) {
|
||||||
assertMap(getIndexSettingsAsMap(followIndexName), matchesMap().extraOk().entry("index.number_of_replicas", "0"));
|
assertMap(getIndexSettingsAsMap(followIndexName), matchesMap().extraOk().entry("index.number_of_replicas", "0"));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.elasticsearch.client.Response;
|
||||||
import org.elasticsearch.client.ResponseException;
|
import org.elasticsearch.client.ResponseException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.network.NetworkAddress;
|
import org.elasticsearch.common.network.NetworkAddress;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.core.CheckedConsumer;
|
import org.elasticsearch.core.CheckedConsumer;
|
||||||
import org.elasticsearch.geo.GeometryTestUtils;
|
import org.elasticsearch.geo.GeometryTestUtils;
|
||||||
import org.elasticsearch.index.mapper.BlockLoader;
|
import org.elasticsearch.index.mapper.BlockLoader;
|
||||||
|
@ -1456,16 +1457,12 @@ public abstract class FieldExtractorTestCase extends ESRestTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createIndex(String name, CheckedConsumer<XContentBuilder, IOException> mapping) throws IOException {
|
private static void createIndex(String name, CheckedConsumer<XContentBuilder, IOException> mapping) throws IOException {
|
||||||
Request request = new Request("PUT", "/" + name);
|
|
||||||
XContentBuilder index = JsonXContent.contentBuilder().prettyPrint().startObject();
|
XContentBuilder index = JsonXContent.contentBuilder().prettyPrint().startObject();
|
||||||
index.startObject("mappings");
|
|
||||||
mapping.accept(index);
|
mapping.accept(index);
|
||||||
index.endObject();
|
index.endObject();
|
||||||
index.endObject();
|
|
||||||
String configStr = Strings.toString(index);
|
String configStr = Strings.toString(index);
|
||||||
logger.info("index: {} {}", name, configStr);
|
logger.info("index: {} {}", name, configStr);
|
||||||
request.setJsonEntity(configStr);
|
ESRestTestCase.createIndex(name, Settings.EMPTY, configStr);
|
||||||
client().performRequest(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -67,10 +67,13 @@ public class LogsDBPlugin extends Plugin implements ActionPlugin {
|
||||||
if (DiscoveryNode.isStateless(settings)) {
|
if (DiscoveryNode.isStateless(settings)) {
|
||||||
return List.of(logsdbIndexModeSettingsProvider);
|
return List.of(logsdbIndexModeSettingsProvider);
|
||||||
}
|
}
|
||||||
return List.of(
|
var syntheticSettingProvider = new SyntheticSourceIndexSettingsProvider(
|
||||||
new SyntheticSourceIndexSettingsProvider(licenseService, parameters.mapperServiceFactory(), logsdbIndexModeSettingsProvider),
|
licenseService,
|
||||||
logsdbIndexModeSettingsProvider
|
parameters.mapperServiceFactory(),
|
||||||
|
logsdbIndexModeSettingsProvider,
|
||||||
|
() -> parameters.clusterService().state().nodes().getMinSupportedIndexVersion()
|
||||||
);
|
);
|
||||||
|
return List.of(syntheticSettingProvider, logsdbIndexModeSettingsProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_ROUTING_PATH;
|
import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_ROUTING_PATH;
|
||||||
|
|
||||||
|
@ -39,15 +40,18 @@ final class SyntheticSourceIndexSettingsProvider implements IndexSettingProvider
|
||||||
private final SyntheticSourceLicenseService syntheticSourceLicenseService;
|
private final SyntheticSourceLicenseService syntheticSourceLicenseService;
|
||||||
private final CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory;
|
private final CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory;
|
||||||
private final LogsdbIndexModeSettingsProvider logsdbIndexModeSettingsProvider;
|
private final LogsdbIndexModeSettingsProvider logsdbIndexModeSettingsProvider;
|
||||||
|
private final Supplier<IndexVersion> createdIndexVersion;
|
||||||
|
|
||||||
SyntheticSourceIndexSettingsProvider(
|
SyntheticSourceIndexSettingsProvider(
|
||||||
SyntheticSourceLicenseService syntheticSourceLicenseService,
|
SyntheticSourceLicenseService syntheticSourceLicenseService,
|
||||||
CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory,
|
CheckedFunction<IndexMetadata, MapperService, IOException> mapperServiceFactory,
|
||||||
LogsdbIndexModeSettingsProvider logsdbIndexModeSettingsProvider
|
LogsdbIndexModeSettingsProvider logsdbIndexModeSettingsProvider,
|
||||||
|
Supplier<IndexVersion> createdIndexVersion
|
||||||
) {
|
) {
|
||||||
this.syntheticSourceLicenseService = syntheticSourceLicenseService;
|
this.syntheticSourceLicenseService = syntheticSourceLicenseService;
|
||||||
this.mapperServiceFactory = mapperServiceFactory;
|
this.mapperServiceFactory = mapperServiceFactory;
|
||||||
this.logsdbIndexModeSettingsProvider = logsdbIndexModeSettingsProvider;
|
this.logsdbIndexModeSettingsProvider = logsdbIndexModeSettingsProvider;
|
||||||
|
this.createdIndexVersion = createdIndexVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -148,7 +152,7 @@ final class SyntheticSourceIndexSettingsProvider implements IndexSettingProvider
|
||||||
);
|
);
|
||||||
int shardReplicas = indexTemplateAndCreateRequestSettings.getAsInt(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0);
|
int shardReplicas = indexTemplateAndCreateRequestSettings.getAsInt(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0);
|
||||||
var finalResolvedSettings = Settings.builder()
|
var finalResolvedSettings = Settings.builder()
|
||||||
.put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())
|
.put(IndexMetadata.SETTING_VERSION_CREATED, createdIndexVersion.get())
|
||||||
.put(indexTemplateAndCreateRequestSettings)
|
.put(indexTemplateAndCreateRequestSettings)
|
||||||
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, dummyShards)
|
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, dummyShards)
|
||||||
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, shardReplicas)
|
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, shardReplicas)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.core.Tuple;
|
import org.elasticsearch.core.Tuple;
|
||||||
import org.elasticsearch.index.IndexMode;
|
import org.elasticsearch.index.IndexMode;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
|
import org.elasticsearch.index.IndexVersion;
|
||||||
import org.elasticsearch.index.MapperTestUtils;
|
import org.elasticsearch.index.MapperTestUtils;
|
||||||
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||||
import org.elasticsearch.license.MockLicenseState;
|
import org.elasticsearch.license.MockLicenseState;
|
||||||
|
@ -54,7 +55,7 @@ public class SyntheticSourceIndexSettingsProviderTests extends ESTestCase {
|
||||||
provider = new SyntheticSourceIndexSettingsProvider(syntheticSourceLicenseService, im -> {
|
provider = new SyntheticSourceIndexSettingsProvider(syntheticSourceLicenseService, im -> {
|
||||||
newMapperServiceCounter.incrementAndGet();
|
newMapperServiceCounter.incrementAndGet();
|
||||||
return MapperTestUtils.newMapperService(xContentRegistry(), createTempDir(), im.getSettings(), im.getIndex().getName());
|
return MapperTestUtils.newMapperService(xContentRegistry(), createTempDir(), im.getSettings(), im.getIndex().getName());
|
||||||
}, getLogsdbIndexModeSettingsProvider(false));
|
}, getLogsdbIndexModeSettingsProvider(false), IndexVersion::current);
|
||||||
newMapperServiceCounter.set(0);
|
newMapperServiceCounter.set(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +337,8 @@ public class SyntheticSourceIndexSettingsProviderTests extends ESTestCase {
|
||||||
provider = new SyntheticSourceIndexSettingsProvider(
|
provider = new SyntheticSourceIndexSettingsProvider(
|
||||||
syntheticSourceLicenseService,
|
syntheticSourceLicenseService,
|
||||||
im -> MapperTestUtils.newMapperService(xContentRegistry(), createTempDir(), im.getSettings(), im.getIndex().getName()),
|
im -> MapperTestUtils.newMapperService(xContentRegistry(), createTempDir(), im.getSettings(), im.getIndex().getName()),
|
||||||
getLogsdbIndexModeSettingsProvider(true)
|
getLogsdbIndexModeSettingsProvider(true),
|
||||||
|
IndexVersion::current
|
||||||
);
|
);
|
||||||
final Settings settings = Settings.EMPTY;
|
final Settings settings = Settings.EMPTY;
|
||||||
|
|
||||||
|
|
|
@ -470,13 +470,7 @@ create an index with time_series index mode and synthetic source:
|
||||||
indices.get_settings:
|
indices.get_settings:
|
||||||
index: "test_time_series_index_mode_synthetic"
|
index: "test_time_series_index_mode_synthetic"
|
||||||
- match: { test_time_series_index_mode_synthetic.settings.index.mode: time_series }
|
- match: { test_time_series_index_mode_synthetic.settings.index.mode: time_series }
|
||||||
|
- match: { test_time_series_index_mode_synthetic.settings.index.mapping.source.mode: synthetic }
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.get_mapping:
|
|
||||||
index: test_time_series_index_mode_synthetic
|
|
||||||
|
|
||||||
- match: { test_time_series_index_mode_synthetic.mappings._source.mode: synthetic }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
create an index with logsdb index mode and synthetic source:
|
create an index with logsdb index mode and synthetic source:
|
||||||
|
@ -493,12 +487,7 @@ create an index with logsdb index mode and synthetic source:
|
||||||
indices.get_settings:
|
indices.get_settings:
|
||||||
index: "test_logsdb_index_mode_synthetic"
|
index: "test_logsdb_index_mode_synthetic"
|
||||||
- match: { test_logsdb_index_mode_synthetic.settings.index.mode: logsdb }
|
- match: { test_logsdb_index_mode_synthetic.settings.index.mode: logsdb }
|
||||||
|
- match: { test_logsdb_index_mode_synthetic.settings.index.mapping.source.mode: synthetic }
|
||||||
- do:
|
|
||||||
indices.get_mapping:
|
|
||||||
index: test_logsdb_index_mode_synthetic
|
|
||||||
|
|
||||||
- match: { test_logsdb_index_mode_synthetic.mappings._source.mode: synthetic }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
create an index with time_series index mode and stored source:
|
create an index with time_series index mode and stored source:
|
||||||
|
@ -524,12 +513,7 @@ create an index with time_series index mode and stored source:
|
||||||
indices.get_settings:
|
indices.get_settings:
|
||||||
index: "test_time_series_index_mode_undefined"
|
index: "test_time_series_index_mode_undefined"
|
||||||
- match: { test_time_series_index_mode_undefined.settings.index.mode: time_series }
|
- match: { test_time_series_index_mode_undefined.settings.index.mode: time_series }
|
||||||
|
- match: { test_time_series_index_mode_undefined.settings.index.mapping.source.mode: stored }
|
||||||
- do:
|
|
||||||
indices.get_mapping:
|
|
||||||
index: test_time_series_index_mode_undefined
|
|
||||||
|
|
||||||
- match: { test_time_series_index_mode_undefined.mappings._source.mode: stored }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
create an index with logsdb index mode and stored source:
|
create an index with logsdb index mode and stored source:
|
||||||
|
@ -546,12 +530,7 @@ create an index with logsdb index mode and stored source:
|
||||||
indices.get_settings:
|
indices.get_settings:
|
||||||
index: "test_logsdb_index_mode_undefined"
|
index: "test_logsdb_index_mode_undefined"
|
||||||
- match: { test_logsdb_index_mode_undefined.settings.index.mode: logsdb }
|
- match: { test_logsdb_index_mode_undefined.settings.index.mode: logsdb }
|
||||||
|
- match: { test_logsdb_index_mode_undefined.settings.index.mapping.source.mode: stored }
|
||||||
- do:
|
|
||||||
indices.get_mapping:
|
|
||||||
index: test_logsdb_index_mode_undefined
|
|
||||||
|
|
||||||
- match: { test_logsdb_index_mode_undefined.mappings._source.mode: stored }
|
|
||||||
|
|
||||||
---
|
---
|
||||||
create an index with time_series index mode and disabled source:
|
create an index with time_series index mode and disabled source:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue