Skip to content

Commit 6785391

Browse files
committed
Merge branch 'master' into index-lifecycle
2 parents 43eaec3 + a486177 commit 6785391

File tree

22 files changed

+856
-92
lines changed

22 files changed

+856
-92
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/ClusterClientIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ public void testClusterHealthYellowClusterLevel() throws IOException {
129129
createIndex("index2", Settings.EMPTY);
130130
ClusterHealthRequest request = new ClusterHealthRequest();
131131
request.timeout("5s");
132-
request.level(ClusterHealthRequest.Level.CLUSTER);
133132
ClusterHealthResponse response = execute(request, highLevelClient().cluster()::health, highLevelClient().cluster()::healthAsync);
134133

135134
assertYellowShards(response);
@@ -170,6 +169,7 @@ public void testClusterHealthYellowSpecificIndex() throws IOException {
170169
createIndex("index", Settings.EMPTY);
171170
createIndex("index2", Settings.EMPTY);
172171
ClusterHealthRequest request = new ClusterHealthRequest("index");
172+
request.level(ClusterHealthRequest.Level.SHARDS);
173173
request.timeout("5s");
174174
ClusterHealthResponse response = execute(request, highLevelClient().cluster()::health, highLevelClient().cluster()::healthAsync);
175175

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ public void testClusterHealth() {
15681568
healthRequest.level(level);
15691569
expectedParams.put("level", level.name().toLowerCase(Locale.ROOT));
15701570
} else {
1571-
expectedParams.put("level", "shards");
1571+
expectedParams.put("level", "cluster");
15721572
}
15731573
if (randomBoolean()) {
15741574
Priority priority = randomFrom(Priority.values());

docs/java-rest/high-level/cluster/health.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ include-tagged::{doc-tests}/ClusterClientDocumentationIT.java[health-request-wai
6767
include-tagged::{doc-tests}/ClusterClientDocumentationIT.java[health-request-level]
6868
--------------------------------------------------
6969
<1> The level of detail of the returned health information. Accepts a `ClusterHealthRequest.Level` value.
70+
Default value is `cluster`.
7071

7172
["source","java",subs="attributes,callouts,macros"]
7273
--------------------------------------------------

docs/reference/migration/migrate_7_0/restclient.asciidoc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,11 @@ header, e.g. `client.index(indexRequest)` becomes
1010
`client.index(indexRequest, RequestOptions.DEFAULT)`.
1111
In case you are specifying headers
1212
e.g. `client.index(indexRequest, new Header("name" "value"))` becomes
13-
`client.index(indexRequest, RequestOptions.DEFAULT.toBuilder().addHeader("name", "value").build());`
13+
`client.index(indexRequest, RequestOptions.DEFAULT.toBuilder().addHeader("name", "value").build());`
14+
15+
==== Cluster Health API default to `cluster` level
16+
17+
The Cluster Health API used to default to `shards` level to ease migration
18+
from transport client that doesn't support the `level` parameter and always
19+
returns information including indices and shards details. The level default
20+
value has been aligned with the Elasticsearch default level: `cluster`.

server/src/main/java/org/elasticsearch/action/admin/cluster/health/ClusterHealthRequest.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ public class ClusterHealthRequest extends MasterNodeReadRequest<ClusterHealthReq
4848
private Priority waitForEvents = null;
4949
/**
5050
* Only used by the high-level REST Client. Controls the details level of the health information returned.
51-
* The default value is 'shards' so it is backward compatible with the transport client behaviour.
51+
* The default value is 'cluster'.
5252
*/
53-
private Level level = Level.SHARDS;
53+
private Level level = Level.CLUSTER;
5454

5555
public ClusterHealthRequest() {
5656
}
@@ -250,8 +250,7 @@ public Priority waitForEvents() {
250250

251251
/**
252252
* Set the level of detail for the health information to be returned.
253-
* Only used by the high-level REST Client
254-
* The default value is 'shards' so it is backward compatible with the transport client behaviour.
253+
* Only used by the high-level REST Client.
255254
*/
256255
public void level(Level level) {
257256
this.level = Objects.requireNonNull(level, "level must not be null");
@@ -260,7 +259,6 @@ public void level(Level level) {
260259
/**
261260
* Get the level of detail for the health information to be returned.
262261
* Only used by the high-level REST Client.
263-
* The default value is 'shards' so it is backward compatible with the transport client behaviour.
264262
*/
265263
public Level level() {
266264
return level;

server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataUpdateSettingsService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ public void updateSettings(final UpdateSettingsClusterStateUpdateRequest request
8282
Settings.Builder settingsForOpenIndices = Settings.builder();
8383
final Set<String> skippedSettings = new HashSet<>();
8484

85-
indexScopedSettings.validate(normalizedSettings.filter(s -> Regex.isSimpleMatchPattern(s) == false /* don't validate wildcards */),
86-
false); //don't validate dependencies here we check it below never allow to change the number of shards
85+
indexScopedSettings.validate(
86+
normalizedSettings.filter(s -> Regex.isSimpleMatchPattern(s) == false), // don't validate wildcards
87+
false, // don't validate dependencies here we check it below never allow to change the number of shards
88+
true); // validate internal index settings
8789
for (String key : normalizedSettings.keySet()) {
8890
Setting setting = indexScopedSettings.get(key);
8991
boolean isWildcard = setting == null && Regex.isSimpleMatchPattern(key);

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

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,18 @@ public final void validate(final Settings settings, final boolean validateDepend
282282
validate(settings, validateDependencies, false, false);
283283
}
284284

285+
/**
286+
* Validates that all settings are registered and valid.
287+
*
288+
* @param settings the settings to validate
289+
* @param validateDependencies true if dependent settings should be validated
290+
* @param validateInternalIndex true if internal index settings should be validated
291+
* @see Setting#getSettingsDependencies(String)
292+
*/
293+
public final void validate(final Settings settings, final boolean validateDependencies, final boolean validateInternalIndex) {
294+
validate(settings, validateDependencies, false, false, validateInternalIndex);
295+
}
296+
285297
/**
286298
* Validates that all settings are registered and valid.
287299
*
@@ -296,6 +308,25 @@ public final void validate(
296308
final boolean validateDependencies,
297309
final boolean ignorePrivateSettings,
298310
final boolean ignoreArchivedSettings) {
311+
validate(settings, validateDependencies, ignorePrivateSettings, ignoreArchivedSettings, false);
312+
}
313+
314+
/**
315+
* Validates that all settings are registered and valid.
316+
*
317+
* @param settings the settings
318+
* @param validateDependencies true if dependent settings should be validated
319+
* @param ignorePrivateSettings true if private settings should be ignored during validation
320+
* @param ignoreArchivedSettings true if archived settings should be ignored during validation
321+
* @param validateInternalIndex true if index internal settings should be validated
322+
* @see Setting#getSettingsDependencies(String)
323+
*/
324+
public final void validate(
325+
final Settings settings,
326+
final boolean validateDependencies,
327+
final boolean ignorePrivateSettings,
328+
final boolean ignoreArchivedSettings,
329+
final boolean validateInternalIndex) {
299330
final List<RuntimeException> exceptions = new ArrayList<>();
300331
for (final String key : settings.keySet()) { // settings iterate in deterministic fashion
301332
if (isPrivateSetting(key) && ignorePrivateSettings) {
@@ -305,7 +336,7 @@ public final void validate(
305336
continue;
306337
}
307338
try {
308-
validate(key, settings, validateDependencies);
339+
validate(key, settings, validateDependencies, validateInternalIndex);
309340
} catch (final RuntimeException ex) {
310341
exceptions.add(ex);
311342
}
@@ -314,9 +345,27 @@ public final void validate(
314345
}
315346

316347
/**
317-
* Validates that the setting is valid
348+
* Validates that the settings is valid.
349+
*
350+
* @param key the key of the setting to validate
351+
* @param settings the settings
352+
* @param validateDependencies true if dependent settings should be validated
353+
* @throws IllegalArgumentException if the setting is invalid
318354
*/
319-
void validate(String key, Settings settings, boolean validateDependencies) {
355+
void validate(final String key, final Settings settings, final boolean validateDependencies) {
356+
validate(key, settings, validateDependencies, false);
357+
}
358+
359+
/**
360+
* Validates that the settings is valid.
361+
*
362+
* @param key the key of the setting to validate
363+
* @param settings the settings
364+
* @param validateDependencies true if dependent settings should be validated
365+
* @param validateInternalIndex true if internal index settings should be validated
366+
* @throws IllegalArgumentException if the setting is invalid
367+
*/
368+
void validate(final String key, final Settings settings, final boolean validateDependencies, final boolean validateInternalIndex) {
320369
Setting setting = getRaw(key);
321370
if (setting == null) {
322371
LevensteinDistance ld = new LevensteinDistance();
@@ -356,6 +405,11 @@ void validate(String key, Settings settings, boolean validateDependencies) {
356405
}
357406
}
358407
}
408+
// the only time that validateInternalIndex should be true is if this call is coming via the update settings API
409+
if (validateInternalIndex && setting.getProperties().contains(Setting.Property.InternalIndex)) {
410+
throw new IllegalArgumentException(
411+
"can not update internal setting [" + setting.getKey() + "]; this setting is managed via a dedicated API");
412+
}
359413
}
360414
setting.get(settings);
361415
}

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ public enum Property {
120120
* Mark this setting as not copyable during an index resize (shrink or split). This property can only be applied to settings that
121121
* also have {@link Property#IndexScope}.
122122
*/
123-
NotCopyableOnResize
123+
NotCopyableOnResize,
124+
125+
/**
126+
* Indicates an index-level setting that is managed internally. Such a setting can only be added to an index on index creation but
127+
* can not be updated via the update API.
128+
*/
129+
InternalIndex
124130
}
125131

126132
private final Key key;
@@ -152,14 +158,18 @@ private Setting(Key key, @Nullable Setting<T> fallbackSetting, Function<Settings
152158
if (propertiesAsSet.contains(Property.Dynamic) && propertiesAsSet.contains(Property.Final)) {
153159
throw new IllegalArgumentException("final setting [" + key + "] cannot be dynamic");
154160
}
155-
if (propertiesAsSet.contains(Property.NotCopyableOnResize) && propertiesAsSet.contains(Property.IndexScope) == false) {
156-
throw new IllegalArgumentException(
157-
"non-index-scoped setting [" + key + "] can not have property [" + Property.NotCopyableOnResize + "]");
158-
}
161+
checkPropertyRequiresIndexScope(propertiesAsSet, Property.NotCopyableOnResize);
162+
checkPropertyRequiresIndexScope(propertiesAsSet, Property.InternalIndex);
159163
this.properties = propertiesAsSet;
160164
}
161165
}
162166

167+
private void checkPropertyRequiresIndexScope(final EnumSet<Property> properties, final Property property) {
168+
if (properties.contains(property) && properties.contains(Property.IndexScope) == false) {
169+
throw new IllegalArgumentException("non-index-scoped setting [" + key + "] can not have property [" + property + "]");
170+
}
171+
}
172+
163173
/**
164174
* Creates a new Setting instance
165175
* @param key the settings key for this setting.

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,4 +876,28 @@ public void testFinalSettingUpdateFail() {
876876
Settings.builder().put(currentSettings), Settings.builder(), "node"));
877877
assertThat(exc.getMessage(), containsString("final node setting [some.final.group.foo]"));
878878
}
879+
880+
public void testInternalIndexSettingsFailsValidation() {
881+
final Setting<String> indexInternalSetting = Setting.simpleString("index.internal", Property.InternalIndex, Property.IndexScope);
882+
final IndexScopedSettings indexScopedSettings =
883+
new IndexScopedSettings(Settings.EMPTY, Collections.singleton(indexInternalSetting));
884+
final IllegalArgumentException e = expectThrows(
885+
IllegalArgumentException.class,
886+
() -> {
887+
final Settings settings = Settings.builder().put("index.internal", "internal").build();
888+
indexScopedSettings.validate(settings, false, /* validateInternalIndex */ true);
889+
});
890+
final String message = "can not update internal setting [index.internal]; this setting is managed via a dedicated API";
891+
assertThat(e, hasToString(containsString(message)));
892+
}
893+
894+
public void testInternalIndexSettingsSkipValidation() {
895+
final Setting<String> internalIndexSetting = Setting.simpleString("index.internal", Property.InternalIndex, Property.IndexScope);
896+
final IndexScopedSettings indexScopedSettings =
897+
new IndexScopedSettings(Settings.EMPTY, Collections.singleton(internalIndexSetting));
898+
// nothing should happen, validation should not throw an exception
899+
final Settings settings = Settings.builder().put("index.internal", "internal").build();
900+
indexScopedSettings.validate(settings, false, /* validateInternalIndex */ false);
901+
}
902+
879903
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,13 @@ public void testRejectNonIndexScopedNotCopyableOnResizeSetting() {
735735
assertThat(e, hasToString(containsString("non-index-scoped setting [foo.bar] can not have property [NotCopyableOnResize]")));
736736
}
737737

738+
public void testRejectNonIndexScopedIndexInternalSetting() {
739+
final IllegalArgumentException e = expectThrows(
740+
IllegalArgumentException.class,
741+
() -> Setting.simpleString("foo.bar", Property.InternalIndex));
742+
assertThat(e, hasToString(containsString("non-index-scoped setting [foo.bar] can not have property [InternalIndex]")));
743+
}
744+
738745
public void testTimeValue() {
739746
final TimeValue random = TimeValue.parseTimeValue(randomTimeValue(), "test");
740747

0 commit comments

Comments
 (0)