Skip to content

Commit 4974336

Browse files
authored
Fix synthetic recovery source version validation. (#118924)
The validation didn't work as expected, because created version was always 0 (which is created version default value). Moving the validation to a place that does have access to the index version.
1 parent b348671 commit 4974336

File tree

5 files changed

+61
-74
lines changed

5 files changed

+61
-74
lines changed

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,3 +2012,42 @@ synthetic_source with copy_to pointing inside dynamic object:
20122012
hits.hits.2.fields:
20132013
c.copy.keyword: [ "hello", "zap" ]
20142014

2015+
---
2016+
create index with use_synthetic_source:
2017+
- requires:
2018+
cluster_features: ["mapper.synthetic_recovery_source"]
2019+
reason: requires synthetic recovery source
2020+
2021+
- do:
2022+
indices.create:
2023+
index: test
2024+
body:
2025+
settings:
2026+
index:
2027+
recovery:
2028+
use_synthetic_source: true
2029+
mapping:
2030+
source:
2031+
mode: synthetic
2032+
2033+
- do:
2034+
indices.get_settings: {}
2035+
- match: { test.settings.index.mapping.source.mode: synthetic}
2036+
- is_true: test.settings.index.recovery.use_synthetic_source
2037+
2038+
- do:
2039+
bulk:
2040+
index: test
2041+
refresh: true
2042+
body:
2043+
- '{ "create": { } }'
2044+
- '{ "field": "aaaa" }'
2045+
- '{ "create": { } }'
2046+
- '{ "field": "bbbb" }'
2047+
2048+
- do:
2049+
indices.disk_usage:
2050+
index: test
2051+
run_expensive_tasks: true
2052+
- gt: { test.fields.field.total_in_bytes: 0 }
2053+
- is_false: test.fields.field._recovery_source

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

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -685,29 +685,11 @@ public void validate(Boolean enabled, Map<Setting<?>, Object> settings) {
685685
);
686686
}
687687
}
688-
689-
// Verify that all nodes can handle this setting
690-
var version = (IndexVersion) settings.get(SETTING_INDEX_VERSION_CREATED);
691-
if (version.before(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY)
692-
&& version.between(
693-
IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT,
694-
IndexVersions.UPGRADE_TO_LUCENE_10_0_0
695-
) == false) {
696-
throw new IllegalArgumentException(
697-
String.format(
698-
Locale.ROOT,
699-
"The setting [%s] is unavailable on this cluster because some nodes are running older "
700-
+ "versions that do not support it. Please upgrade all nodes to the latest version "
701-
+ "and try again.",
702-
RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey()
703-
)
704-
);
705-
}
706688
}
707689

708690
@Override
709691
public Iterator<Setting<?>> settings() {
710-
List<Setting<?>> res = List.of(INDEX_MAPPER_SOURCE_MODE_SETTING, SETTING_INDEX_VERSION_CREATED, MODE);
692+
List<Setting<?>> res = List.of(INDEX_MAPPER_SOURCE_MODE_SETTING, MODE);
711693
return res.iterator();
712694
}
713695
},
@@ -1050,6 +1032,24 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
10501032
indexMappingSourceMode = scopedSettings.get(INDEX_MAPPER_SOURCE_MODE_SETTING);
10511033
recoverySourceEnabled = RecoverySettings.INDICES_RECOVERY_SOURCE_ENABLED_SETTING.get(nodeSettings);
10521034
recoverySourceSyntheticEnabled = scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
1035+
if (recoverySourceSyntheticEnabled) {
1036+
// Verify that all nodes can handle this setting
1037+
if (version.before(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY)
1038+
&& version.between(
1039+
IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT,
1040+
IndexVersions.UPGRADE_TO_LUCENE_10_0_0
1041+
) == false) {
1042+
throw new IllegalArgumentException(
1043+
String.format(
1044+
Locale.ROOT,
1045+
"The setting [%s] is unavailable on this cluster because some nodes are running older "
1046+
+ "versions that do not support it. Please upgrade all nodes to the latest version "
1047+
+ "and try again.",
1048+
RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey()
1049+
)
1050+
);
1051+
}
1052+
}
10531053

10541054
scopedSettings.addSettingsUpdateConsumer(
10551055
MergePolicyConfig.INDEX_COMPOUND_FORMAT_SETTING,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public Set<NodeFeature> getTestFeatures() {
7777
DocumentParser.FIX_PARSING_SUBOBJECTS_FALSE_DYNAMIC_FALSE,
7878
CONSTANT_KEYWORD_SYNTHETIC_SOURCE_WRITE_FIX,
7979
META_FETCH_FIELDS_ERROR_CODE_CHANGED,
80-
SPARSE_VECTOR_STORE_SUPPORT
80+
SPARSE_VECTOR_STORE_SUPPORT,
81+
SourceFieldMapper.SYNTHETIC_RECOVERY_SOURCE
8182
);
8283
}
8384
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class SourceFieldMapper extends MetadataFieldMapper {
5656
"mapper.source.remove_synthetic_source_only_validation"
5757
);
5858
public static final NodeFeature SOURCE_MODE_FROM_INDEX_SETTING = new NodeFeature("mapper.source.mode_from_index_setting");
59+
public static final NodeFeature SYNTHETIC_RECOVERY_SOURCE = new NodeFeature("mapper.synthetic_recovery_source");
5960

6061
public static final String NAME = "_source";
6162
public static final String RECOVERY_SOURCE_NAME = "_recovery_source";

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

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -465,60 +465,6 @@ public void testRecoverySourceWitInvalidSettings() {
465465
)
466466
);
467467
}
468-
{
469-
Settings settings = Settings.builder()
470-
.put(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(), SourceFieldMapper.Mode.SYNTHETIC.toString())
471-
.put(IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey(), true)
472-
.build();
473-
IllegalArgumentException exc = expectThrows(
474-
IllegalArgumentException.class,
475-
() -> createMapperService(
476-
IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT),
477-
settings,
478-
() -> false,
479-
topMapping(b -> {})
480-
)
481-
);
482-
assertThat(
483-
exc.getMessage(),
484-
containsString(
485-
String.format(
486-
Locale.ROOT,
487-
"The setting [%s] is unavailable on this cluster",
488-
IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey()
489-
)
490-
)
491-
);
492-
}
493-
{
494-
Settings settings = Settings.builder()
495-
.put(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(), SourceFieldMapper.Mode.SYNTHETIC.toString())
496-
.put(IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey(), true)
497-
.build();
498-
IllegalArgumentException exc = expectThrows(
499-
IllegalArgumentException.class,
500-
() -> createMapperService(
501-
IndexVersionUtils.randomVersionBetween(
502-
random(),
503-
IndexVersions.UPGRADE_TO_LUCENE_10_0_0,
504-
IndexVersions.DEPRECATE_SOURCE_MODE_MAPPER
505-
),
506-
settings,
507-
() -> false,
508-
topMapping(b -> {})
509-
)
510-
);
511-
assertThat(
512-
exc.getMessage(),
513-
containsString(
514-
String.format(
515-
Locale.ROOT,
516-
"The setting [%s] is unavailable on this cluster",
517-
IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey()
518-
)
519-
)
520-
);
521-
}
522468
}
523469

524470
public void testRecoverySourceWithSyntheticSource() throws IOException {

0 commit comments

Comments
 (0)