Skip to content

Commit 359a8b3

Browse files
authored
[9.0] Avoid serializing empty _source fields in mappings. (#124200)
Backporting #122606 to 9.0 branch.
1 parent a757202 commit 359a8b3

File tree

14 files changed

+161
-76
lines changed

14 files changed

+161
-76
lines changed

docs/changelog/122606.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 122606
2+
summary: Avoid serializing empty `_source` fields in mappings
3+
area: Mapping
4+
type: bug
5+
issues: []

qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,26 @@ public class FullClusterRestartDownsampleIT extends ParameterizedFullClusterRest
4444

4545
protected static LocalClusterConfigProvider clusterConfig = c -> {};
4646

47-
private static ElasticsearchCluster cluster = ElasticsearchCluster.local()
48-
.distribution(DistributionType.DEFAULT)
49-
.version(Version.fromString(OLD_CLUSTER_VERSION))
50-
.nodes(2)
51-
.setting("xpack.security.enabled", "false")
52-
.setting("indices.lifecycle.poll_interval", "5s")
53-
.apply(() -> clusterConfig)
54-
.feature(FeatureFlag.TIME_SERIES_MODE)
55-
.feature(FeatureFlag.FAILURE_STORE_ENABLED)
56-
.build();
47+
private static ElasticsearchCluster cluster = buildCluster();
48+
49+
private static ElasticsearchCluster buildCluster() {
50+
Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION);
51+
var cluster = ElasticsearchCluster.local()
52+
.distribution(DistributionType.DEFAULT)
53+
.version(Version.fromString(OLD_CLUSTER_VERSION))
54+
.nodes(2)
55+
.setting("xpack.security.enabled", "false")
56+
.setting("indices.lifecycle.poll_interval", "5s")
57+
.apply(() -> clusterConfig)
58+
.feature(FeatureFlag.TIME_SERIES_MODE)
59+
.feature(FeatureFlag.FAILURE_STORE_ENABLED);
60+
61+
if (oldVersion.before(Version.fromString("9.0.0"))) {
62+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper");
63+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService");
64+
}
65+
return cluster.build();
66+
}
5767

5868
@ClassRule
5969
public static TestRule ruleChain = RuleChain.outerRule(repoDirectory).around(cluster);

qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,28 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas
103103

104104
protected static LocalClusterConfigProvider clusterConfig = c -> {};
105105

106-
private static ElasticsearchCluster cluster = ElasticsearchCluster.local()
107-
.distribution(DistributionType.DEFAULT)
108-
.version(Version.fromString(OLD_CLUSTER_VERSION))
109-
.nodes(2)
110-
.setting("path.repo", () -> repoDirectory.getRoot().getPath())
111-
.setting("xpack.security.enabled", "false")
112-
// some tests rely on the translog not being flushed
113-
.setting("indices.memory.shard_inactive_time", "60m")
114-
.apply(() -> clusterConfig)
115-
.feature(FeatureFlag.TIME_SERIES_MODE)
116-
.feature(FeatureFlag.FAILURE_STORE_ENABLED)
117-
.build();
106+
private static ElasticsearchCluster cluster = buildCluster();
107+
108+
private static ElasticsearchCluster buildCluster() {
109+
Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION);
110+
var cluster = ElasticsearchCluster.local()
111+
.distribution(DistributionType.DEFAULT)
112+
.version(Version.fromString(OLD_CLUSTER_VERSION))
113+
.nodes(2)
114+
.setting("path.repo", () -> repoDirectory.getRoot().getPath())
115+
.setting("xpack.security.enabled", "false")
116+
// some tests rely on the translog not being flushed
117+
.setting("indices.memory.shard_inactive_time", "60m")
118+
.apply(() -> clusterConfig)
119+
.feature(FeatureFlag.TIME_SERIES_MODE)
120+
.feature(FeatureFlag.FAILURE_STORE_ENABLED);
121+
122+
if (oldVersion.before(Version.fromString("9.0.0"))) {
123+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper");
124+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService");
125+
}
126+
return cluster.build();
127+
}
118128

119129
@ClassRule
120130
public static TestRule ruleChain = RuleChain.outerRule(repoDirectory).around(cluster);

qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,27 @@
3333
public class LogsIndexModeFullClusterRestartIT extends ParameterizedFullClusterRestartTestCase {
3434

3535
@ClassRule
36-
public static final ElasticsearchCluster cluster = ElasticsearchCluster.local()
37-
.distribution(DistributionType.DEFAULT)
38-
.version(Version.fromString(OLD_CLUSTER_VERSION))
39-
.module("constant-keyword")
40-
.module("data-streams")
41-
.module("mapper-extras")
42-
.module("x-pack-aggregate-metric")
43-
.module("x-pack-stack")
44-
.setting("xpack.security.enabled", "false")
45-
.setting("xpack.license.self_generated.type", "trial")
46-
.build();
36+
public static final ElasticsearchCluster cluster = buildCluster();
37+
38+
private static ElasticsearchCluster buildCluster() {
39+
Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION);
40+
var cluster = ElasticsearchCluster.local()
41+
.distribution(DistributionType.DEFAULT)
42+
.version(Version.fromString(OLD_CLUSTER_VERSION))
43+
.module("constant-keyword")
44+
.module("data-streams")
45+
.module("mapper-extras")
46+
.module("x-pack-aggregate-metric")
47+
.module("x-pack-stack")
48+
.setting("xpack.security.enabled", "false")
49+
.setting("xpack.license.self_generated.type", "trial");
50+
51+
if (oldVersion.before(Version.fromString("9.0.0"))) {
52+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper");
53+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService");
54+
}
55+
return cluster.build();
56+
}
4757

4858
public LogsIndexModeFullClusterRestartIT(@Name("cluster") FullClusterRestartUpgradeStatus upgradeStatus) {
4959
super(upgradeStatus);

qa/mixed-cluster/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ buildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
9191
setting 'health.master_history.no_master_transitions_threshold', '10'
9292
}
9393
requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
94+
if (bwcVersion.before(Version.fromString("9.0.0"))) {
95+
jvmArgs '-da:org.elasticsearch.index.mapper.DocumentMapper'
96+
jvmArgs '-da:org.elasticsearch.index.mapper.MapperService'
97+
}
9498
}
9599

96100
tasks.register("${baseName}#mixedClusterTest", StandaloneRestIntegTestTask) {

qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeTestCase.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.test.cluster.ElasticsearchCluster;
1616
import org.elasticsearch.test.cluster.FeatureFlag;
1717
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
18+
import org.elasticsearch.test.cluster.util.Version;
1819
import org.junit.ClassRule;
1920
import org.junit.rules.RuleChain;
2021
import org.junit.rules.TemporaryFolder;
@@ -26,20 +27,30 @@ public abstract class AbstractRollingUpgradeTestCase extends ParameterizedRollin
2627

2728
private static final TemporaryFolder repoDirectory = new TemporaryFolder();
2829

29-
private static final ElasticsearchCluster cluster = ElasticsearchCluster.local()
30-
.distribution(DistributionType.DEFAULT)
31-
.version(getOldClusterTestVersion())
32-
.nodes(NODE_NUM)
33-
.setting("path.repo", new Supplier<>() {
34-
@Override
35-
@SuppressForbidden(reason = "TemporaryFolder only has io.File methods, not nio.File")
36-
public String get() {
37-
return repoDirectory.getRoot().getPath();
38-
}
39-
})
40-
.setting("xpack.security.enabled", "false")
41-
.feature(FeatureFlag.TIME_SERIES_MODE)
42-
.build();
30+
private static final ElasticsearchCluster cluster = buildCluster();
31+
32+
private static ElasticsearchCluster buildCluster() {
33+
Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION);
34+
var cluster = ElasticsearchCluster.local()
35+
.distribution(DistributionType.DEFAULT)
36+
.version(getOldClusterTestVersion())
37+
.nodes(NODE_NUM)
38+
.setting("path.repo", new Supplier<>() {
39+
@Override
40+
@SuppressForbidden(reason = "TemporaryFolder only has io.File methods, not nio.File")
41+
public String get() {
42+
return repoDirectory.getRoot().getPath();
43+
}
44+
})
45+
.setting("xpack.security.enabled", "false")
46+
.feature(FeatureFlag.TIME_SERIES_MODE);
47+
48+
if (oldVersion.before(Version.fromString("9.0.0"))) {
49+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper");
50+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService");
51+
}
52+
return cluster.build();
53+
}
4354

4455
@ClassRule
4556
public static TestRule ruleChain = RuleChain.outerRule(repoDirectory).around(cluster);

qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
public abstract class ParameterizedRollingUpgradeTestCase extends ESRestTestCase {
3838
protected static final int NODE_NUM = 3;
39-
private static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version");
39+
protected static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version");
4040
private static final Set<Integer> upgradedNodes = new HashSet<>();
4141
private static TestFeatureService oldClusterTestFeatureService = null;
4242
private static boolean upgradeFailed = false;

server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,17 @@ public Builder(
171171
|| settings.getAsBoolean(LOSSY_PARAMETERS_ALLOWED_SETTING_NAME, true);
172172
this.sourceModeIsNoop = sourceModeIsNoop;
173173
this.serializeMode = serializeMode;
174-
this.mode = new Parameter<>(
175-
"mode",
176-
true,
177-
() -> null,
178-
(n, c, o) -> Mode.valueOf(o.toString().toUpperCase(Locale.ROOT)),
179-
m -> toType(m).enabled.explicit() ? null : toType(m).mode,
180-
(b, n, v) -> b.field(n, v.toString().toLowerCase(Locale.ROOT)),
181-
v -> v.toString().toLowerCase(Locale.ROOT)
182-
).setMergeValidator((previous, current, conflicts) -> (previous == current) || current != Mode.STORED)
174+
this.mode = new Parameter<>("mode", true, () -> null, (n, c, o) -> Mode.valueOf(o.toString().toUpperCase(Locale.ROOT)), m -> {
175+
var sfm = toType(m);
176+
if (sfm.enabled.explicit()) {
177+
return null;
178+
} else if (sfm.serializeMode) {
179+
return sfm.mode;
180+
} else {
181+
return null;
182+
}
183+
}, (b, n, v) -> b.field(n, v.toString().toLowerCase(Locale.ROOT)), v -> v.toString().toLowerCase(Locale.ROOT))
184+
.setMergeValidator((previous, current, conflicts) -> (previous == current) || current != Mode.STORED)
183185
// don't emit if `enabled` is configured
184186
.setSerializerCheck((includeDefaults, isConfigured, value) -> serializeMode && value != null);
185187
}
@@ -300,10 +302,11 @@ private static SourceFieldMapper resolveStaticInstance(final Mode sourceMode) {
300302
if (indexMode == IndexMode.STANDARD && settingSourceMode == Mode.STORED) {
301303
return DEFAULT;
302304
}
305+
SourceFieldMapper sourceFieldMapper;
303306
if (onOrAfterDeprecateModeVersion(c.indexVersionCreated())) {
304-
return resolveStaticInstance(settingSourceMode);
307+
sourceFieldMapper = resolveStaticInstance(settingSourceMode);
305308
} else {
306-
return new SourceFieldMapper(
309+
sourceFieldMapper = new SourceFieldMapper(
307310
settingSourceMode,
308311
Explicit.IMPLICIT_TRUE,
309312
Strings.EMPTY_ARRAY,
@@ -312,6 +315,8 @@ private static SourceFieldMapper resolveStaticInstance(final Mode sourceMode) {
312315
c.indexVersionCreated().onOrAfter(IndexVersions.SOURCE_MAPPER_MODE_ATTRIBUTE_NOOP)
313316
);
314317
}
318+
indexMode.validateSourceFieldMapper(sourceFieldMapper);
319+
return sourceFieldMapper;
315320
},
316321
c -> new Builder(
317322
c.getIndexSettings().getMode(),

server/src/test/java/org/elasticsearch/index/mapper/SourceFieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,14 @@ public void testSyntheticSourceInTimeSeries() throws IOException {
267267
});
268268
DocumentMapper mapper = createTimeSeriesModeDocumentMapper(mapping);
269269
assertTrue(mapper.sourceMapper().isSynthetic());
270-
assertEquals("{\"_source\":{}}", mapper.sourceMapper().toString());
270+
assertEquals("{}", mapper.sourceMapper().toString());
271271
}
272272

273273
public void testSyntheticSourceWithLogsIndexMode() throws IOException {
274274
XContentBuilder mapping = fieldMapping(b -> { b.field("type", "keyword"); });
275275
DocumentMapper mapper = createLogsModeDocumentMapper(mapping);
276276
assertTrue(mapper.sourceMapper().isSynthetic());
277-
assertEquals("{\"_source\":{}}", mapper.sourceMapper().toString());
277+
assertEquals("{}", mapper.sourceMapper().toString());
278278
}
279279

280280
public void testSupportsNonDefaultParameterValues() throws IOException {

x-pack/plugin/downsample/qa/mixed-cluster/src/yamlRestTest/java/org/elasticsearch/xpack/downsample/MixedClusterDownsampleRestIT.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,23 @@
1919
public class MixedClusterDownsampleRestIT extends ESClientYamlSuiteTestCase {
2020

2121
@ClassRule
22-
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
23-
.distribution(DistributionType.DEFAULT)
24-
.withNode(node -> node.version(getOldVersion()))
25-
.withNode(node -> node.version(Version.CURRENT))
26-
.setting("xpack.security.enabled", "false")
27-
.setting("xpack.license.self_generated.type", "trial")
28-
.build();
22+
public static ElasticsearchCluster cluster = buildCluster();
23+
24+
private static ElasticsearchCluster buildCluster() {
25+
Version oldVersion = getOldVersion();
26+
var cluster = ElasticsearchCluster.local()
27+
.distribution(DistributionType.DEFAULT)
28+
.withNode(node -> node.version(getOldVersion()))
29+
.withNode(node -> node.version(Version.CURRENT))
30+
.setting("xpack.security.enabled", "false")
31+
.setting("xpack.license.self_generated.type", "trial");
32+
33+
if (oldVersion.before(Version.fromString("9.0.0"))) {
34+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper");
35+
cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService");
36+
}
37+
return cluster.build();
38+
}
2939

3040
static Version getOldVersion() {
3141
return Version.fromString(System.getProperty("tests.old_cluster_version"));

0 commit comments

Comments
 (0)