Skip to content

Commit 8e786c1

Browse files
committed
Merge branch 'main' into 2025/02/05/validate-known-transport-handshake-version
2 parents 90fc6d3 + 94d7f22 commit 8e786c1

File tree

16 files changed

+416
-126
lines changed

16 files changed

+416
-126
lines changed

muted-tests.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ tests:
134134
- class: org.elasticsearch.datastreams.DataStreamsClientYamlTestSuiteIT
135135
method: test {p0=data_stream/120_data_streams_stats/Multiple data stream}
136136
issue: https://github.com/elastic/elasticsearch/issues/118217
137+
# TODO: re-enable after backporting https://github.com/elastic/elasticsearch/pull/119110
138+
- class: org.elasticsearch.test.rest.ClientYamlTestSuiteIT
139+
method: test {yaml=update/100_synthetic_source/keyword}
140+
# TODO: re-enable after backporting https://github.com/elastic/elasticsearch/pull/119110
141+
- class: org.elasticsearch.test.rest.ClientYamlTestSuiteIT
142+
method: test {yaml=update/100_synthetic_source/stored text}
137143
- class: org.elasticsearch.xpack.searchablesnapshots.RetrySearchIntegTests
138144
method: testSearcherId
139145
issue: https://github.com/elastic/elasticsearch/issues/118374

qa/smoke-test-multinode/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ tasks.named("yamlRestTest").configure {
2828
'cat.templates/10_basic/No templates',
2929
'cat.templates/10_basic/Sort templates',
3030
'cat.templates/10_basic/Multiple template',
31+
'update/100_synthetic_source/keyword',
32+
'update/100_synthetic_source/stored text'
3133
].join(',')
3234
}

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/update/100_synthetic_source.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ setup:
66
---
77
keyword:
88
- requires:
9-
cluster_features: ["gte_v8.4.0"]
10-
reason: introduced in 8.4.0
9+
cluster_features: [ "mapper.synthetic_recovery_source" ]
10+
reason: requires synthetic recovery source
1111

1212
- do:
1313
indices.create:
@@ -60,13 +60,14 @@ keyword:
6060
index: test
6161
run_expensive_tasks: true
6262
- is_false: test.fields._source
63-
- is_true: test.fields._recovery_source
63+
# When synthetic source is used there is no _recovery_source field
64+
- match: { test.fields._recovery_source: null }
6465

6566
---
6667
stored text:
6768
- requires:
68-
cluster_features: ["gte_v8.5.0"]
69-
reason: introduced in 8.5.0
69+
cluster_features: [ "mapper.synthetic_recovery_source" ]
70+
reason: requires synthetic recovery source
7071

7172
- do:
7273
indices.create:
@@ -121,4 +122,5 @@ stored text:
121122
index: test
122123
run_expensive_tasks: true
123124
- is_false: test.fields._source
124-
- is_true: test.fields._recovery_source
125+
# When synthetic source is used there is no _recovery_source field
126+
- match: { test.fields._recovery_source: null }

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ static TransportVersion def(int id) {
175175
public static final TransportVersion COHERE_BIT_EMBEDDING_TYPE_SUPPORT_ADDED_BACKPORT_8_X = def(8_840_0_01);
176176
public static final TransportVersion ELASTICSEARCH_9_0 = def(9_000_0_00);
177177
public static final TransportVersion COHERE_BIT_EMBEDDING_TYPE_SUPPORT_ADDED = def(9_001_0_00);
178+
public static final TransportVersion TRANSPORT_STATS_HANDLING_TIME_REQUIRED = def(9_002_0_00);
179+
178180
/*
179181
* STOP! READ THIS FIRST! No, really,
180182
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,15 @@ public static Setting<Boolean> boolSetting(String key, boolean defaultValue, Val
15801580
return new Setting<>(key, Boolean.toString(defaultValue), booleanParser(key, properties), validator, properties);
15811581
}
15821582

1583+
public static Setting<Boolean> boolSetting(
1584+
String key,
1585+
Function<Settings, String> defaultValueFn,
1586+
Validator<Boolean> validator,
1587+
Property... properties
1588+
) {
1589+
return new Setting<>(key, defaultValueFn, booleanParser(key, properties), validator, properties);
1590+
}
1591+
15831592
public static Setting<Boolean> boolSetting(String key, Function<Settings, String> defaultValueFn, Property... properties) {
15841593
return new Setting<>(key, defaultValueFn, booleanParser(key, properties), properties);
15851594
}

server/src/main/java/org/elasticsearch/index/IndexSettings.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.common.time.DateUtils;
2525
import org.elasticsearch.common.unit.ByteSizeUnit;
2626
import org.elasticsearch.common.unit.ByteSizeValue;
27+
import org.elasticsearch.common.util.FeatureFlag;
2728
import org.elasticsearch.core.TimeValue;
2829
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
2930
import org.elasticsearch.index.mapper.Mapper;
@@ -39,6 +40,7 @@
3940
import java.util.List;
4041
import java.util.Locale;
4142
import java.util.Map;
43+
import java.util.Objects;
4244
import java.util.concurrent.TimeUnit;
4345
import java.util.function.Consumer;
4446

@@ -722,9 +724,25 @@ public Iterator<Setting<?>> settings() {
722724
Setting.Property.ServerlessPublic
723725
);
724726

727+
public static final FeatureFlag RECOVERY_USE_SYNTHETIC_SOURCE = new FeatureFlag("index_recovery_use_synthetic_source");
725728
public static final Setting<Boolean> RECOVERY_USE_SYNTHETIC_SOURCE_SETTING = Setting.boolSetting(
726729
"index.recovery.use_synthetic_source",
727-
false,
730+
settings -> {
731+
boolean isSyntheticSourceRecoveryFeatureFlagEnabled = RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled();
732+
boolean isNewIndexVersion = SETTING_INDEX_VERSION_CREATED.get(settings)
733+
.onOrAfter(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT);
734+
boolean isIndexVersionInBackportRange = SETTING_INDEX_VERSION_CREATED.get(settings)
735+
.between(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT_BACKPORT, IndexVersions.UPGRADE_TO_LUCENE_10_0_0);
736+
737+
boolean useSyntheticRecoverySource = isSyntheticSourceRecoveryFeatureFlagEnabled
738+
&& (isNewIndexVersion || isIndexVersionInBackportRange);
739+
740+
return String.valueOf(
741+
useSyntheticRecoverySource
742+
&& Objects.equals(INDEX_MAPPER_SOURCE_MODE_SETTING.get(settings), SourceFieldMapper.Mode.SYNTHETIC)
743+
);
744+
745+
},
728746
new Setting.Validator<>() {
729747
@Override
730748
public void validate(Boolean value) {}
@@ -1083,7 +1101,8 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
10831101
skipIgnoredSourceRead = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
10841102
indexMappingSourceMode = scopedSettings.get(INDEX_MAPPER_SOURCE_MODE_SETTING);
10851103
recoverySourceEnabled = RecoverySettings.INDICES_RECOVERY_SOURCE_ENABLED_SETTING.get(nodeSettings);
1086-
recoverySourceSyntheticEnabled = scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
1104+
recoverySourceSyntheticEnabled = DiscoveryNode.isStateless(nodeSettings) == false
1105+
&& scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
10871106
if (recoverySourceSyntheticEnabled) {
10881107
if (DiscoveryNode.isStateless(settings)) {
10891108
throw new IllegalArgumentException("synthetic recovery source is only allowed in stateful");

server/src/main/java/org/elasticsearch/index/IndexVersions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ private static Version parseUnchecked(String version) {
134134
public static final IndexVersion UPGRADE_TO_LUCENE_9_12_1 = def(8_523_0_00, parseUnchecked("9.12.1"));
135135
public static final IndexVersion INFERENCE_METADATA_FIELDS_BACKPORT = def(8_524_0_00, parseUnchecked("9.12.1"));
136136
public static final IndexVersion LOGSB_OPTIONAL_SORTING_ON_HOST_NAME_BACKPORT = def(8_525_0_00, parseUnchecked("9.12.1"));
137+
public static final IndexVersion USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT_BACKPORT = def(8_526_0_00, parseUnchecked("9.12.1"));
137138
public static final IndexVersion UPGRADE_TO_LUCENE_10_0_0 = def(9_000_0_00, Version.LUCENE_10_0_0);
138139
public static final IndexVersion LOGSDB_DEFAULT_IGNORE_DYNAMIC_BEYOND_LIMIT = def(9_001_0_00, Version.LUCENE_10_0_0);
139140
public static final IndexVersion TIME_BASED_K_ORDERED_DOC_ID = def(9_002_0_00, Version.LUCENE_10_0_0);
@@ -144,6 +145,7 @@ private static Version parseUnchecked(String version) {
144145
public static final IndexVersion SOURCE_MAPPER_MODE_ATTRIBUTE_NOOP = def(9_007_0_00, Version.LUCENE_10_0_0);
145146
public static final IndexVersion HOSTNAME_DOC_VALUES_SPARSE_INDEX = def(9_008_0_00, Version.LUCENE_10_0_0);
146147
public static final IndexVersion UPGRADE_TO_LUCENE_10_1_0 = def(9_009_0_00, Version.LUCENE_10_1_0);
148+
public static final IndexVersion USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT = def(9_010_00_0, Version.LUCENE_10_1_0);
147149
/*
148150
* STOP! READ THIS FIRST! No, really,
149151
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _

server/src/main/java/org/elasticsearch/transport/TransportStats.java

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import org.elasticsearch.common.unit.ByteSizeValue;
1919
import org.elasticsearch.common.xcontent.ChunkedToXContent;
2020
import org.elasticsearch.core.TimeValue;
21-
import org.elasticsearch.core.UpdateForV9;
2221
import org.elasticsearch.xcontent.ToXContent;
2322
import org.elasticsearch.xcontent.XContentBuilder;
2423

@@ -70,18 +69,16 @@ public TransportStats(StreamInput in) throws IOException {
7069
rxSize = in.readVLong();
7170
txCount = in.readVLong();
7271
txSize = in.readVLong();
73-
if (in.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0) && in.readBoolean()) {
74-
inboundHandlingTimeBucketFrequencies = new long[HandlingTimeTracker.BUCKET_COUNT];
75-
for (int i = 0; i < inboundHandlingTimeBucketFrequencies.length; i++) {
76-
inboundHandlingTimeBucketFrequencies[i] = in.readVLong();
77-
}
78-
outboundHandlingTimeBucketFrequencies = new long[HandlingTimeTracker.BUCKET_COUNT];
79-
for (int i = 0; i < inboundHandlingTimeBucketFrequencies.length; i++) {
80-
outboundHandlingTimeBucketFrequencies[i] = in.readVLong();
81-
}
82-
} else {
83-
inboundHandlingTimeBucketFrequencies = new long[0];
84-
outboundHandlingTimeBucketFrequencies = new long[0];
72+
if (in.getTransportVersion().before(TransportVersions.TRANSPORT_STATS_HANDLING_TIME_REQUIRED)) {
73+
in.readBoolean();
74+
}
75+
inboundHandlingTimeBucketFrequencies = new long[HandlingTimeTracker.BUCKET_COUNT];
76+
for (int i = 0; i < inboundHandlingTimeBucketFrequencies.length; i++) {
77+
inboundHandlingTimeBucketFrequencies[i] = in.readVLong();
78+
}
79+
outboundHandlingTimeBucketFrequencies = new long[HandlingTimeTracker.BUCKET_COUNT];
80+
for (int i = 0; i < inboundHandlingTimeBucketFrequencies.length; i++) {
81+
outboundHandlingTimeBucketFrequencies[i] = in.readVLong();
8582
}
8683
if (in.getTransportVersion().onOrAfter(TransportVersions.V_8_8_0)) {
8784
transportActionStats = Collections.unmodifiableMap(in.readOrderedMap(StreamInput::readString, TransportActionStats::new));
@@ -99,15 +96,16 @@ public void writeTo(StreamOutput out) throws IOException {
9996
out.writeVLong(rxSize);
10097
out.writeVLong(txCount);
10198
out.writeVLong(txSize);
102-
if (out.getTransportVersion().onOrAfter(TransportVersions.V_8_1_0)) {
103-
assert (inboundHandlingTimeBucketFrequencies.length > 0) == (outboundHandlingTimeBucketFrequencies.length > 0);
104-
out.writeBoolean(inboundHandlingTimeBucketFrequencies.length > 0);
105-
for (long handlingTimeBucketFrequency : inboundHandlingTimeBucketFrequencies) {
106-
out.writeVLong(handlingTimeBucketFrequency);
107-
}
108-
for (long handlingTimeBucketFrequency : outboundHandlingTimeBucketFrequencies) {
109-
out.writeVLong(handlingTimeBucketFrequency);
110-
}
99+
assert inboundHandlingTimeBucketFrequencies.length == HandlingTimeTracker.BUCKET_COUNT;
100+
assert outboundHandlingTimeBucketFrequencies.length == HandlingTimeTracker.BUCKET_COUNT;
101+
if (out.getTransportVersion().before(TransportVersions.TRANSPORT_STATS_HANDLING_TIME_REQUIRED)) {
102+
out.writeBoolean(true);
103+
}
104+
for (long handlingTimeBucketFrequency : inboundHandlingTimeBucketFrequencies) {
105+
out.writeVLong(handlingTimeBucketFrequency);
106+
}
107+
for (long handlingTimeBucketFrequency : outboundHandlingTimeBucketFrequencies) {
108+
out.writeVLong(handlingTimeBucketFrequency);
111109
}
112110
if (out.getTransportVersion().onOrAfter(TransportVersions.V_8_8_0)) {
113111
out.writeMap(transportActionStats, StreamOutput::writeWriteable);
@@ -166,24 +164,13 @@ public Map<String, TransportActionStats> getTransportActionStats() {
166164
return transportActionStats;
167165
}
168166

169-
@UpdateForV9(owner = UpdateForV9.Owner.DISTRIBUTED_COORDINATION)
170-
// Review and simplify the if-else blocks containing this symbol once v9 is released
171-
private static final boolean IMPOSSIBLE_IN_V9 = true;
172-
173167
private boolean assertHistogramsConsistent() {
174168
assert inboundHandlingTimeBucketFrequencies.length == outboundHandlingTimeBucketFrequencies.length;
175-
if (inboundHandlingTimeBucketFrequencies.length == 0) {
176-
// Stats came from before v8.1
177-
assert IMPOSSIBLE_IN_V9;
178-
} else {
179-
assert inboundHandlingTimeBucketFrequencies.length == HandlingTimeTracker.BUCKET_COUNT;
180-
}
169+
assert inboundHandlingTimeBucketFrequencies.length == HandlingTimeTracker.BUCKET_COUNT;
181170
return true;
182171
}
183172

184173
@Override
185-
@UpdateForV9(owner = UpdateForV9.Owner.DISTRIBUTED_COORDINATION)
186-
// review the "if" blocks checking for non-empty once we have
187174
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerParams) {
188175
return Iterators.concat(Iterators.single((builder, params) -> {
189176
builder.startObject(Fields.TRANSPORT);
@@ -193,19 +180,10 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP
193180
builder.humanReadableField(Fields.RX_SIZE_IN_BYTES, Fields.RX_SIZE, ByteSizeValue.ofBytes(rxSize));
194181
builder.field(Fields.TX_COUNT, txCount);
195182
builder.humanReadableField(Fields.TX_SIZE_IN_BYTES, Fields.TX_SIZE, ByteSizeValue.ofBytes(txSize));
196-
if (inboundHandlingTimeBucketFrequencies.length > 0) {
197-
histogramToXContent(builder, inboundHandlingTimeBucketFrequencies, Fields.INBOUND_HANDLING_TIME_HISTOGRAM);
198-
histogramToXContent(builder, outboundHandlingTimeBucketFrequencies, Fields.OUTBOUND_HANDLING_TIME_HISTOGRAM);
199-
} else {
200-
// Stats came from before v8.1
201-
assert IMPOSSIBLE_IN_V9;
202-
}
203-
if (transportActionStats.isEmpty() == false) {
204-
builder.startObject(Fields.ACTIONS);
205-
} else {
206-
// Stats came from before v8.8
207-
assert IMPOSSIBLE_IN_V9;
208-
}
183+
assert inboundHandlingTimeBucketFrequencies.length > 0;
184+
histogramToXContent(builder, inboundHandlingTimeBucketFrequencies, Fields.INBOUND_HANDLING_TIME_HISTOGRAM);
185+
histogramToXContent(builder, outboundHandlingTimeBucketFrequencies, Fields.OUTBOUND_HANDLING_TIME_HISTOGRAM);
186+
builder.startObject(Fields.ACTIONS);
209187
return builder;
210188
}),
211189

@@ -215,12 +193,7 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP
215193
return builder;
216194
}),
217195

218-
Iterators.single((builder, params) -> {
219-
if (transportActionStats.isEmpty() == false) {
220-
builder.endObject();
221-
}
222-
return builder.endObject();
223-
})
196+
Iterators.single((builder, params) -> { return builder.endObject().endObject(); })
224197
);
225198
}
226199

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,8 +2427,14 @@ protected void validateRoundTripReader(String syntheticSource, DirectoryReader r
24272427
// and since the copy is exact, contents of ignored source are different.
24282428
assertReaderEquals(
24292429
"round trip " + syntheticSource,
2430-
new FieldMaskingReader(Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME), reader),
2431-
new FieldMaskingReader(Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME), roundTripReader)
2430+
new FieldMaskingReader(
2431+
Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME),
2432+
reader
2433+
),
2434+
new FieldMaskingReader(
2435+
Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME),
2436+
roundTripReader
2437+
)
24322438
);
24332439
}
24342440
}

0 commit comments

Comments
 (0)