Skip to content

Commit 58b539c

Browse files
authored
[9.1] Improved validation message for unknown archived settings (elastic#138810) (elastic#138875)
* Improved validation message for unknown archived settings (elastic#138810) (cherry picked from commit 074dc72) # Conflicts: # server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt * Update ScopedSettingsTests.java
1 parent 0c30c40 commit 58b539c

File tree

4 files changed

+64
-19
lines changed

4 files changed

+64
-19
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
@@ -85,6 +85,7 @@ public enum ReferenceDocs {
8585
SECURE_SETTINGS,
8686
CLUSTER_SHARD_LIMIT,
8787
DELETE_INDEX_BLOCK,
88+
ARCHIVED_SETTINGS,
8889
// this comment keeps the ';' on the next line so every entry above has a trailing ',' which makes the diff for adding new links cleaner
8990
;
9091

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;
@@ -543,29 +545,40 @@ void validate(final String key, final Settings settings, final boolean validateV
543545
void validate(final String key, final Settings settings, final boolean validateValue, final boolean validateInternalOrPrivateIndex) {
544546
Setting<?> setting = getRaw(key);
545547
if (setting == null) {
546-
LevenshteinDistance ld = new LevenshteinDistance();
547-
List<Tuple<Float, String>> scoredKeys = new ArrayList<>();
548-
for (String k : this.keySettings.keySet()) {
549-
float distance = ld.getDistance(key, k);
550-
if (distance > 0.7f) {
551-
scoredKeys.add(new Tuple<>(distance, k));
552-
}
553-
}
554-
CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1()));
555-
String msgPrefix = "unknown setting";
556548
SecureSettings secureSettings = settings.getSecureSettings();
557-
if (secureSettings != null && settings.getSecureSettings().getSettingNames().contains(key)) {
558-
msgPrefix = "unknown secure setting";
549+
String msgPrefix = (secureSettings != null && secureSettings.getSettingNames().contains(key))
550+
? "unknown secure setting"
551+
: "unknown setting";
552+
if (key.startsWith(ARCHIVED_SETTINGS_PREFIX)) {
553+
throw new IllegalArgumentException(
554+
Strings.format(
555+
"%s [%s] was archived after upgrading, and must be removed. See [%s] for details.",
556+
msgPrefix,
557+
key,
558+
ReferenceDocs.ARCHIVED_SETTINGS
559+
)
560+
);
559561
}
560-
String msg = msgPrefix + " [" + key + "]";
561-
List<String> keys = scoredKeys.stream().map((a) -> a.v2()).toList();
562+
List<String> keys = findSimilarKeys(key);
562563
if (keys.isEmpty() == false) {
563-
msg += " did you mean " + (keys.size() == 1 ? "[" + keys.get(0) + "]" : "any of " + keys.toString()) + "?";
564+
throw new IllegalArgumentException(
565+
Strings.format(
566+
"%s [%s] did you mean %s?",
567+
msgPrefix,
568+
key,
569+
(keys.size() == 1 ? "[" + keys.getFirst() + "]" : "any of " + keys)
570+
)
571+
);
564572
} else {
565-
msg += " please check that any required plugins are installed, or check the breaking changes documentation for removed "
566-
+ "settings";
573+
throw new IllegalArgumentException(
574+
Strings.format(
575+
"%s [%s] please check that any required plugins are installed,"
576+
+ " or check the breaking changes documentation for removed settings",
577+
msgPrefix,
578+
key
579+
)
580+
);
567581
}
568-
throw new IllegalArgumentException(msg);
569582
} else {
570583
Set<Setting.SettingDependency> settingsDependencies = setting.getSettingsDependencies(key);
571584
if (setting.hasComplexMatcher()) {
@@ -618,6 +631,19 @@ void validate(final String key, final Settings settings, final boolean validateV
618631
}
619632
}
620633

634+
private List<String> findSimilarKeys(String key) {
635+
LevenshteinDistance ld = new LevenshteinDistance();
636+
List<Tuple<Float, String>> scoredKeys = new ArrayList<>();
637+
for (String k : this.keySettings.keySet()) {
638+
float distance = ld.getDistance(key, k);
639+
if (distance > 0.7f) {
640+
scoredKeys.add(new Tuple<>(distance, k));
641+
}
642+
}
643+
CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1()));
644+
return scoredKeys.stream().map((a) -> a.v2()).toList();
645+
}
646+
621647
/**
622648
* Transactional interface to update settings.
623649
* @see Setting

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ ALLOCATION_EXPLAIN_NO_COPIES troubleshoot/ela
4646
ALLOCATION_EXPLAIN_MAX_RETRY troubleshoot/elasticsearch/diagnose-unassigned-shards#maximum-retries-exceeded
4747
SECURE_SETTINGS deploy-manage/security/secure-settings
4848
CLUSTER_SHARD_LIMIT reference/elasticsearch/configuration-reference/miscellaneous-cluster-settings#cluster-shard-limit
49-
DELETE_INDEX_BLOCK api/doc/elasticsearch/operation/operation-indices-remove-block
49+
DELETE_INDEX_BLOCK api/doc/elasticsearch/operation/operation-indices-remove-block
50+
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.1] "
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)