Skip to content

Commit 7d0ec62

Browse files
authored
[9.2] Improved validation message for unknown archived settings (elastic#138810) (elastic#138827)
* Improved validation message for unknown archived settings (elastic#138810) * Update ScopedSettingsTests.java
1 parent 32933f3 commit 7d0ec62

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

server/src/main/java/org/elasticsearch/common/ReferenceDocs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public enum ReferenceDocs {
8686
CLUSTER_SHARD_LIMIT,
8787
DEPLOY_CLOUD_DIFF_FROM_STATEFUL,
8888
DELETE_INDEX_BLOCK,
89+
ARCHIVED_SETTINGS,
8990
// this comment keeps the ';' on the next line so every entry above has a trailing ',' which makes the diff for adding new links cleaner
9091
;
9192

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

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.apache.lucene.search.spell.LevenshteinDistance;
1515
import org.apache.lucene.util.CollectionUtil;
1616
import org.elasticsearch.ExceptionsHelper;
17+
import org.elasticsearch.common.ReferenceDocs;
18+
import org.elasticsearch.common.Strings;
1719
import org.elasticsearch.common.regex.Regex;
1820
import org.elasticsearch.common.util.Maps;
1921
import org.elasticsearch.common.util.set.Sets;
@@ -560,29 +562,40 @@ void validate(final String key, final Settings settings, final boolean validateV
560562
void validate(final String key, final Settings settings, final boolean validateValue, final boolean validateInternalOrPrivateIndex) {
561563
Setting<?> setting = getRaw(key);
562564
if (setting == null) {
563-
LevenshteinDistance ld = new LevenshteinDistance();
564-
List<Tuple<Float, String>> scoredKeys = new ArrayList<>();
565-
for (String k : this.keySettings.keySet()) {
566-
float distance = ld.getDistance(key, k);
567-
if (distance > 0.7f) {
568-
scoredKeys.add(new Tuple<>(distance, k));
569-
}
570-
}
571-
CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1()));
572-
String msgPrefix = "unknown setting";
573565
SecureSettings secureSettings = settings.getSecureSettings();
574-
if (secureSettings != null && settings.getSecureSettings().getSettingNames().contains(key)) {
575-
msgPrefix = "unknown secure setting";
566+
String msgPrefix = (secureSettings != null && secureSettings.getSettingNames().contains(key))
567+
? "unknown secure setting"
568+
: "unknown setting";
569+
if (key.startsWith(ARCHIVED_SETTINGS_PREFIX)) {
570+
throw new IllegalArgumentException(
571+
Strings.format(
572+
"%s [%s] was archived after upgrading, and must be removed. See [%s] for details.",
573+
msgPrefix,
574+
key,
575+
ReferenceDocs.ARCHIVED_SETTINGS
576+
)
577+
);
576578
}
577-
String msg = msgPrefix + " [" + key + "]";
578-
List<String> keys = scoredKeys.stream().map((a) -> a.v2()).toList();
579+
List<String> keys = findSimilarKeys(key);
579580
if (keys.isEmpty() == false) {
580-
msg += " did you mean " + (keys.size() == 1 ? "[" + keys.get(0) + "]" : "any of " + keys.toString()) + "?";
581+
throw new IllegalArgumentException(
582+
Strings.format(
583+
"%s [%s] did you mean %s?",
584+
msgPrefix,
585+
key,
586+
(keys.size() == 1 ? "[" + keys.getFirst() + "]" : "any of " + keys)
587+
)
588+
);
581589
} else {
582-
msg += " please check that any required plugins are installed, or check the breaking changes documentation for removed "
583-
+ "settings";
590+
throw new IllegalArgumentException(
591+
Strings.format(
592+
"%s [%s] please check that any required plugins are installed,"
593+
+ " or check the breaking changes documentation for removed settings",
594+
msgPrefix,
595+
key
596+
)
597+
);
584598
}
585-
throw new IllegalArgumentException(msg);
586599
} else {
587600
Set<Setting.SettingDependency> settingsDependencies = setting.getSettingsDependencies(key);
588601
if (setting.hasComplexMatcher()) {
@@ -635,6 +648,19 @@ void validate(final String key, final Settings settings, final boolean validateV
635648
}
636649
}
637650

651+
private List<String> findSimilarKeys(String key) {
652+
LevenshteinDistance ld = new LevenshteinDistance();
653+
List<Tuple<Float, String>> scoredKeys = new ArrayList<>();
654+
for (String k : this.keySettings.keySet()) {
655+
float distance = ld.getDistance(key, k);
656+
if (distance > 0.7f) {
657+
scoredKeys.add(new Tuple<>(distance, k));
658+
}
659+
}
660+
CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1()));
661+
return scoredKeys.stream().map((a) -> a.v2()).toList();
662+
}
663+
638664
/**
639665
* Transactional interface to update settings.
640666
* @see Setting

server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ SECURE_SETTINGS deploy-manage/se
4848
CLUSTER_SHARD_LIMIT reference/elasticsearch/configuration-reference/miscellaneous-cluster-settings#cluster-shard-limit
4949
DEPLOY_CLOUD_DIFF_FROM_STATEFUL deploy-manage/deploy/elastic-cloud/differences-from-other-elasticsearch-offerings
5050
DELETE_INDEX_BLOCK api/doc/elasticsearch/operation/operation-indices-remove-block
51+
ARCHIVED_SETTINGS deploy-manage/upgrade/deployment-or-cluster/archived-settings

server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,23 @@ public Iterator<Setting<?>> settings() {
335335
assertThat(e3.getMessage(), equalTo("too long"));
336336
}
337337

338+
public void testValidateArchivedSetting() {
339+
IndexScopedSettings settings = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS);
340+
final IllegalArgumentException e = expectThrows(
341+
IllegalArgumentException.class,
342+
() -> settings.validate(Settings.builder().put("archived.index.store.type", "boom").build(), false)
343+
);
344+
assertThat(
345+
e.getMessage(),
346+
equalTo(
347+
"unknown setting [archived.index.store.type] was archived after upgrading, and must be removed."
348+
+ " See [https://www.elastic.co/docs/deploy-manage/upgrade/deployment-or-cluster/archived-settings?version=9.2] "
349+
+ "for details."
350+
)
351+
);
352+
353+
}
354+
338355
public void testTupleAffixUpdateConsumer() {
339356
String prefix = randomAlphaOfLength(3) + "foo.";
340357
String intSuffix = randomAlphaOfLength(3);

0 commit comments

Comments
 (0)