From aabb124209634a2d29116ca4620f2c98453f8b46 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Fri, 29 Jan 2016 18:05:18 +0100 Subject: [PATCH 01/49] Add filtering support within Setting class Now we have a nice Setting infra, we can define in Setting class if a setting should be filtered or not. So when we register a setting, setting filtering would be automatically done. Instead of writing: ```java Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER); settingsModule.registerSetting(AwsEc2Service.KEY_SETTING, false); settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.KEY_SETTING.getKey()); ``` We could simply write: ```java Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER, true); settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.KEY_SETTING.getKey()); ``` It also removes `settingsModule.registerSettingsFilterIfMissing` method. The plan would be to remove as well `settingsModule.registerSettingsFilter` method but it still used with wildcards. For example in Azure Repository plugin: ```java module.registerSettingsFilter(AzureStorageService.Storage.PREFIX + "*.account"); module.registerSettingsFilter(AzureStorageService.Storage.PREFIX + "*.key"); ``` Closes #16598. --- .../common/settings/Setting.java | 70 ++++++++++++++++--- .../common/settings/SettingsModule.java | 11 ++- .../cluster/settings/SettingsFilteringIT.java | 14 ++-- .../common/settings/SettingsModuleTests.java | 3 +- .../DedicatedClusterSnapshotRestoreIT.java | 4 +- .../snapshots/mockstore/MockRepository.java | 10 ++- .../azure/management/AzureComputeService.java | 25 ++++--- .../discovery/azure/AzureDiscoveryPlugin.java | 5 -- .../cloud/aws/AwsEc2Service.java | 12 ++-- .../discovery/ec2/Ec2DiscoveryPlugin.java | 8 --- .../azure/storage/AzureStorageService.java | 33 ++++++--- .../azure/AzureRepositoryPlugin.java | 4 +- .../elasticsearch/cloud/aws/AwsS3Service.java | 12 ++-- .../repository/s3/S3RepositoryPlugin.java | 10 --- .../repositories/s3/S3Repository.java | 4 +- 15 files changed, 141 insertions(+), 84 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index 7f64c011133..e1349cc2a00 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -71,22 +71,50 @@ public class Setting extends ToXContentToBytes { private final Function parser; private final boolean dynamic; private final Scope scope; + private final boolean filtered; + + /** + * Creates a new Setting instance, unfiltered + * @param key the settings key for this setting. + * @param defaultValue a default value function that returns the default values string representation. + * @param parser a parser that parses the string rep into a complex datatype. + * @param dynamic true if this setting can be dynamically updateable + * @param scope the scope of this setting + */ + public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope) { + this(key, defaultValue, parser, dynamic, scope, false); + } /** * Creates a new Setting instance * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable + * @param dynamic true if this setting can be dynamically updateable * @param scope the scope of this setting + * @param filtered true if this setting should be filtered */ - public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope) { + public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope, + boolean filtered) { assert parser.apply(defaultValue.apply(Settings.EMPTY)) != null || this.isGroupSetting(): "parser returned null"; this.key = key; this.defaultValue = defaultValue; this.parser = parser; this.dynamic = dynamic; this.scope = scope; + this.filtered = filtered; + } + + /** + * Creates a new Setting instance, unfiltered + * @param key the settings key for this setting. + * @param fallBackSetting a setting to fall back to if the current setting is not set. + * @param parser a parser that parses the string rep into a complex datatype. + * @param dynamic true iff this setting can be dynamically updateable + * @param scope the scope of this setting + */ + public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, Scope scope) { + this(key, fallBackSetting, parser, dynamic, scope, false); } /** @@ -96,9 +124,10 @@ public class Setting extends ToXContentToBytes { * @param parser a parser that parses the string rep into a complex datatype. * @param dynamic true iff this setting can be dynamically updateable * @param scope the scope of this setting + * @param filtered true if this setting should be filtered */ - public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, Scope scope) { - this(key, fallBackSetting::getRaw, parser, dynamic, scope); + public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, Scope scope, boolean filtered) { + this(key, fallBackSetting::getRaw, parser, dynamic, scope, filtered); } /** @@ -113,7 +142,7 @@ public class Setting extends ToXContentToBytes { } /** - * Returns true iff this setting is dynamically updateable, otherwise false + * Returns true if this setting is dynamically updateable, otherwise false */ public final boolean isDynamic() { return dynamic; @@ -126,6 +155,13 @@ public class Setting extends ToXContentToBytes { return scope; } + /** + * Returns true if this setting must be filtered, otherwise false + */ + public boolean isFiltered() { + return filtered; + } + /** * Returns true iff this setting is a group setting. Group settings represent a set of settings * rather than a single value. The key, see {@link #getKey()}, in contrast to non-group settings is a prefix like cluster.store. @@ -331,7 +367,11 @@ public class Setting extends ToXContentToBytes { public Setting(String key, String defaultValue, Function parser, boolean dynamic, Scope scope) { - this(key, (s) -> defaultValue, parser, dynamic, scope); + this(key, defaultValue, parser, dynamic, scope, false); + } + + public Setting(String key, String defaultValue, Function parser, boolean dynamic, Scope scope, boolean filtered) { + this(key, (s) -> defaultValue, parser, dynamic, scope, filtered); } public static Setting floatSetting(String key, float defaultValue, boolean dynamic, Scope scope) { @@ -357,11 +397,19 @@ public class Setting extends ToXContentToBytes { } public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), dynamic, scope); + return longSetting(key, defaultValue, minValue, dynamic, scope, false); + } + + public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, Scope scope, boolean filtered) { + return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), dynamic, scope, filtered); } public static Setting simpleString(String key, boolean dynamic, Scope scope) { - return new Setting<>(key, "", Function.identity(), dynamic, scope); + return simpleString(key, dynamic, scope, false); + } + + public static Setting simpleString(String key, boolean dynamic, Scope scope, boolean filtered) { + return new Setting<>(key, s -> "", Function.identity(), dynamic, scope, filtered); } public static int parseInt(String s, int minValue, String key) { @@ -392,7 +440,11 @@ public class Setting extends ToXContentToBytes { } public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, dynamic, scope); + return boolSetting(key, defaultValue, dynamic, scope, false); + } + + public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, Scope scope, boolean filtered) { + return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, dynamic, scope, filtered); } public static Setting boolSetting(String key, Setting fallbackSetting, boolean dynamic, Scope scope) { diff --git a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java index b06f53459c8..027e6e7cafe 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java +++ b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java @@ -71,6 +71,11 @@ public class SettingsModule extends AbstractModule { * the setting during startup. */ public void registerSetting(Setting setting) { + if (setting.isFiltered()) { + if (settingsFilterPattern.contains(setting.getKey()) == false) { + registerSettingsFilter(setting.getKey()); + } + } switch (setting.getScope()) { case CLUSTER: if (clusterSettings.containsKey(setting.getKey())) { @@ -101,12 +106,6 @@ public class SettingsModule extends AbstractModule { settingsFilterPattern.add(filter); } - public void registerSettingsFilterIfMissing(String filter) { - if (settingsFilterPattern.contains(filter) == false) { - registerSettingsFilter(filter); - } - } - /** * Check if a setting has already been registered */ diff --git a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java index ed03c918c31..dbf502d5805 100644 --- a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java @@ -50,6 +50,11 @@ public class SettingsFilteringIT extends ESIntegTestCase { } public static class SettingsFilteringPlugin extends Plugin { + public static final Setting SOME_NODE_SETTING = + Setting.boolSetting("some.node.setting", false, false, Setting.Scope.CLUSTER, true); + public static final Setting SOME_OTHER_NODE_SETTING = + Setting.boolSetting("some.other.node.setting", false, false, Setting.Scope.CLUSTER); + /** * The name of the plugin. */ @@ -72,10 +77,9 @@ public class SettingsFilteringIT extends ESIntegTestCase { } public void onModule(SettingsModule module) { + module.registerSetting(SOME_NODE_SETTING); + module.registerSetting(SOME_OTHER_NODE_SETTING); module.registerSetting(Setting.groupSetting("index.filter_test.", false, Setting.Scope.INDEX)); - module.registerSetting(Setting.boolSetting("some.node.setting", false, false, Setting.Scope.CLUSTER)); - module.registerSetting(Setting.boolSetting("some.other.node.setting", false, false, Setting.Scope.CLUSTER)); - module.registerSettingsFilter("some.node.setting"); module.registerSettingsFilter("index.filter_test.foo"); module.registerSettingsFilter("index.filter_test.bar*"); } @@ -104,8 +108,8 @@ public class SettingsFilteringIT extends ESIntegTestCase { for(NodeInfo info : nodeInfos.getNodes()) { Settings settings = info.getSettings(); assertNotNull(settings); - assertNull(settings.get("some.node.setting")); - assertTrue(settings.getAsBoolean("some.other.node.setting", false)); + assertNull(settings.get(SettingsFilteringPlugin.SOME_NODE_SETTING.getKey())); + assertTrue(settings.getAsBoolean(SettingsFilteringPlugin.SOME_OTHER_NODE_SETTING.getKey(), false)); assertEquals(settings.get("node.name"), info.getNode().getName()); } } diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java index 4f790c2d3a9..ce32be6c935 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java @@ -132,11 +132,10 @@ public class SettingsModuleTests extends ModuleTestCase { Settings settings = Settings.builder().put("foo.bar", "false").put("bar.foo", false).put("bar.baz", false).build(); SettingsModule module = new SettingsModule(settings); module.registerSetting(Setting.boolSetting("foo.bar", true, false, Setting.Scope.CLUSTER)); - module.registerSetting(Setting.boolSetting("bar.foo", true, false, Setting.Scope.CLUSTER)); + module.registerSetting(Setting.boolSetting("bar.foo", true, false, Setting.Scope.CLUSTER, true)); module.registerSetting(Setting.boolSetting("bar.baz", true, false, Setting.Scope.CLUSTER)); module.registerSettingsFilter("foo.*"); - module.registerSettingsFilterIfMissing("bar.foo"); try { module.registerSettingsFilter("bar.foo"); fail(); diff --git a/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index bd6c2533652..51ae133f39e 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/core/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -632,8 +632,8 @@ public class DedicatedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTest client().admin().cluster().preparePutRepository("test-repo") .setType("mock").setSettings(Settings.settingsBuilder() .put("location", randomRepoPath()) - .put("secret.mock.username", "notsecretusername") - .put("secret.mock.password", "verysecretpassword") + .put(MockRepository.Plugin.USERNAME_SETTING.getKey(), "notsecretusername") + .put(MockRepository.Plugin.PASSWORD_SETTING.getKey(), "verysecretpassword") ).get(); RestGetRepositoriesAction getRepoAction = internalCluster().getInstance(RestGetRepositoriesAction.class); diff --git a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java index e92a28db86b..1e383290753 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java +++ b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.io.PathUtils; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.settings.SettingsModule; @@ -63,6 +64,11 @@ public class MockRepository extends FsRepository { public static class Plugin extends org.elasticsearch.plugins.Plugin { + public static final Setting USERNAME_SETTING = + Setting.simpleString("secret.mock.username", false, Setting.Scope.CLUSTER); + public static final Setting PASSWORD_SETTING = + Setting.simpleString("secret.mock.password", false, Setting.Scope.CLUSTER, true); + @Override public String name() { return "mock-repository"; @@ -78,8 +84,8 @@ public class MockRepository extends FsRepository { } public void onModule(SettingsModule module) { - module.registerSettingsFilter("secret.mock.password"); - + module.registerSetting(USERNAME_SETTING); + module.registerSetting(PASSWORD_SETTING); } } diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java index 0c665c138b8..027caaccebc 100644 --- a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java +++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java @@ -22,26 +22,35 @@ package org.elasticsearch.cloud.azure.management; import com.microsoft.windowsazure.core.utils.KeyStoreType; import com.microsoft.windowsazure.management.compute.models.HostedServiceGetDetailedResponse; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.Scope; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.azure.AzureUnicastHostsProvider; public interface AzureComputeService { final class Management { - public static final Setting SUBSCRIPTION_ID_SETTING = Setting.simpleString("cloud.azure.management.subscription.id", false, Setting.Scope.CLUSTER); - public static final Setting SERVICE_NAME_SETTING = Setting.simpleString("cloud.azure.management.cloud.service.name", false, Setting.Scope.CLUSTER); + public static final Setting SUBSCRIPTION_ID_SETTING = + Setting.simpleString("cloud.azure.management.subscription.id", false, Scope.CLUSTER, true); + public static final Setting SERVICE_NAME_SETTING = + Setting.simpleString("cloud.azure.management.cloud.service.name", false, Scope.CLUSTER); // Keystore settings - public static final Setting KEYSTORE_PATH_SETTING = Setting.simpleString("cloud.azure.management.keystore.path", false, Setting.Scope.CLUSTER); - public static final Setting KEYSTORE_PASSWORD_SETTING = Setting.simpleString("cloud.azure.management.keystore.password", false, Setting.Scope.CLUSTER); - public static final Setting KEYSTORE_TYPE_SETTING = new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, false, Setting.Scope.CLUSTER); + public static final Setting KEYSTORE_PATH_SETTING = + Setting.simpleString("cloud.azure.management.keystore.path", false, Scope.CLUSTER, true); + public static final Setting KEYSTORE_PASSWORD_SETTING = + Setting.simpleString("cloud.azure.management.keystore.password", false, Scope.CLUSTER, true); + public static final Setting KEYSTORE_TYPE_SETTING = + new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, false, + Scope.CLUSTER, false); } final class Discovery { - public static final Setting REFRESH_SETTING = Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), false, Setting.Scope.CLUSTER); + public static final Setting REFRESH_SETTING = + Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), false, Scope.CLUSTER); - public static final Setting HOST_TYPE_SETTING = new Setting<>("discovery.azure.host.type", - AzureUnicastHostsProvider.HostType.PRIVATE_IP.name(), AzureUnicastHostsProvider.HostType::fromString, false, Setting.Scope.CLUSTER); + public static final Setting HOST_TYPE_SETTING = + new Setting<>("discovery.azure.host.type", AzureUnicastHostsProvider.HostType.PRIVATE_IP.name(), + AzureUnicastHostsProvider.HostType::fromString, false, Scope.CLUSTER); public static final String ENDPOINT_NAME = "discovery.azure.endpoint.name"; public static final String DEPLOYMENT_NAME = "discovery.azure.deployment.name"; diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/plugin/discovery/azure/AzureDiscoveryPlugin.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/plugin/discovery/azure/AzureDiscoveryPlugin.java index a8282dc9561..a0b29fad024 100644 --- a/plugins/discovery-azure/src/main/java/org/elasticsearch/plugin/discovery/azure/AzureDiscoveryPlugin.java +++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/plugin/discovery/azure/AzureDiscoveryPlugin.java @@ -74,10 +74,5 @@ public class AzureDiscoveryPlugin extends Plugin { settingsModule.registerSetting(AzureComputeService.Management.SUBSCRIPTION_ID_SETTING); settingsModule.registerSetting(AzureComputeService.Management.SERVICE_NAME_SETTING); settingsModule.registerSetting(AzureComputeService.Discovery.HOST_TYPE_SETTING); - // Cloud management API settings we need to hide - settingsModule.registerSettingsFilter(AzureComputeService.Management.KEYSTORE_PATH_SETTING.getKey()); - settingsModule.registerSettingsFilter(AzureComputeService.Management.KEYSTORE_PASSWORD_SETTING.getKey()); - settingsModule.registerSettingsFilter(AzureComputeService.Management.KEYSTORE_TYPE_SETTING.getKey()); - settingsModule.registerSettingsFilter(AzureComputeService.Management.SUBSCRIPTION_ID_SETTING.getKey()); } } diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java index a90d3573468..ce34dd61f40 100644 --- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java +++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java @@ -40,11 +40,11 @@ public interface AwsEc2Service { /** * cloud.aws.access_key: AWS Access key. Shared with repository-s3 plugin */ - Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER); + Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.secret_key: AWS Secret key. Shared with repository-s3 plugin */ - Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER); + Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with repository-s3 plugin */ @@ -65,7 +65,7 @@ public interface AwsEc2Service { /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with repository-s3 plugin */ - Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER); + Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with repository-s3 plugin */ @@ -84,13 +84,13 @@ public interface AwsEc2Service { * @see AwsEc2Service#KEY_SETTING */ Setting KEY_SETTING = new Setting<>("cloud.aws.ec2.access_key", AwsEc2Service.KEY_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER); + Setting.Scope.CLUSTER, true); /** * cloud.aws.ec2.secret_key: AWS Secret key specific for EC2 API calls. Defaults to cloud.aws.secret_key. * @see AwsEc2Service#SECRET_SETTING */ Setting SECRET_SETTING = new Setting<>("cloud.aws.ec2.secret_key", AwsEc2Service.SECRET_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER); + Setting.Scope.CLUSTER, true); /** * cloud.aws.ec2.protocol: Protocol for AWS API specific for EC2 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsEc2Service#PROTOCOL_SETTING @@ -122,7 +122,7 @@ public interface AwsEc2Service { * @see AwsEc2Service#PROXY_PASSWORD_SETTING */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.ec2.proxy.password", AwsEc2Service.PROXY_PASSWORD_SETTING, - Function.identity(), false, Setting.Scope.CLUSTER); + Function.identity(), false, Setting.Scope.CLUSTER, true); /** * cloud.aws.ec2.signer: If you are using an old AWS API version, you can define a Signer. Specific for EC2 API calls. * Defaults to cloud.aws.signer. diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/plugin/discovery/ec2/Ec2DiscoveryPlugin.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/plugin/discovery/ec2/Ec2DiscoveryPlugin.java index baad869a0aa..211597ee454 100644 --- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/plugin/discovery/ec2/Ec2DiscoveryPlugin.java +++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/plugin/discovery/ec2/Ec2DiscoveryPlugin.java @@ -134,14 +134,6 @@ public class Ec2DiscoveryPlugin extends Plugin { settingsModule.registerSetting(AwsEc2Service.DISCOVERY_EC2.GROUPS_SETTING); settingsModule.registerSetting(AwsEc2Service.DISCOVERY_EC2.AVAILABILITY_ZONES_SETTING); settingsModule.registerSetting(AwsEc2Service.DISCOVERY_EC2.NODE_CACHE_TIME_SETTING); - - // Filter global settings - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.KEY_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.SECRET_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.PROXY_PASSWORD_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.CLOUD_EC2.KEY_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.CLOUD_EC2.SECRET_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsEc2Service.CLOUD_EC2.PROXY_PASSWORD_SETTING.getKey()); } /** diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java index 657c292db31..2c5521887d8 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java @@ -41,13 +41,20 @@ public interface AzureStorageService { final class Storage { public static final String PREFIX = "cloud.azure.storage."; - public static final Setting TIMEOUT_SETTING = Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), false, Setting.Scope.CLUSTER); - public static final Setting ACCOUNT_SETTING = Setting.simpleString("repositories.azure.account", false, Setting.Scope.CLUSTER); - public static final Setting CONTAINER_SETTING = Setting.simpleString("repositories.azure.container", false, Setting.Scope.CLUSTER); - public static final Setting BASE_PATH_SETTING = Setting.simpleString("repositories.azure.base_path", false, Setting.Scope.CLUSTER); - public static final Setting LOCATION_MODE_SETTING = Setting.simpleString("repositories.azure.location_mode", false, Setting.Scope.CLUSTER); - public static final Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("repositories.azure.compress", false, false, Setting.Scope.CLUSTER); + public static final Setting TIMEOUT_SETTING = + Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), false, Setting.Scope.CLUSTER); + public static final Setting ACCOUNT_SETTING = + Setting.simpleString("repositories.azure.account", false, Setting.Scope.CLUSTER, true); + public static final Setting CONTAINER_SETTING = + Setting.simpleString("repositories.azure.container", false, Setting.Scope.CLUSTER); + public static final Setting BASE_PATH_SETTING = + Setting.simpleString("repositories.azure.base_path", false, Setting.Scope.CLUSTER); + public static final Setting LOCATION_MODE_SETTING = + Setting.simpleString("repositories.azure.location_mode", false, Setting.Scope.CLUSTER); + public static final Setting CHUNK_SIZE_SETTING = + Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); + public static final Setting COMPRESS_SETTING = + Setting.boolSetting("repositories.azure.compress", false, false, Setting.Scope.CLUSTER); } boolean doesContainerExist(String account, LocationMode mode, String container); @@ -62,13 +69,17 @@ public interface AzureStorageService { void deleteBlob(String account, LocationMode mode, String container, String blob) throws URISyntaxException, StorageException; - InputStream getInputStream(String account, LocationMode mode, String container, String blob) throws URISyntaxException, StorageException; + InputStream getInputStream(String account, LocationMode mode, String container, String blob) + throws URISyntaxException, StorageException; - OutputStream getOutputStream(String account, LocationMode mode, String container, String blob) throws URISyntaxException, StorageException; + OutputStream getOutputStream(String account, LocationMode mode, String container, String blob) + throws URISyntaxException, StorageException; - Map listBlobsByPrefix(String account, LocationMode mode, String container, String keyPath, String prefix) throws URISyntaxException, StorageException; + Map listBlobsByPrefix(String account, LocationMode mode, String container, String keyPath, String prefix) + throws URISyntaxException, StorageException; - void moveBlob(String account, LocationMode mode, String container, String sourceBlob, String targetBlob) throws URISyntaxException, StorageException; + void moveBlob(String account, LocationMode mode, String container, String sourceBlob, String targetBlob) + throws URISyntaxException, StorageException; AzureStorageService start(); } diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/plugin/repository/azure/AzureRepositoryPlugin.java b/plugins/repository-azure/src/main/java/org/elasticsearch/plugin/repository/azure/AzureRepositoryPlugin.java index 616b150f954..3ce043500ae 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/plugin/repository/azure/AzureRepositoryPlugin.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/plugin/repository/azure/AzureRepositoryPlugin.java @@ -74,9 +74,9 @@ public class AzureRepositoryPlugin extends Plugin { module.registerSetting(AzureStorageService.Storage.BASE_PATH_SETTING); module.registerSetting(AzureStorageService.Storage.CHUNK_SIZE_SETTING); module.registerSetting(AzureStorageService.Storage.LOCATION_MODE_SETTING); - // Cloud storage API settings needed to be hidden + + // Cloud storage API settings using a pattern needed to be hidden module.registerSettingsFilter(AzureStorageService.Storage.PREFIX + "*.account"); module.registerSettingsFilter(AzureStorageService.Storage.PREFIX + "*.key"); - module.registerSettingsFilter(AzureStorageService.Storage.ACCOUNT_SETTING.getKey()); } } diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java index 3ccd6d7987f..3af9446fbe9 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java @@ -38,11 +38,11 @@ public interface AwsS3Service extends LifecycleComponent { /** * cloud.aws.access_key: AWS Access key. Shared with discovery-ec2 plugin */ - Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER); + Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.secret_key: AWS Secret key. Shared with discovery-ec2 plugin */ - Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER); + Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with discovery-ec2 plugin */ @@ -63,7 +63,7 @@ public interface AwsS3Service extends LifecycleComponent { /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with discovery-ec2 plugin */ - Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER); + Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER, true); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with discovery-ec2 plugin */ @@ -82,13 +82,13 @@ public interface AwsS3Service extends LifecycleComponent { * @see AwsS3Service#KEY_SETTING */ Setting KEY_SETTING = - new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), false, Setting.Scope.CLUSTER, true); /** * cloud.aws.s3.secret_key: AWS Secret key specific for S3 API calls. Defaults to cloud.aws.secret_key. * @see AwsS3Service#SECRET_SETTING */ Setting SECRET_SETTING = - new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), false, Setting.Scope.CLUSTER, true); /** * cloud.aws.s3.protocol: Protocol for AWS API specific for S3 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsS3Service#PROTOCOL_SETTING @@ -124,7 +124,7 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.s3.proxy.password", AwsS3Service.PROXY_PASSWORD_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER); + Setting.Scope.CLUSTER, true); /** * cloud.aws.s3.signer: If you are using an old AWS API version, you can define a Signer. Specific for S3 API calls. * Defaults to cloud.aws.signer. diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/plugin/repository/s3/S3RepositoryPlugin.java b/plugins/repository-s3/src/main/java/org/elasticsearch/plugin/repository/s3/S3RepositoryPlugin.java index 5d21bb4e2ac..d07d8c174c5 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/plugin/repository/s3/S3RepositoryPlugin.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/plugin/repository/s3/S3RepositoryPlugin.java @@ -144,16 +144,6 @@ public class S3RepositoryPlugin extends Plugin { settingsModule.registerSetting(S3Repository.Repository.STORAGE_CLASS_SETTING); settingsModule.registerSetting(S3Repository.Repository.CANNED_ACL_SETTING); settingsModule.registerSetting(S3Repository.Repository.BASE_PATH_SETTING); - - // Filter global settings - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.KEY_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.SECRET_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.PROXY_PASSWORD_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.CLOUD_S3.KEY_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.CLOUD_S3.SECRET_SETTING.getKey()); - settingsModule.registerSettingsFilterIfMissing(AwsS3Service.CLOUD_S3.PROXY_PASSWORD_SETTING.getKey()); - settingsModule.registerSettingsFilter(S3Repository.Repository.KEY_SETTING.getKey()); - settingsModule.registerSettingsFilter(S3Repository.Repository.SECRET_SETTING.getKey()); } /** diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index 3edead0765e..6b3b5bf943a 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -140,12 +140,12 @@ public class S3Repository extends BlobStoreRepository { * access_key * @see Repositories#KEY_SETTING */ - Setting KEY_SETTING = Setting.simpleString("access_key", false, Setting.Scope.CLUSTER); + Setting KEY_SETTING = Setting.simpleString("access_key", false, Setting.Scope.CLUSTER, true); /** * secret_key * @see Repositories#SECRET_SETTING */ - Setting SECRET_SETTING = Setting.simpleString("secret_key", false, Setting.Scope.CLUSTER); + Setting SECRET_SETTING = Setting.simpleString("secret_key", false, Setting.Scope.CLUSTER, true); /** * bucket * @see Repositories#BUCKET_SETTING From 08905be2cacca70bc4d4ae85408c0b07b45c4e56 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Wed, 24 Feb 2016 14:05:09 -0800 Subject: [PATCH 02/49] Revert javadoc change: iff is correct --- .../main/java/org/elasticsearch/common/settings/Setting.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index e1349cc2a00..1e0e2190fcc 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -78,7 +78,7 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true if this setting can be dynamically updateable + * @param dynamic true iff this setting can be dynamically updateable * @param scope the scope of this setting */ public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope) { @@ -90,7 +90,7 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true if this setting can be dynamically updateable + * @param dynamic true iff this setting can be dynamically updateable * @param scope the scope of this setting * @param filtered true if this setting should be filtered */ From 31b5e0888f4414b6ba863778436e177b6e82eea5 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Sun, 28 Feb 2016 00:40:00 +0100 Subject: [PATCH 03/49] Use an SettingsProperty enumSet Instead of modifying methods each time we need to add a new behavior for settings, we can simply pass `SettingsProperty... properties` instead. `SettingsProperty` could be defined then: ``` public enum SettingsProperty { Filtered, Dynamic, ClusterScope, NodeScope, IndexScope // HereGoesYours; } ``` Then in setting code, it become much more flexible. TODO: Note that we need to validate SettingsProperty which are added to a Setting as some of them might be mutually exclusive. --- .../close/TransportCloseIndexAction.java | 4 +- .../action/support/AutoCreateIndex.java | 4 +- .../action/support/DestructiveOperations.java | 4 +- .../master/TransportMasterNodeReadAction.java | 4 +- .../bootstrap/BootstrapSettings.java | 13 +- .../cache/recycler/PageCacheRecycler.java | 19 +- .../java/org/elasticsearch/client/Client.java | 3 +- .../TransportClientNodesService.java | 13 +- .../elasticsearch/cluster/ClusterModule.java | 4 +- .../elasticsearch/cluster/ClusterName.java | 3 +- .../cluster/InternalClusterInfoService.java | 8 +- .../action/index/MappingUpdatedAction.java | 4 +- .../cluster/metadata/AutoExpandReplicas.java | 3 +- .../cluster/metadata/IndexMetaData.java | 43 ++-- .../cluster/metadata/MetaData.java | 4 +- .../cluster/routing/UnassignedInfo.java | 5 +- .../allocator/BalancedShardsAllocator.java | 10 +- .../decider/AwarenessAllocationDecider.java | 8 +- .../ClusterRebalanceAllocationDecider.java | 5 +- .../ConcurrentRebalanceAllocationDecider.java | 4 +- .../decider/DiskThresholdDecider.java | 17 +- .../decider/EnableAllocationDecider.java | 13 +- .../decider/FilterAllocationDecider.java | 10 +- .../decider/ShardsLimitAllocationDecider.java | 7 +- .../SnapshotInProgressAllocationDecider.java | 4 +- .../decider/ThrottlingAllocationDecider.java | 22 +- .../service/InternalClusterService.java | 9 +- .../common/logging/ESLoggerFactory.java | 7 +- .../common/network/NetworkModule.java | 12 +- .../common/network/NetworkService.java | 42 ++-- .../settings/AbstractScopedSettings.java | 16 +- .../common/settings/ClusterSettings.java | 3 +- .../common/settings/IndexScopedSettings.java | 9 +- .../common/settings/Setting.java | 233 +++++++++--------- .../common/settings/SettingsModule.java | 34 ++- .../common/util/concurrent/EsExecutors.java | 4 +- .../common/util/concurrent/ThreadContext.java | 4 +- .../discovery/DiscoveryModule.java | 10 +- .../discovery/DiscoveryService.java | 8 +- .../discovery/DiscoverySettings.java | 15 +- .../discovery/zen/ZenDiscovery.java | 34 ++- .../zen/elect/ElectMasterService.java | 4 +- .../discovery/zen/fd/FaultDetection.java | 17 +- .../zen/ping/unicast/UnicastZenPing.java | 8 +- .../org/elasticsearch/env/Environment.java | 22 +- .../elasticsearch/env/NodeEnvironment.java | 8 +- .../elasticsearch/gateway/GatewayService.java | 29 +-- .../gateway/PrimaryShardAllocator.java | 9 +- .../http/HttpTransportSettings.java | 65 +++-- .../http/netty/NettyHttpServerTransport.java | 56 ++--- .../org/elasticsearch/index/IndexModule.java | 10 +- .../elasticsearch/index/IndexSettings.java | 48 ++-- .../org/elasticsearch/index/IndexWarmer.java | 3 +- .../elasticsearch/index/IndexingSlowLog.java | 26 +- .../index/MergePolicyConfig.java | 29 ++- .../index/MergeSchedulerConfig.java | 15 +- .../elasticsearch/index/SearchSlowLog.java | 40 ++- .../index/analysis/NamedAnalyzer.java | 2 +- .../index/analysis/NumericDoubleAnalyzer.java | 2 +- .../index/analysis/NumericFloatAnalyzer.java | 2 +- .../index/analysis/NumericLongAnalyzer.java | 2 +- .../index/cache/bitset/BitsetFilterCache.java | 4 +- .../index/engine/EngineConfig.java | 3 +- .../fielddata/IndexFieldDataService.java | 3 +- .../index/mapper/FieldMapper.java | 7 +- .../index/mapper/MapperService.java | 7 +- .../index/mapper/core/NumberFieldMapper.java | 5 +- .../percolator/PercolatorQueriesRegistry.java | 4 +- .../index/store/FsDirectoryService.java | 3 +- .../elasticsearch/index/store/IndexStore.java | 7 +- .../index/store/IndexStoreConfig.java | 8 +- .../org/elasticsearch/index/store/Store.java | 4 +- .../indices/IndicesQueryCache.java | 7 +- .../indices/IndicesRequestCache.java | 13 +- .../elasticsearch/indices/IndicesService.java | 4 +- .../indices/analysis/HunspellService.java | 10 +- .../HierarchyCircuitBreakerService.java | 22 +- .../cache/IndicesFieldDataCache.java | 4 +- .../indices/recovery/RecoverySettings.java | 27 +- .../indices/store/IndicesStore.java | 5 +- .../indices/ttl/IndicesTTLService.java | 4 +- .../elasticsearch/monitor/fs/FsService.java | 4 +- .../monitor/jvm/JvmGcMonitorService.java | 10 +- .../elasticsearch/monitor/jvm/JvmService.java | 4 +- .../elasticsearch/monitor/os/OsService.java | 4 +- .../monitor/process/ProcessService.java | 4 +- .../java/org/elasticsearch/node/Node.java | 25 +- .../internal/InternalSettingsPreparer.java | 4 +- .../elasticsearch/plugins/PluginsService.java | 4 +- .../repositories/fs/FsRepository.java | 18 +- .../repositories/uri/URLRepository.java | 26 +- .../elasticsearch/rest/BaseRestHandler.java | 4 +- .../elasticsearch/script/ScriptService.java | 10 +- .../elasticsearch/script/ScriptSettings.java | 9 +- .../elasticsearch/search/SearchService.java | 10 +- .../elasticsearch/threadpool/ThreadPool.java | 4 +- .../elasticsearch/transport/Transport.java | 3 +- .../transport/TransportService.java | 11 +- .../transport/TransportSettings.java | 20 +- .../transport/netty/NettyTransport.java | 81 +++--- .../org/elasticsearch/tribe/TribeService.java | 28 ++- .../cluster/ClusterModuleTests.java | 5 +- .../cluster/settings/SettingsFilteringIT.java | 12 +- .../common/settings/ScopedSettingsTests.java | 26 +- .../common/settings/SettingTests.java | 58 +++-- .../common/settings/SettingsModuleTests.java | 11 +- .../elasticsearch/index/IndexModuleTests.java | 5 +- .../index/IndexSettingsTests.java | 9 +- .../index/SettingsListenerIT.java | 5 +- .../indices/IndicesOptionsIntegrationIT.java | 10 +- .../RandomExceptionCircuitBreakerIT.java | 7 +- .../basic/SearchWithRandomExceptionsIT.java | 7 +- .../snapshots/mockstore/MockRepository.java | 10 +- .../azure/management/AzureComputeService.java | 18 +- .../cloud/aws/AwsEc2Service.java | 58 +++-- .../mapper/attachments/AttachmentMapper.java | 10 +- .../azure/storage/AzureStorageService.java | 16 +- .../repositories/azure/AzureRepository.java | 18 +- .../elasticsearch/cloud/aws/AwsS3Service.java | 46 ++-- .../repositories/s3/S3Repository.java | 70 +++--- .../elasticsearch/test/ESIntegTestCase.java | 4 +- .../test/InternalSettingsPlugin.java | 10 +- .../test/MockIndexEventListener.java | 3 +- .../test/engine/MockEngineSupport.java | 7 +- .../test/store/MockFSDirectoryService.java | 18 +- .../test/store/MockFSIndexStore.java | 4 +- .../test/tasks/MockTaskManager.java | 4 +- .../transport/AssertingLocalTransport.java | 11 +- 128 files changed, 1228 insertions(+), 743 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java index f8bbebf7db8..82602a10c00 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java @@ -33,6 +33,7 @@ import org.elasticsearch.cluster.metadata.MetaDataIndexStateService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; @@ -46,7 +47,8 @@ public class TransportCloseIndexAction extends TransportMasterNodeAction CLUSTER_INDICES_CLOSE_ENABLE_SETTING = Setting.boolSetting("cluster.indices.close.enable", true, true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_INDICES_CLOSE_ENABLE_SETTING = + Setting.boolSetting("cluster.indices.close.enable", true, true, SettingsProperty.ClusterScope); @Inject public TransportCloseIndexAction(Settings settings, TransportService transportService, ClusterService clusterService, diff --git a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java index d5574755346..ee304dd05f2 100644 --- a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java +++ b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java @@ -27,6 +27,7 @@ import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.mapper.MapperService; @@ -39,7 +40,8 @@ import java.util.List; */ public final class AutoCreateIndex { - public static final Setting AUTO_CREATE_INDEX_SETTING = new Setting<>("action.auto_create_index", "true", AutoCreate::new, false, Setting.Scope.CLUSTER); + public static final Setting AUTO_CREATE_INDEX_SETTING = + new Setting<>("action.auto_create_index", "true", AutoCreate::new, false, SettingsProperty.ClusterScope); private final boolean dynamicMappingDisabled; private final IndexNameExpressionResolver resolver; diff --git a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java index 5f2fb33e043..cfdd45cdfa1 100644 --- a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java +++ b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -33,7 +34,8 @@ public final class DestructiveOperations extends AbstractComponent { /** * Setting which controls whether wildcard usage (*, prefix*, _all) is allowed. */ - public static final Setting REQUIRES_NAME_SETTING = Setting.boolSetting("action.destructive_requires_name", false, true, Setting.Scope.CLUSTER); + public static final Setting REQUIRES_NAME_SETTING = + Setting.boolSetting("action.destructive_requires_name", false, true, SettingsProperty.ClusterScope); private volatile boolean destructiveRequiresName; @Inject diff --git a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java index ed08e5bdba3..5c15acbbdca 100644 --- a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java +++ b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java @@ -24,6 +24,7 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; @@ -37,7 +38,8 @@ import java.util.function.Supplier; public abstract class TransportMasterNodeReadAction, Response extends ActionResponse> extends TransportMasterNodeAction { - public static final Setting FORCE_LOCAL_SETTING = Setting.boolSetting("action.master.force_local", false, false, Setting.Scope.CLUSTER); + public static final Setting FORCE_LOCAL_SETTING = + Setting.boolSetting("action.master.force_local", false, false, SettingsProperty.ClusterScope); private final boolean forceLocal; diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java index a20ff9bb059..9c0bdcbd2c9 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java @@ -20,7 +20,7 @@ package org.elasticsearch.bootstrap; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; public final class BootstrapSettings { @@ -29,10 +29,13 @@ public final class BootstrapSettings { // TODO: remove this hack when insecure defaults are removed from java public static final Setting SECURITY_FILTER_BAD_DEFAULTS_SETTING = - Setting.boolSetting("security.manager.filter_bad_defaults", true, false, Scope.CLUSTER); + Setting.boolSetting("security.manager.filter_bad_defaults", true, false, SettingsProperty.ClusterScope); - public static final Setting MLOCKALL_SETTING = Setting.boolSetting("bootstrap.mlockall", false, false, Scope.CLUSTER); - public static final Setting SECCOMP_SETTING = Setting.boolSetting("bootstrap.seccomp", true, false, Scope.CLUSTER); - public static final Setting CTRLHANDLER_SETTING = Setting.boolSetting("bootstrap.ctrlhandler", true, false, Scope.CLUSTER); + public static final Setting MLOCKALL_SETTING = + Setting.boolSetting("bootstrap.mlockall", false, false, SettingsProperty.ClusterScope); + public static final Setting SECCOMP_SETTING = + Setting.boolSetting("bootstrap.seccomp", true, false, SettingsProperty.ClusterScope); + public static final Setting CTRLHANDLER_SETTING = + Setting.boolSetting("bootstrap.ctrlhandler", true, false, SettingsProperty.ClusterScope); } diff --git a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java index a293428192b..9cec74115f6 100644 --- a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java +++ b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java @@ -26,6 +26,7 @@ import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.recycler.AbstractRecyclerC; import org.elasticsearch.common.recycler.Recycler; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; @@ -43,13 +44,19 @@ import static org.elasticsearch.common.recycler.Recyclers.none; /** A recycler of fixed-size pages. */ public class PageCacheRecycler extends AbstractComponent implements Releasable { - public static final Setting TYPE_SETTING = new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, false, Setting.Scope.CLUSTER); - public static final Setting LIMIT_HEAP_SETTING = Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", false, Setting.Scope.CLUSTER); - public static final Setting WEIGHT_BYTES_SETTING = Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, false, Setting.Scope.CLUSTER); - public static final Setting WEIGHT_LONG_SETTING = Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, false, Setting.Scope.CLUSTER); - public static final Setting WEIGHT_INT_SETTING = Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, false, Setting.Scope.CLUSTER); + public static final Setting TYPE_SETTING = + new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, false, SettingsProperty.ClusterScope); + public static final Setting LIMIT_HEAP_SETTING = + Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", false, SettingsProperty.ClusterScope); + public static final Setting WEIGHT_BYTES_SETTING = + Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, false, SettingsProperty.ClusterScope); + public static final Setting WEIGHT_LONG_SETTING = + Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, false, SettingsProperty.ClusterScope); + public static final Setting WEIGHT_INT_SETTING = + Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, false, SettingsProperty.ClusterScope); // object pages are less useful to us so we give them a lower weight by default - public static final Setting WEIGHT_OBJECTS_SETTING = Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, false, Setting.Scope.CLUSTER); + public static final Setting WEIGHT_OBJECTS_SETTING = + Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, false, SettingsProperty.ClusterScope); private final Recycler bytePage; private final Recycler intPage; diff --git a/core/src/main/java/org/elasticsearch/client/Client.java b/core/src/main/java/org/elasticsearch/client/Client.java index f81ba9eb1b1..859a15e2c5b 100644 --- a/core/src/main/java/org/elasticsearch/client/Client.java +++ b/core/src/main/java/org/elasticsearch/client/Client.java @@ -87,6 +87,7 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.Map; @@ -114,7 +115,7 @@ public interface Client extends ElasticsearchClient, Releasable { default: throw new IllegalArgumentException("Can't parse [client.type] must be one of [node, transport]"); } - }, false, Setting.Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); /** * The admin client that can be used to perform administrative operations. diff --git a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java index 1e605b9de06..2e495633329 100644 --- a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java +++ b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java @@ -34,6 +34,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -100,10 +101,14 @@ public class TransportClientNodesService extends AbstractComponent { private volatile boolean closed; - public static final Setting CLIENT_TRANSPORT_NODES_SAMPLER_INTERVAL = Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), false, Setting.Scope.CLUSTER); - public static final Setting CLIENT_TRANSPORT_PING_TIMEOUT = Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), false, Setting.Scope.CLUSTER); - public static final Setting CLIENT_TRANSPORT_IGNORE_CLUSTER_NAME = Setting.boolSetting("client.transport.ignore_cluster_name", false, false, Setting.Scope.CLUSTER); - public static final Setting CLIENT_TRANSPORT_SNIFF = Setting.boolSetting("client.transport.sniff", false, false, Setting.Scope.CLUSTER); + public static final Setting CLIENT_TRANSPORT_NODES_SAMPLER_INTERVAL = + Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), false, SettingsProperty.ClusterScope); + public static final Setting CLIENT_TRANSPORT_PING_TIMEOUT = + Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), false, SettingsProperty.ClusterScope); + public static final Setting CLIENT_TRANSPORT_IGNORE_CLUSTER_NAME = + Setting.boolSetting("client.transport.ignore_cluster_name", false, false, SettingsProperty.ClusterScope); + public static final Setting CLIENT_TRANSPORT_SNIFF = + Setting.boolSetting("client.transport.sniff", false, false, SettingsProperty.ClusterScope); @Inject public TransportClientNodesService(Settings settings, ClusterName clusterName, TransportService transportService, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java index 3e668191ff3..ec27ed3a4d4 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java @@ -58,6 +58,7 @@ import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.gateway.GatewayAllocator; @@ -74,7 +75,8 @@ public class ClusterModule extends AbstractModule { public static final String EVEN_SHARD_COUNT_ALLOCATOR = "even_shard"; public static final String BALANCED_ALLOCATOR = "balanced"; // default - public static final Setting SHARDS_ALLOCATOR_TYPE_SETTING = new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), false, Setting.Scope.CLUSTER); + public static final Setting SHARDS_ALLOCATOR_TYPE_SETTING = + new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), false, SettingsProperty.ClusterScope); public static final List> DEFAULT_ALLOCATION_DECIDERS = Collections.unmodifiableList(Arrays.asList( SameShardAllocationDecider.class, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java index daf3000d710..9012b9b0278 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.io.IOException; @@ -37,7 +38,7 @@ public class ClusterName implements Streamable { throw new IllegalArgumentException("[cluster.name] must not be empty"); } return s; - }, false, Setting.Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); public static final ClusterName DEFAULT = new ClusterName(CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY).intern()); diff --git a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java index 5107b4495ab..e6d9c27c1c2 100644 --- a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java +++ b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java @@ -39,6 +39,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; @@ -64,8 +65,11 @@ import java.util.concurrent.TimeUnit; */ public class InternalClusterInfoService extends AbstractComponent implements ClusterInfoService, LocalNodeMasterListener, ClusterStateListener { - public static final Setting INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING = Setting.timeSetting("cluster.info.update.interval", TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); - public static final Setting INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING = Setting.positiveTimeSetting("cluster.info.update.timeout", TimeValue.timeValueSeconds(15), true, Setting.Scope.CLUSTER); + public static final Setting INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING = + Setting.timeSetting("cluster.info.update.interval", TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(10), true, + SettingsProperty.ClusterScope); + public static final Setting INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING = + Setting.positiveTimeSetting("cluster.info.update.timeout", TimeValue.timeValueSeconds(15), true, SettingsProperty.ClusterScope); private volatile TimeValue updateFrequency; diff --git a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java index 0e61712b010..647f5df1cd4 100644 --- a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java +++ b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.mapper.MapperService; @@ -41,7 +42,8 @@ import java.util.concurrent.TimeoutException; */ public class MappingUpdatedAction extends AbstractComponent { - public static final Setting INDICES_MAPPING_DYNAMIC_TIMEOUT_SETTING = Setting.positiveTimeSetting("indices.mapping.dynamic_timeout", TimeValue.timeValueSeconds(30), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_MAPPING_DYNAMIC_TIMEOUT_SETTING = + Setting.positiveTimeSetting("indices.mapping.dynamic_timeout", TimeValue.timeValueSeconds(30), true, SettingsProperty.ClusterScope); private IndicesAdminClient client; private volatile TimeValue dynamicMappingUpdateTimeout; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java index d9b288bb897..dac44814a92 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java @@ -20,6 +20,7 @@ package org.elasticsearch.cluster.metadata; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; /** * This class acts as a functional wrapper around the index.auto_expand_replicas setting. @@ -56,7 +57,7 @@ final class AutoExpandReplicas { } } return new AutoExpandReplicas(min, max, true); - }, true, Setting.Scope.INDEX); + }, true, SettingsProperty.IndexScope); private final int minReplicas; private final int maxReplicas; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index f8822ceb281..f9982384d6e 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -38,6 +38,7 @@ import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.common.xcontent.FromXContentBuilder; @@ -152,28 +153,36 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String INDEX_SETTING_PREFIX = "index."; public static final String SETTING_NUMBER_OF_SHARDS = "index.number_of_shards"; - public static final Setting INDEX_NUMBER_OF_SHARDS_SETTING = Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, false, Setting.Scope.INDEX); + public static final Setting INDEX_NUMBER_OF_SHARDS_SETTING = + Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, false, SettingsProperty.IndexScope); public static final String SETTING_NUMBER_OF_REPLICAS = "index.number_of_replicas"; - public static final Setting INDEX_NUMBER_OF_REPLICAS_SETTING = Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, true, Setting.Scope.INDEX); + public static final Setting INDEX_NUMBER_OF_REPLICAS_SETTING = + Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, true, SettingsProperty.IndexScope); public static final String SETTING_SHADOW_REPLICAS = "index.shadow_replicas"; - public static final Setting INDEX_SHADOW_REPLICAS_SETTING = Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, false, Setting.Scope.INDEX); + public static final Setting INDEX_SHADOW_REPLICAS_SETTING = + Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, false, SettingsProperty.IndexScope); public static final String SETTING_SHARED_FILESYSTEM = "index.shared_filesystem"; - public static final Setting INDEX_SHARED_FILESYSTEM_SETTING = Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, false, Setting.Scope.INDEX); + public static final Setting INDEX_SHARED_FILESYSTEM_SETTING = + Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, false, SettingsProperty.IndexScope); public static final String SETTING_AUTO_EXPAND_REPLICAS = "index.auto_expand_replicas"; public static final Setting INDEX_AUTO_EXPAND_REPLICAS_SETTING = AutoExpandReplicas.SETTING; public static final String SETTING_READ_ONLY = "index.blocks.read_only"; - public static final Setting INDEX_READ_ONLY_SETTING = Setting.boolSetting(SETTING_READ_ONLY, false, true, Setting.Scope.INDEX); + public static final Setting INDEX_READ_ONLY_SETTING = + Setting.boolSetting(SETTING_READ_ONLY, false, true, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_READ = "index.blocks.read"; - public static final Setting INDEX_BLOCKS_READ_SETTING = Setting.boolSetting(SETTING_BLOCKS_READ, false, true, Setting.Scope.INDEX); + public static final Setting INDEX_BLOCKS_READ_SETTING = + Setting.boolSetting(SETTING_BLOCKS_READ, false, true, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_WRITE = "index.blocks.write"; - public static final Setting INDEX_BLOCKS_WRITE_SETTING = Setting.boolSetting(SETTING_BLOCKS_WRITE, false, true, Setting.Scope.INDEX); + public static final Setting INDEX_BLOCKS_WRITE_SETTING = + Setting.boolSetting(SETTING_BLOCKS_WRITE, false, true, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_METADATA = "index.blocks.metadata"; - public static final Setting INDEX_BLOCKS_METADATA_SETTING = Setting.boolSetting(SETTING_BLOCKS_METADATA, false, true, Setting.Scope.INDEX); + public static final Setting INDEX_BLOCKS_METADATA_SETTING = + Setting.boolSetting(SETTING_BLOCKS_METADATA, false, true, SettingsProperty.IndexScope); public static final String SETTING_VERSION_CREATED = "index.version.created"; public static final String SETTING_VERSION_CREATED_STRING = "index.version.created_string"; @@ -182,18 +191,24 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String SETTING_VERSION_MINIMUM_COMPATIBLE = "index.version.minimum_compatible"; public static final String SETTING_CREATION_DATE = "index.creation_date"; public static final String SETTING_PRIORITY = "index.priority"; - public static final Setting INDEX_PRIORITY_SETTING = Setting.intSetting("index.priority", 1, 0, true, Setting.Scope.INDEX); + public static final Setting INDEX_PRIORITY_SETTING = + Setting.intSetting("index.priority", 1, 0, true, SettingsProperty.IndexScope); public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string"; public static final String SETTING_INDEX_UUID = "index.uuid"; public static final String SETTING_DATA_PATH = "index.data_path"; - public static final Setting INDEX_DATA_PATH_SETTING = new Setting<>(SETTING_DATA_PATH, "", Function.identity(), false, Setting.Scope.INDEX); + public static final Setting INDEX_DATA_PATH_SETTING = + new Setting<>(SETTING_DATA_PATH, "", Function.identity(), false, SettingsProperty.IndexScope); public static final String SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE = "index.shared_filesystem.recover_on_any_node"; - public static final Setting INDEX_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE_SETTING = Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, true, Setting.Scope.INDEX); + public static final Setting INDEX_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE_SETTING = + Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, true, SettingsProperty.IndexScope); public static final String INDEX_UUID_NA_VALUE = "_na_"; - public static final Setting INDEX_ROUTING_REQUIRE_GROUP_SETTING = Setting.groupSetting("index.routing.allocation.require.", true, Setting.Scope.INDEX); - public static final Setting INDEX_ROUTING_INCLUDE_GROUP_SETTING = Setting.groupSetting("index.routing.allocation.include.", true, Setting.Scope.INDEX); - public static final Setting INDEX_ROUTING_EXCLUDE_GROUP_SETTING = Setting.groupSetting("index.routing.allocation.exclude.", true, Setting.Scope.INDEX); + public static final Setting INDEX_ROUTING_REQUIRE_GROUP_SETTING = + Setting.groupSetting("index.routing.allocation.require.", true, SettingsProperty.IndexScope); + public static final Setting INDEX_ROUTING_INCLUDE_GROUP_SETTING = + Setting.groupSetting("index.routing.allocation.include.", true, SettingsProperty.IndexScope); + public static final Setting INDEX_ROUTING_EXCLUDE_GROUP_SETTING = + Setting.groupSetting("index.routing.allocation.exclude.", true, SettingsProperty.IndexScope); public static final IndexMetaData PROTO = IndexMetaData.builder("") .settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index 8ba78979f3f..f729cc4cabc 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -41,6 +41,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.common.xcontent.FromXContentBuilder; @@ -139,7 +140,8 @@ public class MetaData implements Iterable, Diffable, Fr } - public static final Setting SETTING_READ_ONLY_SETTING = Setting.boolSetting("cluster.blocks.read_only", false, true, Setting.Scope.CLUSTER); + public static final Setting SETTING_READ_ONLY_SETTING = + Setting.boolSetting("cluster.blocks.read_only", false, true, SettingsProperty.ClusterScope); public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE)); diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java index 714c1e4913a..d7cfe1a39d9 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; @@ -44,7 +45,9 @@ public class UnassignedInfo implements ToXContent, Writeable { public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime"); private static final TimeValue DEFAULT_DELAYED_NODE_LEFT_TIMEOUT = TimeValue.timeValueMinutes(1); - public static final Setting INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING = Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, true, Setting.Scope.INDEX); + public static final Setting INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING = + Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, true, + SettingsProperty.IndexScope); /** * Reason why the shard is in unassigned state. diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java index e12020cfa74..248d5aa25c9 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java @@ -39,6 +39,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.gateway.PriorityComparator; @@ -72,9 +73,12 @@ import static org.elasticsearch.cluster.routing.ShardRoutingState.RELOCATING; */ public class BalancedShardsAllocator extends AbstractComponent implements ShardsAllocator { - public static final Setting INDEX_BALANCE_FACTOR_SETTING = Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, true, Setting.Scope.CLUSTER); - public static final Setting SHARD_BALANCE_FACTOR_SETTING = Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, true, Setting.Scope.CLUSTER); - public static final Setting THRESHOLD_SETTING = Setting.floatSetting("cluster.routing.allocation.balance.threshold", 1.0f, 0.0f, true, Setting.Scope.CLUSTER); + public static final Setting INDEX_BALANCE_FACTOR_SETTING = + Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, true, SettingsProperty.ClusterScope); + public static final Setting SHARD_BALANCE_FACTOR_SETTING = + Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, true, SettingsProperty.ClusterScope); + public static final Setting THRESHOLD_SETTING = + Setting.floatSetting("cluster.routing.allocation.balance.threshold", 1.0f, 0.0f, true, SettingsProperty.ClusterScope); private volatile WeightFunction weightFunction; private volatile float threshold; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java index 9859a9b6584..792f670dcf2 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.HashMap; @@ -77,8 +78,11 @@ public class AwarenessAllocationDecider extends AllocationDecider { public static final String NAME = "awareness"; - public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING = new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING = Setting.groupSetting("cluster.routing.allocation.awareness.force.", true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING = + new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , true, + SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING = + Setting.groupSetting("cluster.routing.allocation.awareness.force.", true, SettingsProperty.ClusterScope); private String[] awarenessAttributes; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java index 11fce397b26..2c59fee3af6 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java @@ -24,6 +24,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.Locale; @@ -48,7 +49,9 @@ import java.util.Locale; public class ClusterRebalanceAllocationDecider extends AllocationDecider { public static final String NAME = "cluster_rebalance"; - public static final Setting CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING = new Setting<>("cluster.routing.allocation.allow_rebalance", ClusterRebalanceType.INDICES_ALL_ACTIVE.name().toLowerCase(Locale.ROOT), ClusterRebalanceType::parseString, true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING = + new Setting<>("cluster.routing.allocation.allow_rebalance", ClusterRebalanceType.INDICES_ALL_ACTIVE.name().toLowerCase(Locale.ROOT), + ClusterRebalanceType::parseString, true, SettingsProperty.ClusterScope); /** * An enum representation for the configured re-balance type. diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java index d39b9604066..cda5e628dec 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java @@ -24,6 +24,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -42,7 +43,8 @@ public class ConcurrentRebalanceAllocationDecider extends AllocationDecider { public static final String NAME = "concurrent_rebalance"; - public static final Setting CLUSTER_ROUTING_ALLOCATION_CLUSTER_CONCURRENT_REBALANCE_SETTING = Setting.intSetting("cluster.routing.allocation.cluster_concurrent_rebalance", 2, -1, true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_CLUSTER_CONCURRENT_REBALANCE_SETTING = + Setting.intSetting("cluster.routing.allocation.cluster_concurrent_rebalance", 2, -1, true, SettingsProperty.ClusterScope); private volatile int clusterConcurrentRebalance; @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java index 821fa55d704..051eab81ec8 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java @@ -38,6 +38,7 @@ import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.RatioValue; @@ -81,11 +82,17 @@ public class DiskThresholdDecider extends AllocationDecider { private volatile boolean enabled; private volatile TimeValue rerouteInterval; - public static final Setting CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING = Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING = new Setting<>("cluster.routing.allocation.disk.watermark.low", "85%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.low"), true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING = new Setting<>("cluster.routing.allocation.disk.watermark.high", "90%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.high"), true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING = Setting.boolSetting("cluster.routing.allocation.disk.include_relocations", true, true, Setting.Scope.CLUSTER);; - public static final Setting CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING = Setting.positiveTimeSetting("cluster.routing.allocation.disk.reroute_interval", TimeValue.timeValueSeconds(60), true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING = + Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING = + new Setting<>("cluster.routing.allocation.disk.watermark.low", "85%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.low"), true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING = + new Setting<>("cluster.routing.allocation.disk.watermark.high", "90%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.high"), true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING = + Setting.boolSetting("cluster.routing.allocation.disk.include_relocations", true, true, SettingsProperty.ClusterScope);; + public static final Setting CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING = + Setting.positiveTimeSetting("cluster.routing.allocation.disk.reroute_interval", TimeValue.timeValueSeconds(60), true, + SettingsProperty.ClusterScope); /** * Listens for a node to go over the high watermark and kicks off an empty diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java index 9131355876b..edece247c8b 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java @@ -26,6 +26,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.Locale; @@ -60,11 +61,15 @@ public class EnableAllocationDecider extends AllocationDecider { public static final String NAME = "enable"; - public static final Setting CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING = new Setting<>("cluster.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, Setting.Scope.CLUSTER); - public static final Setting INDEX_ROUTING_ALLOCATION_ENABLE_SETTING = new Setting<>("index.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, Setting.Scope.INDEX); + public static final Setting CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING = + new Setting<>("cluster.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, SettingsProperty.ClusterScope); + public static final Setting INDEX_ROUTING_ALLOCATION_ENABLE_SETTING = + new Setting<>("index.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, SettingsProperty.IndexScope); - public static final Setting CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING = new Setting<>("cluster.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, Setting.Scope.CLUSTER); - public static final Setting INDEX_ROUTING_REBALANCE_ENABLE_SETTING = new Setting<>("index.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, Setting.Scope.INDEX); + public static final Setting CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING = + new Setting<>("cluster.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, SettingsProperty.ClusterScope); + public static final Setting INDEX_ROUTING_REBALANCE_ENABLE_SETTING = + new Setting<>("index.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, SettingsProperty.IndexScope); private volatile Rebalance enableRebalance; private volatile Allocation enableAllocation; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java index f8ff5f37aed..59f6ec1531a 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java @@ -27,6 +27,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.AND; @@ -60,9 +61,12 @@ public class FilterAllocationDecider extends AllocationDecider { public static final String NAME = "filter"; - public static final Setting CLUSTER_ROUTING_REQUIRE_GROUP_SETTING = Setting.groupSetting("cluster.routing.allocation.require.", true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_INCLUDE_GROUP_SETTING = Setting.groupSetting("cluster.routing.allocation.include.", true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING = Setting.groupSetting("cluster.routing.allocation.exclude.", true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_REQUIRE_GROUP_SETTING = + Setting.groupSetting("cluster.routing.allocation.require.", true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_INCLUDE_GROUP_SETTING = + Setting.groupSetting("cluster.routing.allocation.include.", true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING = + Setting.groupSetting("cluster.routing.allocation.exclude.", true, SettingsProperty.ClusterScope); private volatile DiscoveryNodeFilters clusterRequireFilters; private volatile DiscoveryNodeFilters clusterIncludeFilters; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java index e766b4c49aa..be6c98d147b 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java @@ -27,6 +27,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -59,13 +60,15 @@ public class ShardsLimitAllocationDecider extends AllocationDecider { * Controls the maximum number of shards per index on a single Elasticsearch * node. Negative values are interpreted as unlimited. */ - public static final Setting INDEX_TOTAL_SHARDS_PER_NODE_SETTING = Setting.intSetting("index.routing.allocation.total_shards_per_node", -1, -1, true, Setting.Scope.INDEX); + public static final Setting INDEX_TOTAL_SHARDS_PER_NODE_SETTING = + Setting.intSetting("index.routing.allocation.total_shards_per_node", -1, -1, true, SettingsProperty.IndexScope); /** * Controls the maximum number of shards per node on a global level. * Negative values are interpreted as unlimited. */ - public static final Setting CLUSTER_TOTAL_SHARDS_PER_NODE_SETTING = Setting.intSetting("cluster.routing.allocation.total_shards_per_node", -1, -1, true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_TOTAL_SHARDS_PER_NODE_SETTING = + Setting.intSetting("cluster.routing.allocation.total_shards_per_node", -1, -1, true, SettingsProperty.ClusterScope); @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java index cf889cde6ad..b4927b6c5c7 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java @@ -26,6 +26,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -39,7 +40,8 @@ public class SnapshotInProgressAllocationDecider extends AllocationDecider { /** * Disables relocation of shards that are currently being snapshotted. */ - public static final Setting CLUSTER_ROUTING_ALLOCATION_SNAPSHOT_RELOCATION_ENABLED_SETTING = Setting.boolSetting("cluster.routing.allocation.snapshot.relocation_enabled", false, true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_SNAPSHOT_RELOCATION_ENABLED_SETTING = + Setting.boolSetting("cluster.routing.allocation.snapshot.relocation_enabled", false, true, SettingsProperty.ClusterScope); private volatile boolean enableRelocation = false; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java index 25f43f57610..1e12eb406b8 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -50,10 +51,23 @@ public class ThrottlingAllocationDecider extends AllocationDecider { public static final int DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES = 2; public static final int DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES = 4; public static final String NAME = "throttling"; - public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_recoveries", Integer.toString(DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_recoveries"), true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES_SETTING = Setting.intSetting("cluster.routing.allocation.node_initial_primaries_recoveries", DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES, 0, true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_incoming_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_incoming_recoveries"), true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_outgoing_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_outgoing_recoveries"), true, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING = + new Setting<>("cluster.routing.allocation.node_concurrent_recoveries", + Integer.toString(DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES), + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_recoveries"), true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES_SETTING = + Setting.intSetting("cluster.routing.allocation.node_initial_primaries_recoveries", + DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES, 0, true, SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING = + new Setting<>("cluster.routing.allocation.node_concurrent_incoming_recoveries", + (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_incoming_recoveries"), true, + SettingsProperty.ClusterScope); + public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING = + new Setting<>("cluster.routing.allocation.node_concurrent_outgoing_recoveries", + (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_outgoing_recoveries"), true, + SettingsProperty.ClusterScope); private volatile int primariesInitialRecoveries; diff --git a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java index 1ee3dddf77c..0b0fd5e2b99 100644 --- a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java +++ b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java @@ -51,6 +51,7 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.transport.TransportAddress; @@ -93,8 +94,12 @@ import static org.elasticsearch.common.util.concurrent.EsExecutors.daemonThreadF */ public class InternalClusterService extends AbstractLifecycleComponent implements ClusterService { - public static final Setting CLUSTER_SERVICE_SLOW_TASK_LOGGING_THRESHOLD_SETTING = Setting.positiveTimeSetting("cluster.service.slow_task_logging_threshold", TimeValue.timeValueSeconds(30), true, Setting.Scope.CLUSTER); - public static final Setting CLUSTER_SERVICE_RECONNECT_INTERVAL_SETTING = Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), false, Setting.Scope.CLUSTER); + public static final Setting CLUSTER_SERVICE_SLOW_TASK_LOGGING_THRESHOLD_SETTING = + Setting.positiveTimeSetting("cluster.service.slow_task_logging_threshold", TimeValue.timeValueSeconds(30), true, + SettingsProperty.ClusterScope); + public static final Setting CLUSTER_SERVICE_RECONNECT_INTERVAL_SETTING = + Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), false, + SettingsProperty.ClusterScope); public static final String UPDATE_THREAD_NAME = "clusterService#updateTask"; private final ThreadPool threadPool; diff --git a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java index 4fdde3db895..98d75c86482 100644 --- a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java +++ b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.logging.log4j.Log4jESLoggerFactory; import org.elasticsearch.common.logging.slf4j.Slf4jESLoggerFactory; import org.elasticsearch.common.settings.AbstractScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.Locale; @@ -36,8 +37,10 @@ import java.util.regex.Pattern; */ public abstract class ESLoggerFactory { - public static final Setting LOG_DEFAULT_LEVEL_SETTING = new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, false, Setting.Scope.CLUSTER); - public static final Setting LOG_LEVEL_SETTING = Setting.dynamicKeySetting("logger.", LogLevel.INFO.name(), LogLevel::parse, true, Setting.Scope.CLUSTER); + public static final Setting LOG_DEFAULT_LEVEL_SETTING = + new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, false, SettingsProperty.ClusterScope); + public static final Setting LOG_LEVEL_SETTING = + Setting.dynamicKeySetting("logger.", LogLevel.INFO.name(), LogLevel::parse, true, SettingsProperty.ClusterScope); private static volatile ESLoggerFactory defaultFactory = new JdkESLoggerFactory(); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java index b0598469d3a..ea2cc1b4267 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java @@ -28,8 +28,8 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.Setting.Scope; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.http.HttpServer; import org.elasticsearch.http.HttpServerTransport; @@ -155,10 +155,12 @@ public class NetworkModule extends AbstractModule { public static final String LOCAL_TRANSPORT = "local"; public static final String NETTY_TRANSPORT = "netty"; - public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", false, Scope.CLUSTER); - public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, false, Scope.CLUSTER); - public static final Setting TRANSPORT_SERVICE_TYPE_SETTING = Setting.simpleString("transport.service.type", false, Scope.CLUSTER); - public static final Setting TRANSPORT_TYPE_SETTING = Setting.simpleString("transport.type", false, Scope.CLUSTER); + public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", false, SettingsProperty.ClusterScope); + public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, false, SettingsProperty.ClusterScope); + public static final Setting TRANSPORT_SERVICE_TYPE_SETTING = + Setting.simpleString("transport.service.type", false, SettingsProperty.ClusterScope); + public static final Setting TRANSPORT_TYPE_SETTING = + Setting.simpleString("transport.type", false, SettingsProperty.ClusterScope); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java index 5e8dbc4dcad..abb7795f12a 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java @@ -22,6 +22,7 @@ package org.elasticsearch.common.network; import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -43,24 +44,33 @@ public class NetworkService extends AbstractComponent { /** By default, we bind to loopback interfaces */ public static final String DEFAULT_NETWORK_HOST = "_local_"; - public static final Setting> GLOBAL_NETWORK_HOST_SETTING = Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), - s -> s, false, Setting.Scope.CLUSTER); - public static final Setting> GLOBAL_NETWORK_BINDHOST_SETTING = Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, - s -> s, false, Setting.Scope.CLUSTER); - public static final Setting> GLOBAL_NETWORK_PUBLISHHOST_SETTING = Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, - s -> s, false, Setting.Scope.CLUSTER); - public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, false, Setting.Scope.CLUSTER); + public static final Setting> GLOBAL_NETWORK_HOST_SETTING = + Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> GLOBAL_NETWORK_BINDHOST_SETTING = + Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> GLOBAL_NETWORK_PUBLISHHOST_SETTING = + Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, false, SettingsProperty.ClusterScope); + public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, false, SettingsProperty.ClusterScope); public static final class TcpSettings { - public static final Setting TCP_NO_DELAY = Setting.boolSetting("network.tcp.no_delay", true, false, Setting.Scope.CLUSTER); - public static final Setting TCP_KEEP_ALIVE = Setting.boolSetting("network.tcp.keep_alive", true, false, Setting.Scope.CLUSTER); - public static final Setting TCP_REUSE_ADDRESS = Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), false, Setting.Scope.CLUSTER); - public static final Setting TCP_SEND_BUFFER_SIZE = Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); - public static final Setting TCP_RECEIVE_BUFFER_SIZE = Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); - public static final Setting TCP_BLOCKING = Setting.boolSetting("network.tcp.blocking", false, false, Setting.Scope.CLUSTER); - public static final Setting TCP_BLOCKING_SERVER = Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, false, Setting.Scope.CLUSTER); - public static final Setting TCP_BLOCKING_CLIENT = Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, false, Setting.Scope.CLUSTER); - public static final Setting TCP_CONNECT_TIMEOUT = Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), false, Setting.Scope.CLUSTER); + public static final Setting TCP_NO_DELAY = + Setting.boolSetting("network.tcp.no_delay", true, false, SettingsProperty.ClusterScope); + public static final Setting TCP_KEEP_ALIVE = + Setting.boolSetting("network.tcp.keep_alive", true, false, SettingsProperty.ClusterScope); + public static final Setting TCP_REUSE_ADDRESS = + Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), false, SettingsProperty.ClusterScope); + public static final Setting TCP_SEND_BUFFER_SIZE = + Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + public static final Setting TCP_RECEIVE_BUFFER_SIZE = + Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + public static final Setting TCP_BLOCKING = + Setting.boolSetting("network.tcp.blocking", false, false, SettingsProperty.ClusterScope); + public static final Setting TCP_BLOCKING_SERVER = + Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, false, SettingsProperty.ClusterScope); + public static final Setting TCP_BLOCKING_CLIENT = + Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, false, SettingsProperty.ClusterScope); + public static final Setting TCP_CONNECT_TIMEOUT = + Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), false, SettingsProperty.ClusterScope); } /** diff --git a/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java index b30178857e1..5345ab03b63 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java @@ -22,7 +22,6 @@ package org.elasticsearch.common.settings; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.regex.Regex; -import org.elasticsearch.common.util.set.Sets; import java.util.ArrayList; import java.util.Collections; @@ -45,19 +44,19 @@ public abstract class AbstractScopedSettings extends AbstractComponent { private final List> settingUpdaters = new CopyOnWriteArrayList<>(); private final Map> complexMatchers; private final Map> keySettings; - private final Setting.Scope scope; + private final Setting.SettingsProperty scope; private static final Pattern KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])*[-\\w]+$"); private static final Pattern GROUP_KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])+$"); - protected AbstractScopedSettings(Settings settings, Set> settingsSet, Setting.Scope scope) { + protected AbstractScopedSettings(Settings settings, Set> settingsSet, Setting.SettingsProperty scope) { super(settings); this.lastSettingsApplied = Settings.EMPTY; this.scope = scope; Map> complexMatchers = new HashMap<>(); Map> keySettings = new HashMap<>(); for (Setting setting : settingsSet) { - if (setting.getScope() != scope) { - throw new IllegalArgumentException("Setting must be a " + scope + " setting but was: " + setting.getScope()); + if (setting.getProperties().contains(scope) == false) { + throw new IllegalArgumentException("Setting must be a " + scope + " setting but has: " + setting.getProperties()); } if (isValidKey(setting.getKey()) == false && (setting.isGroupSetting() && isValidGroupKey(setting.getKey())) == false) { throw new IllegalArgumentException("illegal settings key: [" + setting.getKey() + "]"); @@ -92,7 +91,7 @@ public abstract class AbstractScopedSettings extends AbstractComponent { return GROUP_KEY_PATTERN.matcher(key).matches(); } - public Setting.Scope getScope() { + public Setting.SettingsProperty getScope() { return this.scope; } @@ -325,8 +324,9 @@ public abstract class AbstractScopedSettings extends AbstractComponent { * Returns the value for the given setting. */ public T get(Setting setting) { - if (setting.getScope() != scope) { - throw new IllegalArgumentException("settings scope doesn't match the setting scope [" + this.scope + "] != [" + setting.getScope() + "]"); + if (setting.getProperties().contains(scope) == false) { + throw new IllegalArgumentException("settings scope doesn't match the setting scope [" + this.scope + "] not in [" + + setting.getProperties() + "]"); } if (get(setting.getKey()) == null) { throw new IllegalArgumentException("setting " + setting.getKey() + " has not been registered"); diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index d68e43ea1cb..36a06667857 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -45,6 +45,7 @@ import org.elasticsearch.cluster.service.InternalClusterService; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.network.NetworkService; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.discovery.DiscoveryModule; @@ -102,7 +103,7 @@ import java.util.function.Predicate; */ public final class ClusterSettings extends AbstractScopedSettings { public ClusterSettings(Settings nodeSettings, Set> settingsSet) { - super(nodeSettings, settingsSet, Setting.Scope.CLUSTER); + super(nodeSettings, settingsSet, SettingsProperty.ClusterScope); addSettingsUpdater(new LoggingSettingUpdater(nodeSettings)); } diff --git a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index 69ef795812d..a8f06fd9cf5 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -22,6 +22,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.routing.UnassignedInfo; import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.gateway.PrimaryShardAllocator; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; @@ -49,7 +50,7 @@ import java.util.function.Predicate; /** * Encapsulates all valid index level settings. - * @see org.elasticsearch.common.settings.Setting.Scope#INDEX + * @see org.elasticsearch.common.settings.Setting.SettingsProperty#IndexScope */ public final class IndexScopedSettings extends AbstractScopedSettings { @@ -134,15 +135,15 @@ public final class IndexScopedSettings extends AbstractScopedSettings { EngineConfig.INDEX_CODEC_SETTING, IndexWarmer.INDEX_NORMS_LOADING_SETTING, // this sucks but we can't really validate all the analyzers/similarity in here - Setting.groupSetting("index.similarity.", false, Setting.Scope.INDEX), // this allows similarity settings to be passed - Setting.groupSetting("index.analysis.", false, Setting.Scope.INDEX) // this allows analysis settings to be passed + Setting.groupSetting("index.similarity.", false, SettingsProperty.IndexScope), // this allows similarity settings to be passed + Setting.groupSetting("index.analysis.", false, SettingsProperty.IndexScope) // this allows analysis settings to be passed ))); public static final IndexScopedSettings DEFAULT_SCOPED_SETTINGS = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS); public IndexScopedSettings(Settings settings, Set> settingsSet) { - super(settings, settingsSet, Setting.Scope.INDEX); + super(settings, settingsSet, SettingsProperty.IndexScope); } private IndexScopedSettings(Settings settings, IndexScopedSettings other, IndexMetaData metaData) { diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index 1e0e2190fcc..ce66eda1766 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -35,6 +35,8 @@ import org.elasticsearch.common.xcontent.XContentType; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.Objects; import java.util.function.BiConsumer; @@ -50,7 +52,7 @@ import java.util.stream.Collectors; * together with {@link AbstractScopedSettings}. This class contains several utility methods that makes it straight forward * to add settings for the majority of the cases. For instance a simple boolean settings can be defined like this: *
{@code
- * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, false, Scope.CLUSTER);}
+ * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, false, SettingsProperty.ClusterScope);}
  * 
* To retrieve the value of the setting a {@link Settings} object can be passed directly to the {@link Setting#get(Settings)} method. *
@@ -61,29 +63,26 @@ import java.util.stream.Collectors;
  * public enum Color {
  *     RED, GREEN, BLUE;
  * }
- * public static final Setting MY_BOOLEAN = new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, false, Scope.CLUSTER);
+ * public static final Setting MY_BOOLEAN =
+ *     new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, false, SettingsProperty.ClusterScope);
  * }
  * 
*/ public class Setting extends ToXContentToBytes { + + public enum SettingsProperty { + Filtered, + Dynamic, + ClusterScope, + NodeScope, + IndexScope; + } + private final String key; protected final Function defaultValue; private final Function parser; private final boolean dynamic; - private final Scope scope; - private final boolean filtered; - - /** - * Creates a new Setting instance, unfiltered - * @param key the settings key for this setting. - * @param defaultValue a default value function that returns the default values string representation. - * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable - * @param scope the scope of this setting - */ - public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope) { - this(key, defaultValue, parser, dynamic, scope, false); - } + private final EnumSet properties; /** * Creates a new Setting instance @@ -91,30 +90,32 @@ public class Setting extends ToXContentToBytes { * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. * @param dynamic true iff this setting can be dynamically updateable - * @param scope the scope of this setting - * @param filtered true if this setting should be filtered + * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope, - boolean filtered) { + public Setting(String key, Function defaultValue, Function parser, boolean dynamic, + SettingsProperty... properties) { assert parser.apply(defaultValue.apply(Settings.EMPTY)) != null || this.isGroupSetting(): "parser returned null"; this.key = key; this.defaultValue = defaultValue; this.parser = parser; this.dynamic = dynamic; - this.scope = scope; - this.filtered = filtered; + if (properties.length == 0) { + this.properties = EnumSet.of(SettingsProperty.NodeScope); + } else { + this.properties = EnumSet.copyOf(Arrays.asList(properties)); + } } /** - * Creates a new Setting instance, unfiltered + * Creates a new Setting instance * @param key the settings key for this setting. - * @param fallBackSetting a setting to fall back to if the current setting is not set. + * @param defaultValue a default value. * @param parser a parser that parses the string rep into a complex datatype. * @param dynamic true iff this setting can be dynamically updateable - * @param scope the scope of this setting + * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, Scope scope) { - this(key, fallBackSetting, parser, dynamic, scope, false); + public Setting(String key, String defaultValue, Function parser, boolean dynamic, SettingsProperty... properties) { + this(key, s -> defaultValue, parser, dynamic, properties); } /** @@ -123,11 +124,10 @@ public class Setting extends ToXContentToBytes { * @param fallBackSetting a setting to fall back to if the current setting is not set. * @param parser a parser that parses the string rep into a complex datatype. * @param dynamic true iff this setting can be dynamically updateable - * @param scope the scope of this setting - * @param filtered true if this setting should be filtered + * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, Scope scope, boolean filtered) { - this(key, fallBackSetting::getRaw, parser, dynamic, scope, filtered); + public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, SettingsProperty... properties) { + this(key, fallBackSetting::getRaw, parser, dynamic, properties); } /** @@ -149,17 +149,39 @@ public class Setting extends ToXContentToBytes { } /** - * Returns the settings scope + * Returns the setting properties + * @see SettingsProperty */ - public final Scope getScope() { - return scope; + public EnumSet getProperties() { + return properties; } /** * Returns true if this setting must be filtered, otherwise false */ public boolean isFiltered() { - return filtered; + return properties.contains(SettingsProperty.Filtered); + } + + /** + * Returns true if this setting has a cluster scope, otherwise false + */ + public boolean hasClusterScope() { + return properties.contains(SettingsProperty.ClusterScope); + } + + /** + * Returns true if this setting has an index scope, otherwise false + */ + public boolean hasIndexScope() { + return properties.contains(SettingsProperty.IndexScope); + } + + /** + * Returns true if this setting has an index scope, otherwise false + */ + public boolean hasNodeScope() { + return properties.contains(SettingsProperty.NodeScope); } /** @@ -238,7 +260,7 @@ public class Setting extends ToXContentToBytes { public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.field("key", key); - builder.field("type", scope.name()); + builder.field("properties", properties); builder.field("dynamic", dynamic); builder.field("is_group_setting", isGroupSetting()); builder.field("default", defaultValue.apply(Settings.EMPTY)); @@ -261,14 +283,6 @@ public class Setting extends ToXContentToBytes { return this; } - /** - * The settings scope - settings can either be cluster settings or per index settings. - */ - public enum Scope { - CLUSTER, - INDEX; - } - /** * Build a new updater with a noop validator. */ @@ -366,50 +380,35 @@ public class Setting extends ToXContentToBytes { } - public Setting(String key, String defaultValue, Function parser, boolean dynamic, Scope scope) { - this(key, defaultValue, parser, dynamic, scope, false); + public static Setting floatSetting(String key, float defaultValue, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Float.toString(defaultValue), Float::parseFloat, dynamic, properties); } - public Setting(String key, String defaultValue, Function parser, boolean dynamic, Scope scope, boolean filtered) { - this(key, (s) -> defaultValue, parser, dynamic, scope, filtered); - } - - public static Setting floatSetting(String key, float defaultValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> Float.toString(defaultValue), Float::parseFloat, dynamic, scope); - } - - public static Setting floatSetting(String key, float defaultValue, float minValue, boolean dynamic, Scope scope) { + public static Setting floatSetting(String key, float defaultValue, float minValue, boolean dynamic, SettingsProperty... properties) { return new Setting<>(key, (s) -> Float.toString(defaultValue), (s) -> { float value = Float.parseFloat(s); if (value < minValue) { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return value; - }, dynamic, scope); + }, dynamic, properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, maxValue, key), dynamic, scope); + public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, boolean dynamic, + SettingsProperty... properties) { + return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, maxValue, key), dynamic, properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key), dynamic, scope); + public static Setting intSetting(String key, int defaultValue, int minValue, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key), dynamic, properties); } - public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, Scope scope) { - return longSetting(key, defaultValue, minValue, dynamic, scope, false); + public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), dynamic, properties); } - public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, Scope scope, boolean filtered) { - return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), dynamic, scope, filtered); - } - - public static Setting simpleString(String key, boolean dynamic, Scope scope) { - return simpleString(key, dynamic, scope, false); - } - - public static Setting simpleString(String key, boolean dynamic, Scope scope, boolean filtered) { - return new Setting<>(key, s -> "", Function.identity(), dynamic, scope, filtered); + public static Setting simpleString(String key, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, s -> "", Function.identity(), dynamic, properties); } public static int parseInt(String s, int minValue, String key) { @@ -435,55 +434,58 @@ public class Setting extends ToXContentToBytes { return value; } - public static Setting intSetting(String key, int defaultValue, boolean dynamic, Scope scope) { - return intSetting(key, defaultValue, Integer.MIN_VALUE, dynamic, scope); + public static Setting intSetting(String key, int defaultValue, boolean dynamic, SettingsProperty... properties) { + return intSetting(key, defaultValue, Integer.MIN_VALUE, dynamic, properties); } - public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, Scope scope) { - return boolSetting(key, defaultValue, dynamic, scope, false); + public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, dynamic, properties); } - public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, Scope scope, boolean filtered) { - return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, dynamic, scope, filtered); + public static Setting boolSetting(String key, Setting fallbackSetting, boolean dynamic, + SettingsProperty... properties) { + return new Setting<>(key, fallbackSetting, Booleans::parseBooleanExact, dynamic, properties); } - public static Setting boolSetting(String key, Setting fallbackSetting, boolean dynamic, Scope scope) { - return new Setting<>(key, fallbackSetting, Booleans::parseBooleanExact, dynamic, scope); + public static Setting byteSizeSetting(String key, String percentage, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> percentage, (s) -> MemorySizeValue.parseBytesSizeValueOrHeapRatio(s, key), dynamic, properties); } - public static Setting byteSizeSetting(String key, String percentage, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> percentage, (s) -> MemorySizeValue.parseBytesSizeValueOrHeapRatio(s, key), dynamic, scope); + public static Setting byteSizeSetting(String key, ByteSizeValue value, boolean dynamic, SettingsProperty... properties) { + return byteSizeSetting(key, (s) -> value.toString(), dynamic, properties); } - public static Setting byteSizeSetting(String key, ByteSizeValue value, boolean dynamic, Scope scope) { - return byteSizeSetting(key, (s) -> value.toString(), dynamic, scope); + public static Setting byteSizeSetting(String key, Setting fallbackSettings, boolean dynamic, + SettingsProperty... properties) { + return byteSizeSetting(key, fallbackSettings::getRaw, dynamic, properties); } - public static Setting byteSizeSetting(String key, Setting fallbackSettings, boolean dynamic, Scope scope) { - return byteSizeSetting(key, fallbackSettings::getRaw, dynamic, scope); + public static Setting byteSizeSetting(String key, Function defaultValue, boolean dynamic, + SettingsProperty... properties) { + return new Setting<>(key, defaultValue, (s) -> ByteSizeValue.parseBytesSizeValue(s, key), dynamic, properties); } - public static Setting byteSizeSetting(String key, Function defaultValue, boolean dynamic, Scope scope) { - return new Setting<>(key, defaultValue, (s) -> ByteSizeValue.parseBytesSizeValue(s, key), dynamic, scope); + public static Setting positiveTimeSetting(String key, TimeValue defaultValue, boolean dynamic, SettingsProperty... properties) { + return timeSetting(key, defaultValue, TimeValue.timeValueMillis(0), dynamic, properties); } - public static Setting positiveTimeSetting(String key, TimeValue defaultValue, boolean dynamic, Scope scope) { - return timeSetting(key, defaultValue, TimeValue.timeValueMillis(0), dynamic, scope); + public static Setting> listSetting(String key, List defaultStringValue, Function singleValueParser, + boolean dynamic, SettingsProperty... properties) { + return listSetting(key, (s) -> defaultStringValue, singleValueParser, dynamic, properties); } - public static Setting> listSetting(String key, List defaultStringValue, Function singleValueParser, boolean dynamic, Scope scope) { - return listSetting(key, (s) -> defaultStringValue, singleValueParser, dynamic, scope); + public static Setting> listSetting(String key, Setting> fallbackSetting, Function singleValueParser, + boolean dynamic, SettingsProperty... properties) { + return listSetting(key, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), singleValueParser, dynamic, properties); } - public static Setting> listSetting(String key, Setting> fallbackSetting, Function singleValueParser, boolean dynamic, Scope scope) { - return listSetting(key, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), singleValueParser, dynamic, scope); - } - - public static Setting> listSetting(String key, Function> defaultStringValue, Function singleValueParser, boolean dynamic, Scope scope) { + public static Setting> listSetting(String key, Function> defaultStringValue, + Function singleValueParser, boolean dynamic, SettingsProperty... properties) { Function> parser = (s) -> parseableStringToList(s).stream().map(singleValueParser).collect(Collectors.toList()); - return new Setting>(key, (s) -> arrayToParsableString(defaultStringValue.apply(s).toArray(Strings.EMPTY_ARRAY)), parser, dynamic, scope) { + return new Setting>(key, (s) -> arrayToParsableString(defaultStringValue.apply(s).toArray(Strings.EMPTY_ARRAY)), parser, + dynamic, properties) { private final Pattern pattern = Pattern.compile(Pattern.quote(key)+"(\\.\\d+)?"); @Override public String getRaw(Settings settings) { @@ -537,11 +539,11 @@ public class Setting extends ToXContentToBytes { } } - public static Setting groupSetting(String key, boolean dynamic, Scope scope) { + public static Setting groupSetting(String key, boolean dynamic, SettingsProperty... properties) { if (key.endsWith(".") == false) { throw new IllegalArgumentException("key must end with a '.'"); } - return new Setting(key, "", (s) -> null, dynamic, scope) { + return new Setting(key, "", (s) -> null, dynamic, properties) { @Override public boolean isGroupSetting() { @@ -600,36 +602,40 @@ public class Setting extends ToXContentToBytes { }; } - public static Setting timeSetting(String key, Function defaultValue, TimeValue minValue, boolean dynamic, Scope scope) { + public static Setting timeSetting(String key, Function defaultValue, TimeValue minValue, boolean dynamic, + SettingsProperty... properties) { return new Setting<>(key, defaultValue, (s) -> { TimeValue timeValue = TimeValue.parseTimeValue(s, null, key); if (timeValue.millis() < minValue.millis()) { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return timeValue; - }, dynamic, scope); + }, dynamic, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, boolean dynamic, Scope scope) { - return timeSetting(key, (s) -> defaultValue.getStringRep(), minValue, dynamic, scope); + public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, boolean dynamic, + SettingsProperty... properties) { + return timeSetting(key, (s) -> defaultValue.getStringRep(), minValue, dynamic, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, boolean dynamic, Scope scope) { - return new Setting<>(key, (s) -> defaultValue.toString(), (s) -> TimeValue.parseTimeValue(s, key), dynamic, scope); + public static Setting timeSetting(String key, TimeValue defaultValue, boolean dynamic, SettingsProperty... properties) { + return new Setting<>(key, (s) -> defaultValue.toString(), (s) -> TimeValue.parseTimeValue(s, key), dynamic, properties); } - public static Setting timeSetting(String key, Setting fallbackSetting, boolean dynamic, Scope scope) { - return new Setting<>(key, fallbackSetting::getRaw, (s) -> TimeValue.parseTimeValue(s, key), dynamic, scope); + public static Setting timeSetting(String key, Setting fallbackSetting, boolean dynamic, + SettingsProperty... properties) { + return new Setting<>(key, fallbackSetting::getRaw, (s) -> TimeValue.parseTimeValue(s, key), dynamic, properties); } - public static Setting doubleSetting(String key, double defaultValue, double minValue, boolean dynamic, Scope scope) { + public static Setting doubleSetting(String key, double defaultValue, double minValue, boolean dynamic, + SettingsProperty... properties) { return new Setting<>(key, (s) -> Double.toString(defaultValue), (s) -> { final double d = Double.parseDouble(s); if (d < minValue) { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return d; - }, dynamic, scope); + }, dynamic, properties); } @Override @@ -650,8 +656,9 @@ public class Setting extends ToXContentToBytes { * can easily be added with this setting. Yet, dynamic key settings don't support updaters our of the box unless {@link #getConcreteSetting(String)} * is used to pull the updater. */ - public static Setting dynamicKeySetting(String key, String defaultValue, Function parser, boolean dynamic, Scope scope) { - return new Setting(key, defaultValue, parser, dynamic, scope) { + public static Setting dynamicKeySetting(String key, String defaultValue, Function parser, boolean dynamic, + SettingsProperty... properties) { + return new Setting(key, defaultValue, parser, dynamic, properties) { @Override boolean isGroupSetting() { @@ -671,7 +678,7 @@ public class Setting extends ToXContentToBytes { @Override public Setting getConcreteSetting(String key) { if (match(key)) { - return new Setting<>(key, defaultValue, parser, dynamic, scope); + return new Setting<>(key, defaultValue, parser, dynamic, properties); } else { throw new IllegalArgumentException("key must match setting but didn't ["+key +"]"); } diff --git a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java index 027e6e7cafe..8786ac5f447 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java +++ b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java @@ -76,19 +76,17 @@ public class SettingsModule extends AbstractModule { registerSettingsFilter(setting.getKey()); } } - switch (setting.getScope()) { - case CLUSTER: - if (clusterSettings.containsKey(setting.getKey())) { - throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); - } - clusterSettings.put(setting.getKey(), setting); - break; - case INDEX: - if (indexSettings.containsKey(setting.getKey())) { - throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); - } - indexSettings.put(setting.getKey(), setting); - break; + if (setting.hasClusterScope()) { + if (clusterSettings.containsKey(setting.getKey())) { + throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); + } + clusterSettings.put(setting.getKey(), setting); + } + if (setting.hasIndexScope()) { + if (indexSettings.containsKey(setting.getKey())) { + throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); + } + indexSettings.put(setting.getKey(), setting); } } @@ -110,11 +108,11 @@ public class SettingsModule extends AbstractModule { * Check if a setting has already been registered */ public boolean exists(Setting setting) { - switch (setting.getScope()) { - case CLUSTER: - return clusterSettings.containsKey(setting.getKey()); - case INDEX: - return indexSettings.containsKey(setting.getKey()); + if (setting.hasClusterScope()) { + return clusterSettings.containsKey(setting.getKey()); + } + if (setting.hasIndexScope()) { + return indexSettings.containsKey(setting.getKey()); } throw new IllegalArgumentException("setting scope is unknown. This should never happen!"); } diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java index 10b1412425c..6f055e3cf04 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java @@ -20,6 +20,7 @@ package org.elasticsearch.common.util.concurrent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.Arrays; @@ -41,7 +42,8 @@ public class EsExecutors { * Settings key to manually set the number of available processors. * This is used to adjust thread pools sizes etc. per node. */ - public static final Setting PROCESSORS_SETTING = Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, false, Setting.Scope.CLUSTER) ; + public static final Setting PROCESSORS_SETTING = + Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, false, SettingsProperty.ClusterScope); /** * Returns the number of processors available but at most 32. diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java index 1928392fe41..798cd7462af 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.io.Closeable; @@ -63,7 +64,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class ThreadContext implements Closeable, Writeable{ public static final String PREFIX = "request.headers"; - public static final Setting DEFAULT_HEADERS_SETTING = Setting.groupSetting(PREFIX + ".", false, Setting.Scope.CLUSTER); + public static final Setting DEFAULT_HEADERS_SETTING = + Setting.groupSetting(PREFIX + ".", false, SettingsProperty.ClusterScope); private final Map defaultHeader; private static final ThreadContextStruct DEFAULT_CONTEXT = new ThreadContextStruct(Collections.emptyMap()); private final ContextThreadLocal threadLocal; diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java index b51339aac90..57ae63c1104 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java @@ -23,6 +23,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.multibindings.Multibinder; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.discovery.local.LocalDiscovery; @@ -44,10 +45,11 @@ import java.util.function.Function; */ public class DiscoveryModule extends AbstractModule { - public static final Setting DISCOVERY_TYPE_SETTING = new Setting<>("discovery.type", - settings -> DiscoveryNode.localNode(settings) ? "local" : "zen", Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting ZEN_MASTER_SERVICE_TYPE_SETTING = new Setting<>("discovery.zen.masterservice.type", - "zen", Function.identity(), false, Setting.Scope.CLUSTER); + public static final Setting DISCOVERY_TYPE_SETTING = + new Setting<>("discovery.type", settings -> DiscoveryNode.localNode(settings) ? "local" : "zen", Function.identity(), false, + SettingsProperty.ClusterScope); + public static final Setting ZEN_MASTER_SERVICE_TYPE_SETTING = + new Setting<>("discovery.zen.masterservice.type", "zen", Function.identity(), false, SettingsProperty.ClusterScope); private final Settings settings; private final List> unicastHostProviders = new ArrayList<>(); diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java index bef1c8fe5ec..181ee8253c0 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -40,8 +41,11 @@ import java.util.concurrent.TimeUnit; */ public class DiscoveryService extends AbstractLifecycleComponent { - public static final Setting INITIAL_STATE_TIMEOUT_SETTING = Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), false, Setting.Scope.CLUSTER); - public static final Setting DISCOVERY_SEED_SETTING = Setting.longSetting("discovery.id.seed", 0L, Long.MIN_VALUE, false, Setting.Scope.CLUSTER); + public static final Setting INITIAL_STATE_TIMEOUT_SETTING = + Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), false, + SettingsProperty.ClusterScope); + public static final Setting DISCOVERY_SEED_SETTING = + Setting.longSetting("discovery.id.seed", 0L, Long.MIN_VALUE, false, SettingsProperty.ClusterScope); private static class InitialStateListener implements InitialStateDiscoveryListener { diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java index dec856992b3..64c13fabe7c 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.rest.RestStatus; @@ -43,15 +44,21 @@ public class DiscoverySettings extends AbstractComponent { * sets the timeout for a complete publishing cycle, including both sending and committing. the master * will continue to process the next cluster state update after this time has elapsed **/ - public static final Setting PUBLISH_TIMEOUT_SETTING = Setting.positiveTimeSetting("discovery.zen.publish_timeout", TimeValue.timeValueSeconds(30), true, Setting.Scope.CLUSTER); + public static final Setting PUBLISH_TIMEOUT_SETTING = + Setting.positiveTimeSetting("discovery.zen.publish_timeout", TimeValue.timeValueSeconds(30), true, SettingsProperty.ClusterScope); /** * sets the timeout for receiving enough acks for a specific cluster state and committing it. failing * to receive responses within this window will cause the cluster state change to be rejected. */ - public static final Setting COMMIT_TIMEOUT_SETTING = new Setting<>("discovery.zen.commit_timeout", (s) -> PUBLISH_TIMEOUT_SETTING.getRaw(s), (s) -> TimeValue.parseTimeValue(s, TimeValue.timeValueSeconds(30), "discovery.zen.commit_timeout"), true, Setting.Scope.CLUSTER); - public static final Setting NO_MASTER_BLOCK_SETTING = new Setting<>("discovery.zen.no_master_block", "write", DiscoverySettings::parseNoMasterBlock, true, Setting.Scope.CLUSTER); - public static final Setting PUBLISH_DIFF_ENABLE_SETTING = Setting.boolSetting("discovery.zen.publish_diff.enable", true, true, Setting.Scope.CLUSTER); + public static final Setting COMMIT_TIMEOUT_SETTING = + new Setting<>("discovery.zen.commit_timeout", (s) -> PUBLISH_TIMEOUT_SETTING.getRaw(s), + (s) -> TimeValue.parseTimeValue(s, TimeValue.timeValueSeconds(30), "discovery.zen.commit_timeout"), true, + SettingsProperty.ClusterScope); + public static final Setting NO_MASTER_BLOCK_SETTING = + new Setting<>("discovery.zen.no_master_block", "write", DiscoverySettings::parseNoMasterBlock, true, SettingsProperty.ClusterScope); + public static final Setting PUBLISH_DIFF_ENABLE_SETTING = + Setting.boolSetting("discovery.zen.publish_diff.enable", true, true, SettingsProperty.ClusterScope); private volatile ClusterBlock noMasterBlock; private volatile TimeValue publishTimeout; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java index ce083147117..653c77945c9 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java @@ -46,6 +46,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.Discovery; @@ -89,17 +90,28 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; */ public class ZenDiscovery extends AbstractLifecycleComponent implements Discovery, PingContextProvider { - public final static Setting PING_TIMEOUT_SETTING = Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), false, Setting.Scope.CLUSTER); - public final static Setting JOIN_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.join_timeout", - settings -> TimeValue.timeValueMillis(PING_TIMEOUT_SETTING.get(settings).millis() * 20).toString(), TimeValue.timeValueMillis(0), false, Setting.Scope.CLUSTER); - public final static Setting JOIN_RETRY_ATTEMPTS_SETTING = Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, false, Setting.Scope.CLUSTER); - public final static Setting JOIN_RETRY_DELAY_SETTING = Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), false, Setting.Scope.CLUSTER); - public final static Setting MAX_PINGS_FROM_ANOTHER_MASTER_SETTING = Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, false, Setting.Scope.CLUSTER); - public final static Setting SEND_LEAVE_REQUEST_SETTING = Setting.boolSetting("discovery.zen.send_leave_request", true, false, Setting.Scope.CLUSTER); - public final static Setting MASTER_ELECTION_FILTER_CLIENT_SETTING = Setting.boolSetting("discovery.zen.master_election.filter_client", true, false, Setting.Scope.CLUSTER); - public final static Setting MASTER_ELECTION_WAIT_FOR_JOINS_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.master_election.wait_for_joins_timeout", - settings -> TimeValue.timeValueMillis(JOIN_TIMEOUT_SETTING.get(settings).millis() / 2).toString(), TimeValue.timeValueMillis(0), false, Setting.Scope.CLUSTER); - public final static Setting MASTER_ELECTION_FILTER_DATA_SETTING = Setting.boolSetting("discovery.zen.master_election.filter_data", false, false, Setting.Scope.CLUSTER); + public final static Setting PING_TIMEOUT_SETTING = + Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), false, SettingsProperty.ClusterScope); + public final static Setting JOIN_TIMEOUT_SETTING = + Setting.timeSetting("discovery.zen.join_timeout", + settings -> TimeValue.timeValueMillis(PING_TIMEOUT_SETTING.get(settings).millis() * 20).toString(), + TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); + public final static Setting JOIN_RETRY_ATTEMPTS_SETTING = + Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, false, SettingsProperty.ClusterScope); + public final static Setting JOIN_RETRY_DELAY_SETTING = + Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), false, SettingsProperty.ClusterScope); + public final static Setting MAX_PINGS_FROM_ANOTHER_MASTER_SETTING = + Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, false, SettingsProperty.ClusterScope); + public final static Setting SEND_LEAVE_REQUEST_SETTING = + Setting.boolSetting("discovery.zen.send_leave_request", true, false, SettingsProperty.ClusterScope); + public final static Setting MASTER_ELECTION_FILTER_CLIENT_SETTING = + Setting.boolSetting("discovery.zen.master_election.filter_client", true, false, SettingsProperty.ClusterScope); + public final static Setting MASTER_ELECTION_WAIT_FOR_JOINS_TIMEOUT_SETTING = + Setting.timeSetting("discovery.zen.master_election.wait_for_joins_timeout", + settings -> TimeValue.timeValueMillis(JOIN_TIMEOUT_SETTING.get(settings).millis() / 2).toString(), TimeValue.timeValueMillis(0), + false, SettingsProperty.ClusterScope); + public final static Setting MASTER_ELECTION_FILTER_DATA_SETTING = + Setting.boolSetting("discovery.zen.master_election.filter_data", false, false, SettingsProperty.ClusterScope); public static final String DISCOVERY_REJOIN_ACTION_NAME = "internal:discovery/zen/rejoin"; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java index 1482fb92a22..cd418e369c4 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java @@ -26,6 +26,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; @@ -40,7 +41,8 @@ import java.util.List; */ public class ElectMasterService extends AbstractComponent { - public static final Setting DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING = Setting.intSetting("discovery.zen.minimum_master_nodes", -1, true, Setting.Scope.CLUSTER); + public static final Setting DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING = + Setting.intSetting("discovery.zen.minimum_master_nodes", -1, true, SettingsProperty.ClusterScope); // This is the minimum version a master needs to be on, otherwise it gets ignored // This is based on the minimum compatible version of the current version this node is on diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java index 62b0250315c..c4247ea15df 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java @@ -22,7 +22,7 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.threadpool.ThreadPool; @@ -37,11 +37,16 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; */ public abstract class FaultDetection extends AbstractComponent { - public static final Setting CONNECT_ON_NETWORK_DISCONNECT_SETTING = Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, false, Scope.CLUSTER); - public static final Setting PING_INTERVAL_SETTING = Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), false, Scope.CLUSTER); - public static final Setting PING_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), false, Scope.CLUSTER); - public static final Setting PING_RETRIES_SETTING = Setting.intSetting("discovery.zen.fd.ping_retries", 3, false, Scope.CLUSTER); - public static final Setting REGISTER_CONNECTION_LISTENER_SETTING = Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, false, Scope.CLUSTER); + public static final Setting CONNECT_ON_NETWORK_DISCONNECT_SETTING = + Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, false, SettingsProperty.ClusterScope); + public static final Setting PING_INTERVAL_SETTING = + Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), false, SettingsProperty.ClusterScope); + public static final Setting PING_TIMEOUT_SETTING = + Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), false, SettingsProperty.ClusterScope); + public static final Setting PING_RETRIES_SETTING = + Setting.intSetting("discovery.zen.fd.ping_retries", 3, false, SettingsProperty.ClusterScope); + public static final Setting REGISTER_CONNECTION_LISTENER_SETTING = + Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, false, SettingsProperty.ClusterScope); protected final ThreadPool threadPool; protected final ClusterName clusterName; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java index 427abca8d85..24191ccf4fc 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -86,8 +87,11 @@ import static org.elasticsearch.discovery.zen.ping.ZenPing.PingResponse.readPing public class UnicastZenPing extends AbstractLifecycleComponent implements ZenPing { public static final String ACTION_NAME = "internal:discovery/zen/unicast"; - public static final Setting> DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING = Setting.listSetting("discovery.zen.ping.unicast.hosts", Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING = Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, false, Setting.Scope.CLUSTER); + public static final Setting> DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING = + Setting.listSetting("discovery.zen.ping.unicast.hosts", Collections.emptyList(), Function.identity(), false, + SettingsProperty.ClusterScope); + public static final Setting DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING = + Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, false, SettingsProperty.ClusterScope); // these limits are per-address public static final int LIMIT_FOREIGN_PORTS_COUNT = 1; diff --git a/core/src/main/java/org/elasticsearch/env/Environment.java b/core/src/main/java/org/elasticsearch/env/Environment.java index 1f8cffc97f3..143ddf69901 100644 --- a/core/src/main/java/org/elasticsearch/env/Environment.java +++ b/core/src/main/java/org/elasticsearch/env/Environment.java @@ -23,6 +23,7 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.io.IOException; @@ -46,15 +47,18 @@ import static org.elasticsearch.common.Strings.cleanPath; // TODO: move PathUtils to be package-private here instead of // public+forbidden api! public class Environment { - public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", false, Setting.Scope.CLUSTER); - public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", false, Setting.Scope.CLUSTER); - public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", false, Setting.Scope.CLUSTER); - public static final Setting> PATH_DATA_SETTING = Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", false, Setting.Scope.CLUSTER); - public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", false, Setting.Scope.CLUSTER); - public static final Setting> PATH_REPO_SETTING = Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting PATH_SHARED_DATA_SETTING = Setting.simpleString("path.shared_data", false, Setting.Scope.CLUSTER); - public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", false, Setting.Scope.CLUSTER); + public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", false, SettingsProperty.ClusterScope); + public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", false, SettingsProperty.ClusterScope); + public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", false, SettingsProperty.ClusterScope); + public static final Setting> PATH_DATA_SETTING = + Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", false, SettingsProperty.ClusterScope); + public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", false, SettingsProperty.ClusterScope); + public static final Setting> PATH_REPO_SETTING = + Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting PATH_SHARED_DATA_SETTING = + Setting.simpleString("path.shared_data", false, SettingsProperty.ClusterScope); + public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", false, SettingsProperty.ClusterScope); private final Settings settings; diff --git a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java index 5eecafa252f..f6d64b3406b 100644 --- a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java +++ b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java @@ -36,7 +36,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -136,19 +136,19 @@ public class NodeEnvironment extends AbstractComponent implements Closeable { * Maximum number of data nodes that should run in an environment. */ public static final Setting MAX_LOCAL_STORAGE_NODES_SETTING = Setting.intSetting("node.max_local_storage_nodes", 50, 1, false, - Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * If true automatically append node id to custom data paths. */ public static final Setting ADD_NODE_ID_TO_CUSTOM_PATH = Setting.boolSetting("node.add_id_to_custom_path", true, false, - Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * If true the [verbose] SegmentInfos.infoStream logging is sent to System.out. */ public static final Setting ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING = Setting - .boolSetting("node.enable_lucene_segment_infos_trace", false, false, Scope.CLUSTER); + .boolSetting("node.enable_lucene_segment_infos_trace", false, false, SettingsProperty.ClusterScope); public static final String NODES_FOLDER = "nodes"; public static final String INDICES_FOLDER = "indices"; diff --git a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java index 43b22d6c0bb..8c17325c08c 100644 --- a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java +++ b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java @@ -37,6 +37,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.Discovery; @@ -52,20 +53,20 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener { - public static final Setting EXPECTED_NODES_SETTING = Setting.intSetting( - "gateway.expected_nodes", -1, -1, false, Setting.Scope.CLUSTER); - public static final Setting EXPECTED_DATA_NODES_SETTING = Setting.intSetting( - "gateway.expected_data_nodes", -1, -1, false, Setting.Scope.CLUSTER); - public static final Setting EXPECTED_MASTER_NODES_SETTING = Setting.intSetting( - "gateway.expected_master_nodes", -1, -1, false, Setting.Scope.CLUSTER); - public static final Setting RECOVER_AFTER_TIME_SETTING = Setting.positiveTimeSetting( - "gateway.recover_after_time", TimeValue.timeValueMillis(0), false, Setting.Scope.CLUSTER); - public static final Setting RECOVER_AFTER_NODES_SETTING = Setting.intSetting( - "gateway.recover_after_nodes", -1, -1, false, Setting.Scope.CLUSTER); - public static final Setting RECOVER_AFTER_DATA_NODES_SETTING = Setting.intSetting( - "gateway.recover_after_data_nodes", -1, -1, false, Setting.Scope.CLUSTER); - public static final Setting RECOVER_AFTER_MASTER_NODES_SETTING = Setting.intSetting( - "gateway.recover_after_master_nodes", 0, 0, false, Setting.Scope.CLUSTER); + public static final Setting EXPECTED_NODES_SETTING = + Setting.intSetting("gateway.expected_nodes", -1, -1, false, SettingsProperty.ClusterScope); + public static final Setting EXPECTED_DATA_NODES_SETTING = + Setting.intSetting("gateway.expected_data_nodes", -1, -1, false, SettingsProperty.ClusterScope); + public static final Setting EXPECTED_MASTER_NODES_SETTING = + Setting.intSetting("gateway.expected_master_nodes", -1, -1, false, SettingsProperty.ClusterScope); + public static final Setting RECOVER_AFTER_TIME_SETTING = + Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); + public static final Setting RECOVER_AFTER_NODES_SETTING = + Setting.intSetting("gateway.recover_after_nodes", -1, -1, false, SettingsProperty.ClusterScope); + public static final Setting RECOVER_AFTER_DATA_NODES_SETTING = + Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, false, SettingsProperty.ClusterScope); + public static final Setting RECOVER_AFTER_MASTER_NODES_SETTING = + Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, false, SettingsProperty.ClusterScope); public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); diff --git a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java index 8809f68853b..018262c0304 100644 --- a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java @@ -31,6 +31,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.gateway.TransportNodesListGatewayStartedShards.NodeGatewayStartedShards; import org.elasticsearch.index.shard.ShardStateMetaData; @@ -67,9 +68,13 @@ public abstract class PrimaryShardAllocator extends AbstractComponent { } }; - public static final Setting NODE_INITIAL_SHARDS_SETTING = new Setting<>("gateway.initial_shards", (settings) -> settings.get("gateway.local.initial_shards", "quorum"), INITIAL_SHARDS_PARSER, true, Setting.Scope.CLUSTER); + public static final Setting NODE_INITIAL_SHARDS_SETTING = + new Setting<>("gateway.initial_shards", (settings) -> settings.get("gateway.local.initial_shards", "quorum"), INITIAL_SHARDS_PARSER, + true, SettingsProperty.ClusterScope); @Deprecated - public static final Setting INDEX_RECOVERY_INITIAL_SHARDS_SETTING = new Setting<>("index.recovery.initial_shards", (settings) -> NODE_INITIAL_SHARDS_SETTING.get(settings) , INITIAL_SHARDS_PARSER, true, Setting.Scope.INDEX); + public static final Setting INDEX_RECOVERY_INITIAL_SHARDS_SETTING = + new Setting<>("index.recovery.initial_shards", (settings) -> NODE_INITIAL_SHARDS_SETTING.get(settings) , INITIAL_SHARDS_PARSER, true, + SettingsProperty.IndexScope); public PrimaryShardAllocator(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java index 0e362615f0c..2332d8704e6 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java +++ b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java @@ -20,7 +20,7 @@ package org.elasticsearch.http; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.transport.PortsRange; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -32,30 +32,51 @@ import static org.elasticsearch.common.settings.Setting.listSetting; public final class HttpTransportSettings { - public static final Setting SETTING_CORS_ENABLED = Setting.boolSetting("http.cors.enabled", false, false, Scope.CLUSTER); - public static final Setting SETTING_CORS_ALLOW_ORIGIN = new Setting("http.cors.allow-origin", "", (value) -> value, false, Scope.CLUSTER); - public static final Setting SETTING_CORS_MAX_AGE = Setting.intSetting("http.cors.max-age", 1728000, false, Scope.CLUSTER); - public static final Setting SETTING_CORS_ALLOW_METHODS = new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, false, Scope.CLUSTER); - public static final Setting SETTING_CORS_ALLOW_HEADERS = new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, false, Scope.CLUSTER); - public static final Setting SETTING_CORS_ALLOW_CREDENTIALS = Setting.boolSetting("http.cors.allow-credentials", false, false, Scope.CLUSTER); - public static final Setting SETTING_PIPELINING = Setting.boolSetting("http.pipelining", true, false, Scope.CLUSTER); - public static final Setting SETTING_PIPELINING_MAX_EVENTS = Setting.intSetting("http.pipelining.max_events", 10000, false, Scope.CLUSTER); - public static final Setting SETTING_HTTP_COMPRESSION = Setting.boolSetting("http.compression", false, false, Scope.CLUSTER); - public static final Setting SETTING_HTTP_COMPRESSION_LEVEL = Setting.intSetting("http.compression_level", 6, false, Scope.CLUSTER); - public static final Setting> SETTING_HTTP_HOST = listSetting("http.host", emptyList(), s -> s, false, Scope.CLUSTER); - public static final Setting> SETTING_HTTP_PUBLISH_HOST = listSetting("http.publish_host", SETTING_HTTP_HOST, s -> s, false, Scope.CLUSTER); - public static final Setting> SETTING_HTTP_BIND_HOST = listSetting("http.bind_host", SETTING_HTTP_HOST, s -> s, false, Scope.CLUSTER); + public static final Setting SETTING_CORS_ENABLED = + Setting.boolSetting("http.cors.enabled", false, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_CORS_ALLOW_ORIGIN = + new Setting("http.cors.allow-origin", "", (value) -> value, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_CORS_MAX_AGE = + Setting.intSetting("http.cors.max-age", 1728000, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_CORS_ALLOW_METHODS = + new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_CORS_ALLOW_HEADERS = + new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_CORS_ALLOW_CREDENTIALS = + Setting.boolSetting("http.cors.allow-credentials", false, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_PIPELINING = + Setting.boolSetting("http.pipelining", true, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_PIPELINING_MAX_EVENTS = + Setting.intSetting("http.pipelining.max_events", 10000, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_COMPRESSION = + Setting.boolSetting("http.compression", false, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_COMPRESSION_LEVEL = + Setting.intSetting("http.compression_level", 6, false, SettingsProperty.ClusterScope); + public static final Setting> SETTING_HTTP_HOST = + listSetting("http.host", emptyList(), s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> SETTING_HTTP_PUBLISH_HOST = + listSetting("http.publish_host", SETTING_HTTP_HOST, s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> SETTING_HTTP_BIND_HOST = + listSetting("http.bind_host", SETTING_HTTP_HOST, s -> s, false, SettingsProperty.ClusterScope); - public static final Setting SETTING_HTTP_PORT = new Setting("http.port", "9200-9300", PortsRange::new, false, Scope.CLUSTER); - public static final Setting SETTING_HTTP_PUBLISH_PORT = Setting.intSetting("http.publish_port", 0, 0, false, Scope.CLUSTER); - public static final Setting SETTING_HTTP_DETAILED_ERRORS_ENABLED = Setting.boolSetting("http.detailed_errors.enabled", true, false, Scope.CLUSTER); - public static final Setting SETTING_HTTP_MAX_CONTENT_LENGTH = Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), false, Scope.CLUSTER) ; - public static final Setting SETTING_HTTP_MAX_CHUNK_SIZE = Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, Scope.CLUSTER) ; - public static final Setting SETTING_HTTP_MAX_HEADER_SIZE = Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, Scope.CLUSTER) ; - public static final Setting SETTING_HTTP_MAX_INITIAL_LINE_LENGTH = Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), false, Scope.CLUSTER) ; + public static final Setting SETTING_HTTP_PORT = + new Setting("http.port", "9200-9300", PortsRange::new, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_PUBLISH_PORT = + Setting.intSetting("http.publish_port", 0, 0, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_DETAILED_ERRORS_ENABLED = + Setting.boolSetting("http.detailed_errors.enabled", true, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_MAX_CONTENT_LENGTH = + Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_MAX_CHUNK_SIZE = + Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_MAX_HEADER_SIZE = + Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_MAX_INITIAL_LINE_LENGTH = + Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); // don't reset cookies by default, since I don't think we really need to // note, parsing cookies was fixed in netty 3.5.1 regarding stack allocation, but still, currently, we don't need cookies - public static final Setting SETTING_HTTP_RESET_COOKIES = Setting.boolSetting("http.reset_cookies", false, false, Scope.CLUSTER); + public static final Setting SETTING_HTTP_RESET_COOKIES = + Setting.boolSetting("http.reset_cookies", false, false, SettingsProperty.ClusterScope); private HttpTransportSettings() { } diff --git a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java index 79927c27632..f021ea812f9 100644 --- a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java +++ b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java @@ -27,6 +27,7 @@ import org.elasticsearch.common.netty.OpenChannelsHandler; import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -116,33 +117,32 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_MAX_CUMULATION_BUFFER_CAPACITY = - Setting.byteSizeSetting("http.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); + Setting.byteSizeSetting("http.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, + SettingsProperty.ClusterScope); public static Setting SETTING_HTTP_NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = - Setting.intSetting("http.netty.max_composite_buffer_components", -1, false, Setting.Scope.CLUSTER); + Setting.intSetting("http.netty.max_composite_buffer_components", -1, false, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_WORKER_COUNT = new Setting<>("http.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), false, Setting.Scope.CLUSTER); + (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), false, SettingsProperty.ClusterScope); - public static final Setting SETTING_HTTP_TCP_NO_DELAY = boolSetting("http.tcp_no_delay", NetworkService.TcpSettings - .TCP_NO_DELAY, false, - Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_TCP_KEEP_ALIVE = boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings - .TCP_KEEP_ALIVE, false, - Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_TCP_BLOCKING_SERVER = boolSetting("http.tcp.blocking_server", NetworkService - .TcpSettings.TCP_BLOCKING_SERVER, - false, Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_TCP_REUSE_ADDRESS = boolSetting("http.tcp.reuse_address", NetworkService - .TcpSettings.TCP_REUSE_ADDRESS, - false, Setting.Scope.CLUSTER); + public static final Setting SETTING_HTTP_TCP_NO_DELAY = + boolSetting("http.tcp_no_delay", NetworkService.TcpSettings.TCP_NO_DELAY, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_TCP_KEEP_ALIVE = + boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings.TCP_KEEP_ALIVE, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_TCP_BLOCKING_SERVER = + boolSetting("http.tcp.blocking_server", NetworkService.TcpSettings.TCP_BLOCKING_SERVER, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_TCP_REUSE_ADDRESS = + boolSetting("http.tcp.reuse_address", NetworkService.TcpSettings.TCP_REUSE_ADDRESS, false, SettingsProperty.ClusterScope); - public static final Setting SETTING_HTTP_TCP_SEND_BUFFER_SIZE = Setting.byteSizeSetting("http.tcp.send_buffer_size", - NetworkService.TcpSettings.TCP_SEND_BUFFER_SIZE, false, Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE = Setting.byteSizeSetting("http.tcp" + - ".receive_buffer_size", NetworkService.TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting( - "transport.netty.receive_predictor_size", + public static final Setting SETTING_HTTP_TCP_SEND_BUFFER_SIZE = + Setting.byteSizeSetting("http.tcp.send_buffer_size", NetworkService.TcpSettings.TCP_SEND_BUFFER_SIZE, false, + SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE = + Setting.byteSizeSetting("http.tcp.receive_buffer_size", NetworkService.TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, + SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE = + Setting.byteSizeSetting("transport.netty.receive_predictor_size", settings -> { long defaultReceiverPredictor = 512 * 1024; if (JvmInfo.jvmInfo().getMem().getDirectMemoryMax().bytes() > 0) { @@ -152,13 +152,13 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MIN = byteSizeSetting("http.netty" + - ".receive_predictor_min", - SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, Setting.Scope.CLUSTER); - public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MAX = byteSizeSetting("http.netty" + - ".receive_predictor_max", - SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, Setting.Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MIN = + byteSizeSetting("http.netty.receive_predictor_min", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, + SettingsProperty.ClusterScope); + public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MAX = + byteSizeSetting("http.netty.receive_predictor_max", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, + SettingsProperty.ClusterScope); protected final NetworkService networkService; diff --git a/core/src/main/java/org/elasticsearch/index/IndexModule.java b/core/src/main/java/org/elasticsearch/index/IndexModule.java index f9eb3ec2b54..3586e726a40 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexModule.java +++ b/core/src/main/java/org/elasticsearch/index/IndexModule.java @@ -22,6 +22,7 @@ package org.elasticsearch.index; import org.apache.lucene.util.SetOnce; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.index.analysis.AnalysisRegistry; @@ -65,13 +66,16 @@ import java.util.function.Function; */ public final class IndexModule { - public static final Setting INDEX_STORE_TYPE_SETTING = new Setting<>("index.store.type", "", Function.identity(), false, Setting.Scope.INDEX); + public static final Setting INDEX_STORE_TYPE_SETTING = + new Setting<>("index.store.type", "", Function.identity(), false, SettingsProperty.IndexScope); public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity"; public static final String INDEX_QUERY_CACHE = "index"; public static final String NONE_QUERY_CACHE = "none"; - public static final Setting INDEX_QUERY_CACHE_TYPE_SETTING = new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), false, Setting.Scope.INDEX); + public static final Setting INDEX_QUERY_CACHE_TYPE_SETTING = + new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), false, SettingsProperty.IndexScope); // for test purposes only - public static final Setting INDEX_QUERY_CACHE_EVERYTHING_SETTING = Setting.boolSetting("index.queries.cache.everything", false, false, Setting.Scope.INDEX); + public static final Setting INDEX_QUERY_CACHE_EVERYTHING_SETTING = + Setting.boolSetting("index.queries.cache.everything", false, false, SettingsProperty.IndexScope); private final IndexSettings indexSettings; private final IndexStoreConfig indexStoreConfig; private final AnalysisRegistry analysisRegistry; diff --git a/core/src/main/java/org/elasticsearch/index/IndexSettings.java b/core/src/main/java/org/elasticsearch/index/IndexSettings.java index b17b8ab7edf..dbf298e16f1 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/core/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -27,6 +27,7 @@ import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -36,7 +37,6 @@ import org.elasticsearch.index.translog.Translog; import java.util.Locale; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -50,15 +50,26 @@ import java.util.function.Predicate; */ public final class IndexSettings { - public static final Setting DEFAULT_FIELD_SETTING = new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), false, Setting.Scope.INDEX); - public static final Setting QUERY_STRING_LENIENT_SETTING = Setting.boolSetting("index.query_string.lenient", false, false, Setting.Scope.INDEX); - public static final Setting QUERY_STRING_ANALYZE_WILDCARD = Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, false, Setting.Scope.CLUSTER); - public static final Setting QUERY_STRING_ALLOW_LEADING_WILDCARD = Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, false, Setting.Scope.CLUSTER); - public static final Setting ALLOW_UNMAPPED = Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, false, Setting.Scope.INDEX); - public static final Setting INDEX_TRANSLOG_SYNC_INTERVAL_SETTING = Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), false, Setting.Scope.INDEX); - public static final Setting INDEX_TRANSLOG_DURABILITY_SETTING = new Setting<>("index.translog.durability", Translog.Durability.REQUEST.name(), (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), true, Setting.Scope.INDEX); - public static final Setting INDEX_WARMER_ENABLED_SETTING = Setting.boolSetting("index.warmer.enabled", true, true, Setting.Scope.INDEX); - public static final Setting INDEX_TTL_DISABLE_PURGE_SETTING = Setting.boolSetting("index.ttl.disable_purge", false, true, Setting.Scope.INDEX); + public static final Setting DEFAULT_FIELD_SETTING = + new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), false, SettingsProperty.IndexScope); + public static final Setting QUERY_STRING_LENIENT_SETTING = + Setting.boolSetting("index.query_string.lenient", false, false, SettingsProperty.IndexScope); + public static final Setting QUERY_STRING_ANALYZE_WILDCARD = + Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, false, SettingsProperty.ClusterScope); + public static final Setting QUERY_STRING_ALLOW_LEADING_WILDCARD = + Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, false, SettingsProperty.ClusterScope); + public static final Setting ALLOW_UNMAPPED = + Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, false, SettingsProperty.IndexScope); + public static final Setting INDEX_TRANSLOG_SYNC_INTERVAL_SETTING = + Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), false, + SettingsProperty.IndexScope); + public static final Setting INDEX_TRANSLOG_DURABILITY_SETTING = + new Setting<>("index.translog.durability", Translog.Durability.REQUEST.name(), + (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), true, SettingsProperty.IndexScope); + public static final Setting INDEX_WARMER_ENABLED_SETTING = + Setting.boolSetting("index.warmer.enabled", true, true, SettingsProperty.IndexScope); + public static final Setting INDEX_TTL_DISABLE_PURGE_SETTING = + Setting.boolSetting("index.ttl.disable_purge", false, true, SettingsProperty.IndexScope); public static final Setting INDEX_CHECK_ON_STARTUP = new Setting<>("index.shard.check_on_startup", "false", (s) -> { switch(s) { case "false": @@ -69,7 +80,7 @@ public final class IndexSettings { default: throw new IllegalArgumentException("unknown value for [index.shard.check_on_startup] must be one of [true, false, fix, checksum] but was: " + s); } - }, false, Setting.Scope.INDEX); + }, false, SettingsProperty.IndexScope); /** * Index setting describing the maximum value of from + size on a query. @@ -79,10 +90,15 @@ public final class IndexSettings { * safely. 1,000,000 is probably way to high for any cluster to set * safely. */ - public static final Setting MAX_RESULT_WINDOW_SETTING = Setting.intSetting("index.max_result_window", 10000, 1, true, Setting.Scope.INDEX); + public static final Setting MAX_RESULT_WINDOW_SETTING = + Setting.intSetting("index.max_result_window", 10000, 1, true, SettingsProperty.IndexScope); public static final TimeValue DEFAULT_REFRESH_INTERVAL = new TimeValue(1, TimeUnit.SECONDS); - public static final Setting INDEX_REFRESH_INTERVAL_SETTING = Setting.timeSetting("index.refresh_interval", DEFAULT_REFRESH_INTERVAL, new TimeValue(-1, TimeUnit.MILLISECONDS), true, Setting.Scope.INDEX); - public static final Setting INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING = Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), true, Setting.Scope.INDEX); + public static final Setting INDEX_REFRESH_INTERVAL_SETTING = + Setting.timeSetting("index.refresh_interval", DEFAULT_REFRESH_INTERVAL, new TimeValue(-1, TimeUnit.MILLISECONDS), true, + SettingsProperty.IndexScope); + public static final Setting INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING = + Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), true, + SettingsProperty.IndexScope); /** @@ -90,7 +106,9 @@ public final class IndexSettings { * This setting is realtime updateable */ public static final TimeValue DEFAULT_GC_DELETES = TimeValue.timeValueSeconds(60); - public static final Setting INDEX_GC_DELETES_SETTING = Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), true, Setting.Scope.INDEX); + public static final Setting INDEX_GC_DELETES_SETTING = + Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), true, + SettingsProperty.IndexScope); private final Index index; private final Version version; diff --git a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java index 9fabc8efc40..1b790240587 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java +++ b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java @@ -27,6 +27,7 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.NumericDocValues; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.engine.Engine; @@ -56,7 +57,7 @@ public final class IndexWarmer extends AbstractComponent { public static final Setting INDEX_NORMS_LOADING_SETTING = new Setting<>("index.norms.loading", MappedFieldType.Loading.LAZY.toString(), (s) -> MappedFieldType.Loading.parse(s, MappedFieldType.Loading.LAZY), - false, Setting.Scope.INDEX); + false, SettingsProperty.IndexScope); private final List listeners; IndexWarmer(Settings settings, ThreadPool threadPool, Listener... listeners) { diff --git a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java index 5452daa7f07..c66e05a6c79 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.index.engine.Engine; @@ -54,12 +55,23 @@ public final class IndexingSlowLog implements IndexingOperationListener { private final ESLogger deleteLogger; private static final String INDEX_INDEXING_SLOWLOG_PREFIX = "index.indexing.slowlog"; - public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.warn", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.info", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.debug", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.trace", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_INDEXING_SLOWLOG_REFORMAT_SETTING = Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, true, Setting.Scope.INDEX); - public static final Setting INDEX_INDEXING_SLOWLOG_LEVEL_SETTING = new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, Setting.Scope.INDEX); + public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING = + Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.warn", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING = + Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.info", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING = + Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.debug", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING = + Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.trace", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_INDEXING_SLOWLOG_REFORMAT_SETTING = + Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, true, SettingsProperty.IndexScope); + public static final Setting INDEX_INDEXING_SLOWLOG_LEVEL_SETTING = + new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, + SettingsProperty.IndexScope); /** * Reads how much of the source to log. The user can specify any value they * like and numbers are interpreted the maximum number of characters to log @@ -72,7 +84,7 @@ public final class IndexingSlowLog implements IndexingOperationListener { } catch (NumberFormatException e) { return Booleans.parseBoolean(value, true) ? Integer.MAX_VALUE : 0; } - }, true, Setting.Scope.INDEX); + }, true, SettingsProperty.IndexScope); IndexingSlowLog(IndexSettings indexSettings) { this(indexSettings, Loggers.getLogger(INDEX_INDEXING_SLOWLOG_PREFIX + ".index"), diff --git a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java index fc9f30cf3fd..5d2dc7e5bf2 100644 --- a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.TieredMergePolicy; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -126,15 +127,27 @@ public final class MergePolicyConfig { public static final ByteSizeValue DEFAULT_MAX_MERGED_SEGMENT = new ByteSizeValue(5, ByteSizeUnit.GB); public static final double DEFAULT_SEGMENTS_PER_TIER = 10.0d; public static final double DEFAULT_RECLAIM_DELETES_WEIGHT = 2.0d; - public static final Setting INDEX_COMPOUND_FORMAT_SETTING = new Setting<>("index.compound_format", Double.toString(TieredMergePolicy.DEFAULT_NO_CFS_RATIO), MergePolicyConfig::parseNoCFSRatio, true, Setting.Scope.INDEX); + public static final Setting INDEX_COMPOUND_FORMAT_SETTING = + new Setting<>("index.compound_format", Double.toString(TieredMergePolicy.DEFAULT_NO_CFS_RATIO), MergePolicyConfig::parseNoCFSRatio, + true, SettingsProperty.IndexScope); - public static final Setting INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED_SETTING = Setting.doubleSetting("index.merge.policy.expunge_deletes_allowed", DEFAULT_EXPUNGE_DELETES_ALLOWED, 0.0d, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING = Setting.byteSizeSetting("index.merge.policy.floor_segment", DEFAULT_FLOOR_SEGMENT, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_SETTING = Setting.intSetting("index.merge.policy.max_merge_at_once", DEFAULT_MAX_MERGE_AT_ONCE, 2, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT_SETTING = Setting.intSetting("index.merge.policy.max_merge_at_once_explicit", DEFAULT_MAX_MERGE_AT_ONCE_EXPLICIT, 2, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT_SETTING = Setting.byteSizeSetting("index.merge.policy.max_merged_segment", DEFAULT_MAX_MERGED_SEGMENT, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_SEGMENTS_PER_TIER_SETTING = Setting.doubleSetting("index.merge.policy.segments_per_tier", DEFAULT_SEGMENTS_PER_TIER, 2.0d, true, Setting.Scope.INDEX); - public static final Setting INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT_SETTING = Setting.doubleSetting("index.merge.policy.reclaim_deletes_weight", DEFAULT_RECLAIM_DELETES_WEIGHT, 0.0d, true, Setting.Scope.INDEX); + public static final Setting INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED_SETTING = + Setting.doubleSetting("index.merge.policy.expunge_deletes_allowed", DEFAULT_EXPUNGE_DELETES_ALLOWED, 0.0d, true, + SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING = + Setting.byteSizeSetting("index.merge.policy.floor_segment", DEFAULT_FLOOR_SEGMENT, true, SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_SETTING = + Setting.intSetting("index.merge.policy.max_merge_at_once", DEFAULT_MAX_MERGE_AT_ONCE, 2, true, SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT_SETTING = + Setting.intSetting("index.merge.policy.max_merge_at_once_explicit", DEFAULT_MAX_MERGE_AT_ONCE_EXPLICIT, 2, true, + SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT_SETTING = + Setting.byteSizeSetting("index.merge.policy.max_merged_segment", DEFAULT_MAX_MERGED_SEGMENT, true, SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_SEGMENTS_PER_TIER_SETTING = + Setting.doubleSetting("index.merge.policy.segments_per_tier", DEFAULT_SEGMENTS_PER_TIER, 2.0d, true, SettingsProperty.IndexScope); + public static final Setting INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT_SETTING = + Setting.doubleSetting("index.merge.policy.reclaim_deletes_weight", DEFAULT_RECLAIM_DELETES_WEIGHT, 0.0d, true, + SettingsProperty.IndexScope); public static final String INDEX_MERGE_ENABLED = "index.merge.enabled"; // don't convert to Setting<> and register... we only set this in tests and register via a plugin diff --git a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java index 0d212a4eb30..e53315c0249 100644 --- a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java @@ -21,6 +21,7 @@ package org.elasticsearch.index; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.util.concurrent.EsExecutors; /** @@ -51,9 +52,17 @@ import org.elasticsearch.common.util.concurrent.EsExecutors; */ public final class MergeSchedulerConfig { - public static final Setting MAX_THREAD_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_thread_count", (s) -> Integer.toString(Math.max(1, Math.min(4, EsExecutors.boundedNumberOfProcessors(s) / 2))), (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), true, Setting.Scope.INDEX); - public static final Setting MAX_MERGE_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_merge_count", (s) -> Integer.toString(MAX_THREAD_COUNT_SETTING.get(s) + 5), (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), true, Setting.Scope.INDEX); - public static final Setting AUTO_THROTTLE_SETTING = Setting.boolSetting("index.merge.scheduler.auto_throttle", true, true, Setting.Scope.INDEX); + public static final Setting MAX_THREAD_COUNT_SETTING = + new Setting<>("index.merge.scheduler.max_thread_count", + (s) -> Integer.toString(Math.max(1, Math.min(4, EsExecutors.boundedNumberOfProcessors(s) / 2))), + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), true, + SettingsProperty.IndexScope); + public static final Setting MAX_MERGE_COUNT_SETTING = + new Setting<>("index.merge.scheduler.max_merge_count", + (s) -> Integer.toString(MAX_THREAD_COUNT_SETTING.get(s) + 5), + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), true, SettingsProperty.IndexScope); + public static final Setting AUTO_THROTTLE_SETTING = + Setting.boolSetting("index.merge.scheduler.auto_throttle", true, true, SettingsProperty.IndexScope); private volatile boolean autoThrottle; private volatile int maxThreadCount; diff --git a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java index df3139fe57c..ae26eab2de1 100644 --- a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.search.internal.SearchContext; @@ -50,16 +51,35 @@ public final class SearchSlowLog { private final ESLogger fetchLogger; private static final String INDEX_SEARCH_SLOWLOG_PREFIX = "index.search.slowlog"; - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.warn", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.info", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.debug", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.trace", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.warn", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.info", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.debug", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.trace", TimeValue.timeValueNanos(-1), TimeValue.timeValueMillis(-1), true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_REFORMAT = Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, true, Setting.Scope.INDEX); - public static final Setting INDEX_SEARCH_SLOWLOG_LEVEL = new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, Setting.Scope.INDEX); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.warn", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.info", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.debug", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.trace", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.warn", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.info", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.debug", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING = + Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.trace", TimeValue.timeValueNanos(-1), + TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_REFORMAT = + Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, true, SettingsProperty.IndexScope); + public static final Setting INDEX_SEARCH_SLOWLOG_LEVEL = + new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, + SettingsProperty.IndexScope); public SearchSlowLog(IndexSettings indexSettings) { diff --git a/core/src/main/java/org/elasticsearch/index/analysis/NamedAnalyzer.java b/core/src/main/java/org/elasticsearch/index/analysis/NamedAnalyzer.java index 25ff8f96834..1dd562c4bb1 100644 --- a/core/src/main/java/org/elasticsearch/index/analysis/NamedAnalyzer.java +++ b/core/src/main/java/org/elasticsearch/index/analysis/NamedAnalyzer.java @@ -93,7 +93,7 @@ public class NamedAnalyzer extends DelegatingAnalyzerWrapper { public String toString() { return "analyzer name[" + name + "], analyzer [" + analyzer + "]"; } - + /** It is an error if this is ever used, it means we screwed up! */ static final ReuseStrategy ERROR_STRATEGY = new Analyzer.ReuseStrategy() { @Override diff --git a/core/src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java b/core/src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java index e90409421d2..77716e7a43d 100644 --- a/core/src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java +++ b/core/src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java @@ -56,4 +56,4 @@ public class NumericDoubleAnalyzer extends NumericAnalyzer protected NumericFloatTokenizer createNumericTokenizer(char[] buffer) throws IOException { return new NumericFloatTokenizer(precisionStep, buffer); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java b/core/src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java index ab112396392..9b865920341 100644 --- a/core/src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java +++ b/core/src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java @@ -56,4 +56,4 @@ public class NumericLongAnalyzer extends NumericAnalyzer { protected NumericLongTokenizer createNumericTokenizer(char[] buffer) throws IOException { return new NumericLongTokenizer(precisionStep, buffer); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java index 7d5540b6224..72435d90fd9 100644 --- a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java +++ b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java @@ -38,6 +38,7 @@ import org.elasticsearch.common.cache.RemovalListener; import org.elasticsearch.common.cache.RemovalNotification; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; @@ -70,7 +71,8 @@ import java.util.concurrent.Executor; */ public final class BitsetFilterCache extends AbstractIndexComponent implements LeafReader.CoreClosedListener, RemovalListener>, Closeable { - public static final Setting INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING = Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, false, Setting.Scope.INDEX); + public static final Setting INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING = + Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, false, SettingsProperty.IndexScope); private final boolean loadRandomAccessFiltersEagerly; private final Cache> loadedFilters; diff --git a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java index 9740ccd0358..47110c62bfb 100644 --- a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java +++ b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java @@ -26,6 +26,7 @@ import org.apache.lucene.search.QueryCache; import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.search.similarities.Similarity; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -83,7 +84,7 @@ public final class EngineConfig { } return s; } - }, false, Setting.Scope.INDEX); + }, false, SettingsProperty.IndexScope); /** if set to true the engine will start even if the translog id in the commit point can not be found */ public static final String INDEX_FORCE_NEW_TRANSLOG = "index.engine.force_new_translog"; diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index 78bdcb0f7f3..6d12de8c395 100644 --- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -24,6 +24,7 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.fielddata.plain.AbstractGeoPointDVIndexFieldData; @@ -66,7 +67,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo default: throw new IllegalArgumentException("failed to parse [" + s + "] must be one of [node,node]"); } - }, false, Setting.Scope.INDEX); + }, false, SettingsProperty.IndexScope); private static final IndexFieldData.Builder MISSING_DOC_VALUES_BUILDER = (indexProperties, fieldType, cache, breakerService, mapperService1) -> { throw new IllegalStateException("Can't load fielddata on [" + fieldType.name() diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index fd35398a9dc..9fba8c0529e 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.analysis.NamedAnalyzer; @@ -49,8 +50,10 @@ import java.util.Map; import java.util.stream.StreamSupport; public abstract class FieldMapper extends Mapper implements Cloneable { - public static final Setting IGNORE_MALFORMED_SETTING = Setting.boolSetting("index.mapping.ignore_malformed", false, false, Setting.Scope.INDEX); - public static final Setting COERCE_SETTING = Setting.boolSetting("index.mapping.coerce", false, false, Setting.Scope.INDEX); + public static final Setting IGNORE_MALFORMED_SETTING = + Setting.boolSetting("index.mapping.ignore_malformed", false, false, SettingsProperty.IndexScope); + public static final Setting COERCE_SETTING = + Setting.boolSetting("index.mapping.coerce", false, false, SettingsProperty.IndexScope); public abstract static class Builder extends Mapper.Builder { protected final MappedFieldType fieldType; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index b25f5f6a02d..c86219cc05a 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -27,6 +27,7 @@ import org.elasticsearch.ElasticsearchGenerationException; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.AnalysisService; @@ -81,9 +82,11 @@ public class MapperService extends AbstractIndexComponent implements Closeable { } public static final String DEFAULT_MAPPING = "_default_"; - public static final Setting INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING = Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, true, Setting.Scope.INDEX); + public static final Setting INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING = + Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, true, SettingsProperty.IndexScope); public static final boolean INDEX_MAPPER_DYNAMIC_DEFAULT = true; - public static final Setting INDEX_MAPPER_DYNAMIC_SETTING = Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, false, Setting.Scope.INDEX); + public static final Setting INDEX_MAPPER_DYNAMIC_SETTING = + Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, false, SettingsProperty.IndexScope); private static ObjectHashSet META_FIELDS = ObjectHashSet.from( "_uid", "_id", "_type", "_all", "_parent", "_routing", "_index", "_size", "_timestamp", "_ttl" diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java index 90fb20ef827..5f928043688 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java @@ -33,6 +33,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Explicit; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -52,7 +53,9 @@ import java.util.List; * */ public abstract class NumberFieldMapper extends FieldMapper implements AllFieldMapper.IncludeInAll { - private static final Setting COERCE_SETTING = Setting.boolSetting("index.mapping.coerce", true, false, Setting.Scope.INDEX); // this is private since it has a different default + // this is private since it has a different default + private static final Setting COERCE_SETTING = + Setting.boolSetting("index.mapping.coerce", true, false, SettingsProperty.IndexScope); public static class Defaults { diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java index 67ba0aaf1d2..62d5da92259 100644 --- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java +++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java @@ -31,6 +31,7 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.metrics.MeanMetric; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; @@ -61,7 +62,8 @@ import java.util.concurrent.TimeUnit; */ public final class PercolatorQueriesRegistry extends AbstractIndexShardComponent implements Closeable { - public final static Setting INDEX_MAP_UNMAPPED_FIELDS_AS_STRING_SETTING = Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, false, Setting.Scope.INDEX); + public final static Setting INDEX_MAP_UNMAPPED_FIELDS_AS_STRING_SETTING = + Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, false, SettingsProperty.IndexScope); private final ConcurrentMap percolateQueries = ConcurrentCollections.newConcurrentMapWithAggressiveConcurrency(); private final QueryShardContext queryShardContext; diff --git a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java index d5d6d5234be..914979eac05 100644 --- a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java +++ b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java @@ -34,6 +34,7 @@ import org.apache.lucene.util.Constants; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.index.IndexModule; @@ -60,7 +61,7 @@ public class FsDirectoryService extends DirectoryService implements StoreRateLim default: throw new IllegalArgumentException("unrecognized [index.store.fs.fs_lock] \"" + s + "\": must be native or simple"); } - }, false, Setting.Scope.INDEX); + }, false, SettingsProperty.IndexScope); private final CounterMetric rateLimitingTimeInNanos = new CounterMetric(); private final ShardPath path; diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java index e98ad7cc6eb..783ed980646 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java @@ -21,6 +21,7 @@ package org.elasticsearch.index.store; import org.apache.lucene.store.StoreRateLimiting; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; @@ -29,8 +30,10 @@ import org.elasticsearch.index.shard.ShardPath; * */ public class IndexStore extends AbstractIndexComponent { - public static final Setting INDEX_STORE_THROTTLE_TYPE_SETTING = new Setting<>("index.store.throttle.type", "none", IndexRateLimitingType::fromString, true, Setting.Scope.INDEX) ; - public static final Setting INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("index.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, Setting.Scope.INDEX); + public static final Setting INDEX_STORE_THROTTLE_TYPE_SETTING = + new Setting<>("index.store.throttle.type", "none", IndexRateLimitingType::fromString, true, SettingsProperty.IndexScope); + public static final Setting INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = + Setting.byteSizeSetting("index.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, SettingsProperty.IndexScope); protected final IndexStoreConfig indexStoreConfig; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java index ab7075afa5b..328d7604bcf 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java @@ -22,6 +22,7 @@ import org.apache.lucene.store.StoreRateLimiting; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; @@ -36,11 +37,14 @@ public class IndexStoreConfig { /** * Configures the node / cluster level throttle type. See {@link StoreRateLimiting.Type}. */ - public static final Setting INDICES_STORE_THROTTLE_TYPE_SETTING = new Setting<>("indices.store.throttle.type", StoreRateLimiting.Type.NONE.name(),StoreRateLimiting.Type::fromString, true, Setting.Scope.CLUSTER); + public static final Setting INDICES_STORE_THROTTLE_TYPE_SETTING = + new Setting<>("indices.store.throttle.type", StoreRateLimiting.Type.NONE.name(),StoreRateLimiting.Type::fromString, true, + SettingsProperty.ClusterScope); /** * Configures the node / cluster level throttle intensity. The default is 10240 MB */ - public static final Setting INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("indices.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = + Setting.byteSizeSetting("indices.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, SettingsProperty.ClusterScope); private volatile StoreRateLimiting.Type rateLimitingType; private volatile ByteSizeValue rateLimitingThrottle; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/Store.java b/core/src/main/java/org/elasticsearch/index/store/Store.java index c7377a4ab6b..b1d806d520e 100644 --- a/core/src/main/java/org/elasticsearch/index/store/Store.java +++ b/core/src/main/java/org/elasticsearch/index/store/Store.java @@ -62,6 +62,7 @@ import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.store.ByteArrayIndexInput; import org.elasticsearch.common.lucene.store.InputStreamIndexInput; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.Callback; @@ -129,7 +130,8 @@ public class Store extends AbstractIndexShardComponent implements Closeable, Ref static final int VERSION_START = 0; static final int VERSION = VERSION_WRITE_THROWABLE; static final String CORRUPTED = "corrupted_"; - public static final Setting INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING = Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), false, Setting.Scope.INDEX); + public static final Setting INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING = + Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), false, SettingsProperty.IndexScope); private final AtomicBoolean isClosed = new AtomicBoolean(false); private final StoreDirectory directory; diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java index 926ff482248..15eb19fc416 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java @@ -30,10 +30,9 @@ import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Weight; import org.elasticsearch.common.component.AbstractComponent; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.ShardCoreKeyMap; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.cache.query.QueryCacheStats; @@ -50,9 +49,9 @@ import java.util.concurrent.ConcurrentHashMap; public class IndicesQueryCache extends AbstractComponent implements QueryCache, Closeable { public static final Setting INDICES_CACHE_QUERY_SIZE_SETTING = Setting.byteSizeSetting( - "indices.queries.cache.size", "10%", false, Scope.CLUSTER); + "indices.queries.cache.size", "10%", false, SettingsProperty.ClusterScope); public static final Setting INDICES_CACHE_QUERY_COUNT_SETTING = Setting.intSetting( - "indices.queries.cache.count", 10000, 1, false, Scope.CLUSTER); + "indices.queries.cache.count", 10000, 1, false, SettingsProperty.ClusterScope); private final LRUQueryCache cache; private final ShardCoreKeyMap shardKeyMap = new ShardCoreKeyMap(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java index 575153c8ada..8ebe52a2c19 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java @@ -34,6 +34,7 @@ import org.elasticsearch.common.cache.RemovalNotification; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -68,12 +69,12 @@ public final class IndicesRequestCache extends AbstractComponent implements Remo * A setting to enable or disable request caching on an index level. Its dynamic by default * since we are checking on the cluster state IndexMetaData always. */ - public static final Setting INDEX_CACHE_REQUEST_ENABLED_SETTING = Setting.boolSetting("index.requests.cache.enable", - false, true, Setting.Scope.INDEX); - public static final Setting INDICES_CACHE_QUERY_SIZE = Setting.byteSizeSetting("indices.requests.cache.size", "1%", - false, Setting.Scope.CLUSTER); - public static final Setting INDICES_CACHE_QUERY_EXPIRE = Setting.positiveTimeSetting("indices.requests.cache.expire", - new TimeValue(0), false, Setting.Scope.CLUSTER); + public static final Setting INDEX_CACHE_REQUEST_ENABLED_SETTING = + Setting.boolSetting("index.requests.cache.enable", false, true, SettingsProperty.IndexScope); + public static final Setting INDICES_CACHE_QUERY_SIZE = + Setting.byteSizeSetting("indices.requests.cache.size", "1%", false, SettingsProperty.ClusterScope); + public static final Setting INDICES_CACHE_QUERY_EXPIRE = + Setting.positiveTimeSetting("indices.requests.cache.expire", new TimeValue(0), false, SettingsProperty.ClusterScope); private final ConcurrentMap registeredClosedListeners = ConcurrentCollections.newConcurrentMap(); private final Set keysToClean = ConcurrentCollections.newConcurrentSet(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesService.java b/core/src/main/java/org/elasticsearch/indices/IndicesService.java index c7d1be4bf71..d64bb3f0c4c 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesService.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesService.java @@ -47,6 +47,7 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -115,7 +116,8 @@ import static org.elasticsearch.common.util.CollectionUtils.arrayAsArrayList; public class IndicesService extends AbstractLifecycleComponent implements Iterable, IndexService.ShardStoreDeleter { public static final String INDICES_SHARDS_CLOSED_TIMEOUT = "indices.shards_closed_timeout"; - public static final Setting INDICES_CACHE_CLEAN_INTERVAL_SETTING = Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), false, Setting.Scope.CLUSTER); + public static final Setting INDICES_CACHE_CLEAN_INTERVAL_SETTING = + Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), false, SettingsProperty.ClusterScope); private final PluginsService pluginsService; private final NodeEnvironment nodeEnv; private final TimeValue shardsClosedTimeout; diff --git a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java index f99b39ef620..3b7b9782849 100644 --- a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java +++ b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java @@ -24,6 +24,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; @@ -71,9 +72,12 @@ import java.util.function.Function; */ public class HunspellService extends AbstractComponent { - public final static Setting HUNSPELL_LAZY_LOAD = Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, false, Setting.Scope.CLUSTER); - public final static Setting HUNSPELL_IGNORE_CASE = Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, false, Setting.Scope.CLUSTER); - public final static Setting HUNSPELL_DICTIONARY_OPTIONS = Setting.groupSetting("indices.analysis.hunspell.dictionary.", false, Setting.Scope.CLUSTER); + public final static Setting HUNSPELL_LAZY_LOAD = + Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, false, SettingsProperty.ClusterScope); + public final static Setting HUNSPELL_IGNORE_CASE = + Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, false, SettingsProperty.ClusterScope); + public final static Setting HUNSPELL_DICTIONARY_OPTIONS = + Setting.groupSetting("indices.analysis.hunspell.dictionary.", false, SettingsProperty.ClusterScope); private final ConcurrentHashMap dictionaries = new ConcurrentHashMap<>(); private final Map knownDictionaries; private final boolean defaultIgnoreCase; diff --git a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java index 0e1532bc6b3..fdee0b03343 100644 --- a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java +++ b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java @@ -27,6 +27,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; @@ -46,15 +47,22 @@ public class HierarchyCircuitBreakerService extends CircuitBreakerService { private final ConcurrentMap breakers = new ConcurrentHashMap(); - public static final Setting TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING = Setting.byteSizeSetting("indices.breaker.total.limit", "70%", true, Setting.Scope.CLUSTER); + public static final Setting TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING = + Setting.byteSizeSetting("indices.breaker.total.limit", "70%", true, SettingsProperty.ClusterScope); - public static final Setting FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING = Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", true, Setting.Scope.CLUSTER); - public static final Setting FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING = Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, true, Setting.Scope.CLUSTER); - public static final Setting FIELDDATA_CIRCUIT_BREAKER_TYPE_SETTING = new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, false, Setting.Scope.CLUSTER); + public static final Setting FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING = + Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", true, SettingsProperty.ClusterScope); + public static final Setting FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING = + Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, true, SettingsProperty.ClusterScope); + public static final Setting FIELDDATA_CIRCUIT_BREAKER_TYPE_SETTING = + new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, false, SettingsProperty.ClusterScope); - public static final Setting REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING = Setting.byteSizeSetting("indices.breaker.request.limit", "40%", true, Setting.Scope.CLUSTER); - public static final Setting REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING = Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, true, Setting.Scope.CLUSTER); - public static final Setting REQUEST_CIRCUIT_BREAKER_TYPE_SETTING = new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, false, Setting.Scope.CLUSTER); + public static final Setting REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING = + Setting.byteSizeSetting("indices.breaker.request.limit", "40%", true, SettingsProperty.ClusterScope); + public static final Setting REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING = + Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, true, SettingsProperty.ClusterScope); + public static final Setting REQUEST_CIRCUIT_BREAKER_TYPE_SETTING = + new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, false, SettingsProperty.ClusterScope); diff --git a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java index 0a3f063dfcc..dd60c628223 100644 --- a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java +++ b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java @@ -34,6 +34,7 @@ import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.Index; @@ -52,7 +53,8 @@ import java.util.function.ToLongBiFunction; */ public class IndicesFieldDataCache extends AbstractComponent implements RemovalListener, Releasable{ - public static final Setting INDICES_FIELDDATA_CACHE_SIZE_KEY = Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); + public static final Setting INDICES_FIELDDATA_CACHE_SIZE_KEY = + Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); private final IndexFieldDataCache.Listener indicesFieldDataCacheListener; private final Cache cache; diff --git a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java index 8d610dce05b..742b1b78945 100644 --- a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java +++ b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -32,31 +33,45 @@ import org.elasticsearch.common.unit.TimeValue; public class RecoverySettings extends AbstractComponent { - public static final Setting INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("indices.recovery.max_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING = + Setting.byteSizeSetting("indices.recovery.max_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB), true, + SettingsProperty.ClusterScope); /** * how long to wait before retrying after issues cause by cluster state syncing between nodes * i.e., local node is not yet known on remote node, remote shard not yet started etc. */ - public static final Setting INDICES_RECOVERY_RETRY_DELAY_STATE_SYNC_SETTING = Setting.positiveTimeSetting("indices.recovery.retry_delay_state_sync", TimeValue.timeValueMillis(500), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_RETRY_DELAY_STATE_SYNC_SETTING = + Setting.positiveTimeSetting("indices.recovery.retry_delay_state_sync", TimeValue.timeValueMillis(500), true, + SettingsProperty.ClusterScope); /** how long to wait before retrying after network related issues */ - public static final Setting INDICES_RECOVERY_RETRY_DELAY_NETWORK_SETTING = Setting.positiveTimeSetting("indices.recovery.retry_delay_network", TimeValue.timeValueSeconds(5), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_RETRY_DELAY_NETWORK_SETTING = + Setting.positiveTimeSetting("indices.recovery.retry_delay_network", TimeValue.timeValueSeconds(5), true, + SettingsProperty.ClusterScope); /** timeout value to use for requests made as part of the recovery process */ - public static final Setting INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING = Setting.positiveTimeSetting("indices.recovery.internal_action_timeout", TimeValue.timeValueMinutes(15), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING = + Setting.positiveTimeSetting("indices.recovery.internal_action_timeout", TimeValue.timeValueMinutes(15), true, + SettingsProperty.ClusterScope); /** * timeout value to use for requests made as part of the recovery process that are expected to take long time. * defaults to twice `indices.recovery.internal_action_timeout`. */ - public static final Setting INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.internal_action_long_timeout", (s) -> TimeValue.timeValueMillis(INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING.get(s).millis() * 2).toString(), TimeValue.timeValueSeconds(0), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING = + Setting.timeSetting("indices.recovery.internal_action_long_timeout", + (s) -> TimeValue.timeValueMillis(INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING.get(s).millis() * 2).toString(), + TimeValue.timeValueSeconds(0), true, SettingsProperty.ClusterScope); /** * recoveries that don't show any activity for more then this interval will be failed. * defaults to `indices.recovery.internal_action_long_timeout` */ - public static final Setting INDICES_RECOVERY_ACTIVITY_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.recovery_activity_timeout", (s) -> INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING.getRaw(s) , TimeValue.timeValueSeconds(0), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_RECOVERY_ACTIVITY_TIMEOUT_SETTING = + Setting.timeSetting("indices.recovery.recovery_activity_timeout", + (s) -> INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING.getRaw(s) , TimeValue.timeValueSeconds(0), true, + SettingsProperty.ClusterScope); public static final ByteSizeValue DEFAULT_CHUNK_SIZE = new ByteSizeValue(512, ByteSizeUnit.KB); diff --git a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java index d0aec817ee9..23e007c5366 100644 --- a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java +++ b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java @@ -36,6 +36,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; @@ -69,7 +70,9 @@ import java.util.concurrent.atomic.AtomicInteger; public class IndicesStore extends AbstractComponent implements ClusterStateListener, Closeable { // TODO this class can be foled into either IndicesService and partially into IndicesClusterStateService there is no need for a separate public service - public static final Setting INDICES_STORE_DELETE_SHARD_TIMEOUT = Setting.positiveTimeSetting("indices.store.delete.shard.timeout", new TimeValue(30, TimeUnit.SECONDS), false, Setting.Scope.CLUSTER); + public static final Setting INDICES_STORE_DELETE_SHARD_TIMEOUT = + Setting.positiveTimeSetting("indices.store.delete.shard.timeout", new TimeValue(30, TimeUnit.SECONDS), false, + SettingsProperty.ClusterScope); public static final String ACTION_SHARD_EXISTS = "internal:index/shard/exists"; private static final EnumSet ACTIVE_STATES = EnumSet.of(IndexShardState.STARTED, IndexShardState.RELOCATED); private final IndicesService indicesService; diff --git a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java index e4537b876fa..6eb34adc9f8 100644 --- a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java +++ b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java @@ -38,6 +38,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -67,7 +68,8 @@ import java.util.concurrent.locks.ReentrantLock; */ public class IndicesTTLService extends AbstractLifecycleComponent { - public static final Setting INDICES_TTL_INTERVAL_SETTING = Setting.positiveTimeSetting("indices.ttl.interval", TimeValue.timeValueSeconds(60), true, Setting.Scope.CLUSTER); + public static final Setting INDICES_TTL_INTERVAL_SETTING = + Setting.positiveTimeSetting("indices.ttl.interval", TimeValue.timeValueSeconds(60), true, SettingsProperty.ClusterScope); private final ClusterService clusterService; private final IndicesService indicesService; diff --git a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java index 99a78f13a07..be985cb7020 100644 --- a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java @@ -21,6 +21,7 @@ package org.elasticsearch.monitor.fs; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -37,7 +38,8 @@ public class FsService extends AbstractComponent { private final SingleObjectCache fsStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.fs.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Setting.Scope.CLUSTER); + Setting.timeSetting("monitor.fs.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + SettingsProperty.ClusterScope); public FsService(Settings settings, NodeEnvironment nodeEnvironment) throws IOException { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java index 97c813a0fe3..03c6c00d539 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.jvm; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.FutureUtils; @@ -47,12 +47,14 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent ENABLED_SETTING = Setting.boolSetting("monitor.jvm.gc.enabled", true, false, Scope.CLUSTER); + public final static Setting ENABLED_SETTING = + Setting.boolSetting("monitor.jvm.gc.enabled", true, false, SettingsProperty.ClusterScope); public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Scope.CLUSTER); + Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + SettingsProperty.ClusterScope); private static String GC_COLLECTOR_PREFIX = "monitor.jvm.gc.collector."; - public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, false, Scope.CLUSTER); + public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, false, SettingsProperty.ClusterScope); static class GcThreshold { public final String name; diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java index fbec6cda168..e816e51911e 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java @@ -21,6 +21,7 @@ package org.elasticsearch.monitor.jvm; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -36,7 +37,8 @@ public class JvmService extends AbstractComponent { private JvmStats jvmStats; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.jvm.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Setting.Scope.CLUSTER); + Setting.timeSetting("monitor.jvm.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + SettingsProperty.ClusterScope); public JvmService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java index 5f836c6f928..1cd0910ab3e 100644 --- a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java @@ -21,6 +21,7 @@ package org.elasticsearch.monitor.os; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -38,7 +39,8 @@ public class OsService extends AbstractComponent { private SingleObjectCache osStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.os.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Setting.Scope.CLUSTER); + Setting.timeSetting("monitor.os.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + SettingsProperty.ClusterScope); public OsService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java index 9e3283af4fc..316c8a8131f 100644 --- a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java +++ b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java @@ -21,6 +21,7 @@ package org.elasticsearch.monitor.process; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -35,7 +36,8 @@ public final class ProcessService extends AbstractComponent { private final SingleObjectCache processStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.process.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Setting.Scope.CLUSTER); + Setting.timeSetting("monitor.process.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + SettingsProperty.ClusterScope); public ProcessService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index ee523e975a1..4b0c806749f 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -49,6 +49,7 @@ import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.settings.SettingsModule; @@ -124,17 +125,23 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder; */ public class Node implements Closeable { - public static final Setting WRITE_PORTS_FIELD_SETTING = Setting.boolSetting("node.portsfile", false, false, Setting.Scope.CLUSTER); - public static final Setting NODE_CLIENT_SETTING = Setting.boolSetting("node.client", false, false, Setting.Scope.CLUSTER); - public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, false, Setting.Scope.CLUSTER); - public static final Setting NODE_MASTER_SETTING = Setting.boolSetting("node.master", true, false, Setting.Scope.CLUSTER); - public static final Setting NODE_LOCAL_SETTING = Setting.boolSetting("node.local", false, false, Setting.Scope.CLUSTER); - public static final Setting NODE_MODE_SETTING = new Setting<>("node.mode", "network", Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting NODE_INGEST_SETTING = Setting.boolSetting("node.ingest", true, false, Setting.Scope.CLUSTER); - public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", false, Setting.Scope.CLUSTER); + public static final Setting WRITE_PORTS_FIELD_SETTING = + Setting.boolSetting("node.portsfile", false, false, SettingsProperty.ClusterScope); + public static final Setting NODE_CLIENT_SETTING = + Setting.boolSetting("node.client", false, false, SettingsProperty.ClusterScope); + public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, false, SettingsProperty.ClusterScope); + public static final Setting NODE_MASTER_SETTING = + Setting.boolSetting("node.master", true, false, SettingsProperty.ClusterScope); + public static final Setting NODE_LOCAL_SETTING = + Setting.boolSetting("node.local", false, false, SettingsProperty.ClusterScope); + public static final Setting NODE_MODE_SETTING = + new Setting<>("node.mode", "network", Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting NODE_INGEST_SETTING = + Setting.boolSetting("node.ingest", true, false, SettingsProperty.ClusterScope); + public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", false, SettingsProperty.ClusterScope); // this sucks that folks can mistype client etc and get away with it. // TODO: we should move this to node.attribute.${name} = ${value} instead. - public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", false, Setting.Scope.CLUSTER); + public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", false, SettingsProperty.ClusterScope); private static final String CLIENT_TYPE = "node"; diff --git a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java index faf449586c1..45fd66d6daa 100644 --- a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java +++ b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java @@ -26,6 +26,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.env.Environment; @@ -57,7 +58,8 @@ public class InternalSettingsPreparer { public static final String SECRET_PROMPT_VALUE = "${prompt.secret}"; public static final String TEXT_PROMPT_VALUE = "${prompt.text}"; - public static final Setting IGNORE_SYSTEM_PROPERTIES_SETTING = Setting.boolSetting("config.ignore_system_properties", false, false, Setting.Scope.CLUSTER); + public static final Setting IGNORE_SYSTEM_PROPERTIES_SETTING = + Setting.boolSetting("config.ignore_system_properties", false, false, SettingsProperty.ClusterScope); /** * Prepares the settings by gathering all elasticsearch system properties and setting defaults. diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index 3e36c5d8f09..1fb5875109e 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -37,6 +37,7 @@ import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexModule; @@ -71,7 +72,8 @@ public class PluginsService extends AbstractComponent { */ private final List> plugins; private final PluginsAndModules info; - public static final Setting> MANDATORY_SETTING = Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); + public static final Setting> MANDATORY_SETTING = + Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); private final Map> onModuleReferences; diff --git a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java index 0aa62225479..8b364105718 100644 --- a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.blobstore.fs.FsBlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -51,12 +52,17 @@ public class FsRepository extends BlobStoreRepository { public final static String TYPE = "fs"; - public static final Setting LOCATION_SETTING = new Setting<>("location", "", Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting REPOSITORIES_LOCATION_SETTING = new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", false, Setting.Scope.CLUSTER); - public static final Setting REPOSITORIES_CHUNK_SIZE_SETTING = Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", false, Setting.Scope.CLUSTER); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, Setting.Scope.CLUSTER); - public static final Setting REPOSITORIES_COMPRESS_SETTING = Setting.boolSetting("repositories.fs.compress", false, false, Setting.Scope.CLUSTER); + public static final Setting LOCATION_SETTING = + new Setting<>("location", "", Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting REPOSITORIES_LOCATION_SETTING = + new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting CHUNK_SIZE_SETTING = + Setting.byteSizeSetting("chunk_size", "-1", false, SettingsProperty.ClusterScope); + public static final Setting REPOSITORIES_CHUNK_SIZE_SETTING = + Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", false, SettingsProperty.ClusterScope); + public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); + public static final Setting REPOSITORIES_COMPRESS_SETTING = + Setting.boolSetting("repositories.fs.compress", false, false, SettingsProperty.ClusterScope); private final FsBlobStore blobStore; diff --git a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java index 2d15db245aa..c5255fd8b5e 100644 --- a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.blobstore.url.URLBlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.util.URIPattern; import org.elasticsearch.env.Environment; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -55,19 +56,24 @@ public class URLRepository extends BlobStoreRepository { public final static String TYPE = "url"; - public static final Setting> SUPPORTED_PROTOCOLS_SETTING = Setting.listSetting("repositories.url.supported_protocols", - Arrays.asList("http", "https", "ftp", "file", "jar"), Function.identity(), false, Setting.Scope.CLUSTER); + public static final Setting> SUPPORTED_PROTOCOLS_SETTING = + Setting.listSetting("repositories.url.supported_protocols", Arrays.asList("http", "https", "ftp", "file", "jar"), + Function.identity(), false, SettingsProperty.ClusterScope); - public static final Setting> ALLOWED_URLS_SETTING = Setting.listSetting("repositories.url.allowed_urls", - Collections.emptyList(), URIPattern::new, false, Setting.Scope.CLUSTER); + public static final Setting> ALLOWED_URLS_SETTING = + Setting.listSetting("repositories.url.allowed_urls", Collections.emptyList(), URIPattern::new, false, + SettingsProperty.ClusterScope); - public static final Setting URL_SETTING = new Setting<>("url", "http:", URLRepository::parseURL, false, Setting.Scope.CLUSTER); - public static final Setting REPOSITORIES_URL_SETTING = new Setting<>("repositories.url.url", (s) -> s.get("repositories.uri.url", "http:"), - URLRepository::parseURL, false, Setting.Scope.CLUSTER); + public static final Setting URL_SETTING = + new Setting<>("url", "http:", URLRepository::parseURL, false, SettingsProperty.ClusterScope); + public static final Setting REPOSITORIES_URL_SETTING = + new Setting<>("repositories.url.url", (s) -> s.get("repositories.uri.url", "http:"), URLRepository::parseURL, false, + SettingsProperty.ClusterScope); - public static final Setting LIST_DIRECTORIES_SETTING = Setting.boolSetting("list_directories", true, false, Setting.Scope.CLUSTER); - public static final Setting REPOSITORIES_LIST_DIRECTORIES_SETTING = Setting.boolSetting("repositories.uri.list_directories", true, - false, Setting.Scope.CLUSTER); + public static final Setting LIST_DIRECTORIES_SETTING = + Setting.boolSetting("list_directories", true, false, SettingsProperty.ClusterScope); + public static final Setting REPOSITORIES_LIST_DIRECTORIES_SETTING = + Setting.boolSetting("repositories.uri.list_directories", true, false, SettingsProperty.ClusterScope); private final List supportedProtocols; diff --git a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java index 60b3ccce930..1ea87c6c61e 100644 --- a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java +++ b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java @@ -23,6 +23,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; /** @@ -34,7 +35,8 @@ import org.elasticsearch.common.settings.Settings; * {@link org.elasticsearch.rest.RestController#registerRelevantHeaders(String...)} */ public abstract class BaseRestHandler extends AbstractComponent implements RestHandler { - public static final Setting MULTI_ALLOW_EXPLICIT_INDEX = Setting.boolSetting("rest.action.multi.allow_explicit_index", true, false, Setting.Scope.CLUSTER); + public static final Setting MULTI_ALLOW_EXPLICIT_INDEX = + Setting.boolSetting("rest.action.multi.allow_explicit_index", true, false, SettingsProperty.ClusterScope); private final Client client; protected final ParseFieldMatcher parseFieldMatcher; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index d21283d9cfa..058deadcf4c 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -46,6 +46,7 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; @@ -84,10 +85,13 @@ public class ScriptService extends AbstractComponent implements Closeable { static final String DISABLE_DYNAMIC_SCRIPTING_SETTING = "script.disable_dynamic"; - public static final Setting SCRIPT_CACHE_SIZE_SETTING = Setting.intSetting("script.cache.max_size", 100, 0, false, Setting.Scope.CLUSTER); - public static final Setting SCRIPT_CACHE_EXPIRE_SETTING = Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), false, Setting.Scope.CLUSTER); + public static final Setting SCRIPT_CACHE_SIZE_SETTING = + Setting.intSetting("script.cache.max_size", 100, 0, false, SettingsProperty.ClusterScope); + public static final Setting SCRIPT_CACHE_EXPIRE_SETTING = + Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); public static final String SCRIPT_INDEX = ".scripts"; - public static final Setting SCRIPT_AUTO_RELOAD_ENABLED_SETTING = Setting.boolSetting("script.auto_reload_enabled", true, false, Setting.Scope.CLUSTER); + public static final Setting SCRIPT_AUTO_RELOAD_ENABLED_SETTING = + Setting.boolSetting("script.auto_reload_enabled", true, false, SettingsProperty.ClusterScope); private final String defaultLang; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java index 8ececfe25bb..a2ab5f9c269 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java @@ -21,6 +21,7 @@ package org.elasticsearch.script; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.ArrayList; @@ -45,7 +46,7 @@ public class ScriptSettings { scriptType.getDefaultScriptMode().getMode(), ScriptMode::parse, false, - Setting.Scope.CLUSTER)); + SettingsProperty.ClusterScope)); } SCRIPT_TYPE_SETTING_MAP = Collections.unmodifiableMap(scriptTypeSettingMap); } @@ -66,7 +67,7 @@ public class ScriptSettings { throw new IllegalArgumentException("unregistered default language [" + setting + "]"); } return setting; - }, false, Setting.Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); } private static Map> contextSettings(ScriptContextRegistry scriptContextRegistry) { @@ -77,7 +78,7 @@ public class ScriptSettings { ScriptMode.OFF.getMode(), ScriptMode::parse, false, - Setting.Scope.CLUSTER + SettingsProperty.ClusterScope )); } return scriptContextSettingMap; @@ -138,7 +139,7 @@ public class ScriptSettings { defaultSetting, ScriptMode::parse, false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); scriptModeSettings.add(setting); } } diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index 3f62066cd4c..a4106feb231 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -34,6 +34,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.BigArrays; @@ -106,11 +107,14 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueMinutes; public class SearchService extends AbstractLifecycleComponent implements IndexEventListener { // we can have 5 minutes here, since we make sure to clean with search requests and when shard/index closes - public static final Setting DEFAULT_KEEPALIVE_SETTING = Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), false, Setting.Scope.CLUSTER); - public static final Setting KEEPALIVE_INTERVAL_SETTING = Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), false, Setting.Scope.CLUSTER); + public static final Setting DEFAULT_KEEPALIVE_SETTING = + Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), false, SettingsProperty.ClusterScope); + public static final Setting KEEPALIVE_INTERVAL_SETTING = + Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), false, SettingsProperty.ClusterScope); public static final TimeValue NO_TIMEOUT = timeValueMillis(-1); - public static final Setting DEFAULT_SEARCH_TIMEOUT_SETTING = Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, true, Setting.Scope.CLUSTER); + public static final Setting DEFAULT_SEARCH_TIMEOUT_SETTING = + Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, true, SettingsProperty.ClusterScope); private final ThreadPool threadPool; diff --git a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java index c7f4392e56a..14c52ab627a 100644 --- a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java +++ b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.unit.SizeValue; @@ -188,7 +189,8 @@ public class ThreadPool extends AbstractComponent implements Closeable { } } - public static final Setting THREADPOOL_GROUP_SETTING = Setting.groupSetting("threadpool.", true, Setting.Scope.CLUSTER); + public static final Setting THREADPOOL_GROUP_SETTING = + Setting.groupSetting("threadpool.", true, SettingsProperty.ClusterScope); private volatile Map executors; diff --git a/core/src/main/java/org/elasticsearch/transport/Transport.java b/core/src/main/java/org/elasticsearch/transport/Transport.java index c930773f39c..c72bcb2bb54 100644 --- a/core/src/main/java/org/elasticsearch/transport/Transport.java +++ b/core/src/main/java/org/elasticsearch/transport/Transport.java @@ -22,6 +22,7 @@ package org.elasticsearch.transport; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -35,7 +36,7 @@ import java.util.Map; public interface Transport extends LifecycleComponent { - Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, false, Setting.Scope.CLUSTER); + Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, false, SettingsProperty.ClusterScope); void transportServiceAdapter(TransportServiceAdapter service); diff --git a/core/src/main/java/org/elasticsearch/transport/TransportService.java b/core/src/main/java/org/elasticsearch/transport/TransportService.java index d04966bc2ca..2a03c516255 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportService.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportService.java @@ -33,7 +33,7 @@ import org.elasticsearch.common.metrics.MeanMetric; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -98,10 +98,11 @@ public class TransportService extends AbstractLifecycleComponent> TRACE_LOG_INCLUDE_SETTING = listSetting("transport.tracer.include", emptyList(), - Function.identity(), true, Scope.CLUSTER); - public static final Setting> TRACE_LOG_EXCLUDE_SETTING = listSetting("transport.tracer.exclude", - Arrays.asList("internal:discovery/zen/fd*", TransportLivenessAction.NAME), Function.identity(), true, Scope.CLUSTER); + public static final Setting> TRACE_LOG_INCLUDE_SETTING = + listSetting("transport.tracer.include", emptyList(), Function.identity(), true, SettingsProperty.ClusterScope); + public static final Setting> TRACE_LOG_EXCLUDE_SETTING = + listSetting("transport.tracer.exclude", Arrays.asList("internal:discovery/zen/fd*", TransportLivenessAction.NAME), + Function.identity(), true, SettingsProperty.ClusterScope); private final ESLogger tracerLog; diff --git a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java index e02dcc412ed..e5fb9f7e14d 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java @@ -19,7 +19,7 @@ package org.elasticsearch.transport; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.List; @@ -35,13 +35,19 @@ import static org.elasticsearch.common.settings.Setting.listSetting; */ final public class TransportSettings { - public static final Setting> HOST = listSetting("transport.host", emptyList(), s -> s, false, Scope.CLUSTER); - public static final Setting> PUBLISH_HOST = listSetting("transport.publish_host", HOST, s -> s, false, Scope.CLUSTER); - public static final Setting> BIND_HOST = listSetting("transport.bind_host", HOST, s -> s, false, Scope.CLUSTER); - public static final Setting PORT = new Setting<>("transport.tcp.port", "9300-9400", s -> s, false, Scope.CLUSTER); - public static final Setting PUBLISH_PORT = intSetting("transport.publish_port", -1, -1, false, Scope.CLUSTER); + public static final Setting> HOST = + listSetting("transport.host", emptyList(), s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> PUBLISH_HOST = + listSetting("transport.publish_host", HOST, s -> s, false, SettingsProperty.ClusterScope); + public static final Setting> BIND_HOST = + listSetting("transport.bind_host", HOST, s -> s, false, SettingsProperty.ClusterScope); + public static final Setting PORT = + new Setting<>("transport.tcp.port", "9300-9400", s -> s, false, SettingsProperty.ClusterScope); + public static final Setting PUBLISH_PORT = + intSetting("transport.publish_port", -1, -1, false, SettingsProperty.ClusterScope); public static final String DEFAULT_PROFILE = "default"; - public static final Setting TRANSPORT_PROFILES_SETTING = groupSetting("transport.profiles.", true, Scope.CLUSTER); + public static final Setting TRANSPORT_PROFILES_SETTING = + groupSetting("transport.profiles.", true, SettingsProperty.ClusterScope); private TransportSettings() { diff --git a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java index 685fdeda683..dd250fabd1d 100644 --- a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java +++ b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java @@ -42,7 +42,7 @@ import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.network.NetworkService.TcpSettings; import org.elasticsearch.common.network.NetworkUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -147,40 +147,46 @@ public class NettyTransport extends AbstractLifecycleComponent implem public static final String TRANSPORT_CLIENT_WORKER_THREAD_NAME_PREFIX = "transport_client_worker"; public static final String TRANSPORT_CLIENT_BOSS_THREAD_NAME_PREFIX = "transport_client_boss"; - public static final Setting WORKER_COUNT = new Setting<>("transport.netty.worker_count", + public static final Setting WORKER_COUNT = + new Setting<>("transport.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), false, Setting.Scope.CLUSTER); - public static final Setting CONNECTIONS_PER_NODE_RECOVERY = intSetting("transport.connections_per_node.recovery", 2, 1, false, - Scope.CLUSTER); - public static final Setting CONNECTIONS_PER_NODE_BULK = intSetting("transport.connections_per_node.bulk", 3, 1, false, - Scope.CLUSTER); - public static final Setting CONNECTIONS_PER_NODE_REG = intSetting("transport.connections_per_node.reg", 6, 1, false, - Scope.CLUSTER); - public static final Setting CONNECTIONS_PER_NODE_STATE = intSetting("transport.connections_per_node.state", 1, 1, false, - Scope.CLUSTER); - public static final Setting CONNECTIONS_PER_NODE_PING = intSetting("transport.connections_per_node.ping", 1, 1, false, - Scope.CLUSTER); + (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), false, SettingsProperty.ClusterScope); + public static final Setting CONNECTIONS_PER_NODE_RECOVERY = + intSetting("transport.connections_per_node.recovery", 2, 1, false, SettingsProperty.ClusterScope); + public static final Setting CONNECTIONS_PER_NODE_BULK = + intSetting("transport.connections_per_node.bulk", 3, 1, false, SettingsProperty.ClusterScope); + public static final Setting CONNECTIONS_PER_NODE_REG = + intSetting("transport.connections_per_node.reg", 6, 1, false, SettingsProperty.ClusterScope); + public static final Setting CONNECTIONS_PER_NODE_STATE = + intSetting("transport.connections_per_node.state", 1, 1, false, SettingsProperty.ClusterScope); + public static final Setting CONNECTIONS_PER_NODE_PING = + intSetting("transport.connections_per_node.ping", 1, 1, false, SettingsProperty.ClusterScope); // the scheduled internal ping interval setting, defaults to disabled (-1) - public static final Setting PING_SCHEDULE = timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), false, - Setting.Scope.CLUSTER); - public static final Setting TCP_BLOCKING_CLIENT = boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, - false, Setting.Scope.CLUSTER); - public static final Setting TCP_CONNECT_TIMEOUT = timeSetting("transport.tcp.connect_timeout", - TcpSettings.TCP_CONNECT_TIMEOUT, false, Setting.Scope.CLUSTER); - public static final Setting TCP_NO_DELAY = boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, false, - Setting.Scope.CLUSTER); - public static final Setting TCP_KEEP_ALIVE = boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, false, - Setting.Scope.CLUSTER); - public static final Setting TCP_BLOCKING_SERVER = boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, - false, Setting.Scope.CLUSTER); - public static final Setting TCP_REUSE_ADDRESS = boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, - false, Setting.Scope.CLUSTER); + public static final Setting PING_SCHEDULE = + timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), false, SettingsProperty.ClusterScope); + public static final Setting TCP_BLOCKING_CLIENT = + boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, false, SettingsProperty.ClusterScope); + public static final Setting TCP_CONNECT_TIMEOUT = + timeSetting("transport.tcp.connect_timeout", TcpSettings.TCP_CONNECT_TIMEOUT, false, SettingsProperty.ClusterScope); + public static final Setting TCP_NO_DELAY = + boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, false, SettingsProperty.ClusterScope); + public static final Setting TCP_KEEP_ALIVE = + boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, false, SettingsProperty.ClusterScope); + public static final Setting TCP_BLOCKING_SERVER = + boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, false, SettingsProperty.ClusterScope); + public static final Setting TCP_REUSE_ADDRESS = + boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, false, SettingsProperty.ClusterScope); - public static final Setting TCP_SEND_BUFFER_SIZE = Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, false, Setting.Scope.CLUSTER); - public static final Setting TCP_RECEIVE_BUFFER_SIZE = Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, Setting.Scope.CLUSTER); + public static final Setting TCP_SEND_BUFFER_SIZE = + Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, false, SettingsProperty.ClusterScope); + public static final Setting TCP_RECEIVE_BUFFER_SIZE = + Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, + SettingsProperty.ClusterScope); - public static final Setting NETTY_MAX_CUMULATION_BUFFER_CAPACITY = Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); - public static final Setting NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, false, Setting.Scope.CLUSTER); + public static final Setting NETTY_MAX_CUMULATION_BUFFER_CAPACITY = + Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + public static final Setting NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = + Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, false, SettingsProperty.ClusterScope); // See AdaptiveReceiveBufferSizePredictor#DEFAULT_XXX for default values in netty..., we can use higher ones for us, even fixed one public static final Setting NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting( @@ -193,12 +199,13 @@ public class NettyTransport extends AbstractLifecycleComponent implem defaultReceiverPredictor = Math.min(defaultReceiverPredictor, Math.max(l, 64 * 1024)); } return new ByteSizeValue(defaultReceiverPredictor).toString(); - }, false, Setting.Scope.CLUSTER); - public static final Setting NETTY_RECEIVE_PREDICTOR_MIN = byteSizeSetting("transport.netty.receive_predictor_min", - NETTY_RECEIVE_PREDICTOR_SIZE, false, Scope.CLUSTER); - public static final Setting NETTY_RECEIVE_PREDICTOR_MAX = byteSizeSetting("transport.netty.receive_predictor_max", - NETTY_RECEIVE_PREDICTOR_SIZE, false, Scope.CLUSTER); - public static final Setting NETTY_BOSS_COUNT = intSetting("transport.netty.boss_count", 1, 1, false, Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); + public static final Setting NETTY_RECEIVE_PREDICTOR_MIN = + byteSizeSetting("transport.netty.receive_predictor_min", NETTY_RECEIVE_PREDICTOR_SIZE, false, SettingsProperty.ClusterScope); + public static final Setting NETTY_RECEIVE_PREDICTOR_MAX = + byteSizeSetting("transport.netty.receive_predictor_max", NETTY_RECEIVE_PREDICTOR_SIZE, false, SettingsProperty.ClusterScope); + public static final Setting NETTY_BOSS_COUNT = + intSetting("transport.netty.boss_count", 1, 1, false, SettingsProperty.ClusterScope); protected final NetworkService networkService; protected final Version version; diff --git a/core/src/main/java/org/elasticsearch/tribe/TribeService.java b/core/src/main/java/org/elasticsearch/tribe/TribeService.java index af2e3fe96f0..0b4f99457eb 100644 --- a/core/src/main/java/org/elasticsearch/tribe/TribeService.java +++ b/core/src/main/java/org/elasticsearch/tribe/TribeService.java @@ -44,6 +44,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.set.Sets; @@ -121,7 +122,7 @@ public class TribeService extends AbstractLifecycleComponent { } // internal settings only - public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", false, Setting.Scope.CLUSTER); + public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", false, SettingsProperty.ClusterScope); private final ClusterService clusterService; private final String[] blockIndicesWrite; private final String[] blockIndicesRead; @@ -140,18 +141,21 @@ public class TribeService extends AbstractLifecycleComponent { throw new IllegalArgumentException( "Invalid value for [tribe.on_conflict] must be either [any, drop or start with prefer_] but was: [" + s + "]"); } - }, false, Setting.Scope.CLUSTER); + }, false, SettingsProperty.ClusterScope); - public static final Setting BLOCKS_METADATA_SETTING = Setting.boolSetting("tribe.blocks.metadata", false, false, - Setting.Scope.CLUSTER); - public static final Setting BLOCKS_WRITE_SETTING = Setting.boolSetting("tribe.blocks.write", false, false, - Setting.Scope.CLUSTER); - public static final Setting> BLOCKS_WRITE_INDICES_SETTING = Setting.listSetting("tribe.blocks.write.indices", - Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting> BLOCKS_READ_INDICES_SETTING = Setting.listSetting("tribe.blocks.read.indices", - Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting> BLOCKS_METADATA_INDICES_SETTING = Setting.listSetting("tribe.blocks.metadata.indices", - Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); + public static final Setting BLOCKS_METADATA_SETTING = + Setting.boolSetting("tribe.blocks.metadata", false, false, SettingsProperty.ClusterScope); + public static final Setting BLOCKS_WRITE_SETTING = + Setting.boolSetting("tribe.blocks.write", false, false, SettingsProperty.ClusterScope); + public static final Setting> BLOCKS_WRITE_INDICES_SETTING = + Setting.listSetting("tribe.blocks.write.indices", Collections.emptyList(), Function.identity(), false, + SettingsProperty.ClusterScope); + public static final Setting> BLOCKS_READ_INDICES_SETTING = + Setting.listSetting("tribe.blocks.read.indices", Collections.emptyList(), Function.identity(), false, + SettingsProperty.ClusterScope); + public static final Setting> BLOCKS_METADATA_INDICES_SETTING = + Setting.listSetting("tribe.blocks.metadata.indices", Collections.emptyList(), Function.identity(), false, + SettingsProperty.ClusterScope); public static final Set TRIBE_SETTING_KEYS = Sets.newHashSet(TRIBE_NAME_SETTING.getKey(), ON_CONFLICT_SETTING.getKey(), BLOCKS_METADATA_INDICES_SETTING.getKey(), BLOCKS_METADATA_SETTING.getKey(), BLOCKS_READ_INDICES_SETTING.getKey(), BLOCKS_WRITE_INDICES_SETTING.getKey(), BLOCKS_WRITE_SETTING.getKey()); diff --git a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java index 2c2bab24605..9efccd0afd2 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.inject.ModuleTestCase; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; @@ -83,7 +84,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterClusterDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, true, Setting.Scope.CLUSTER)); + module.registerSetting(Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope)); assertInstanceBinding(module, ClusterSettings.class, service -> service.hasDynamicSetting("foo.bar")); } @@ -98,7 +99,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterIndexDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, true, Setting.Scope.INDEX)); + module.registerSetting(Setting.boolSetting("foo.bar", false, true, SettingsProperty.IndexScope)); assertInstanceBinding(module, IndexScopedSettings.class, service -> service.hasDynamicSetting("foo.bar")); } diff --git a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java index dbf502d5805..9590d214d5b 100644 --- a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java @@ -22,19 +22,15 @@ package org.elasticsearch.cluster.settings; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; import java.util.Collection; -import java.util.Collections; import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @@ -51,9 +47,9 @@ public class SettingsFilteringIT extends ESIntegTestCase { public static class SettingsFilteringPlugin extends Plugin { public static final Setting SOME_NODE_SETTING = - Setting.boolSetting("some.node.setting", false, false, Setting.Scope.CLUSTER, true); + Setting.boolSetting("some.node.setting", false, false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting SOME_OTHER_NODE_SETTING = - Setting.boolSetting("some.other.node.setting", false, false, Setting.Scope.CLUSTER); + Setting.boolSetting("some.other.node.setting", false, false, SettingsProperty.ClusterScope); /** * The name of the plugin. @@ -79,7 +75,7 @@ public class SettingsFilteringIT extends ESIntegTestCase { public void onModule(SettingsModule module) { module.registerSetting(SOME_NODE_SETTING); module.registerSetting(SOME_OTHER_NODE_SETTING); - module.registerSetting(Setting.groupSetting("index.filter_test.", false, Setting.Scope.INDEX)); + module.registerSetting(Setting.groupSetting("index.filter_test.", false, SettingsProperty.IndexScope)); module.registerSettingsFilter("index.filter_test.foo"); module.registerSettingsFilter("index.filter_test.bar*"); } diff --git a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index 58f5cde65ce..7a2e424393b 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -23,6 +23,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider; import org.elasticsearch.common.logging.ESLoggerFactory; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.index.IndexModule; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.TransportService; @@ -38,8 +39,8 @@ import java.util.concurrent.atomic.AtomicReference; public class ScopedSettingsTests extends ESTestCase { public void testAddConsumer() { - Setting testSetting = Setting.intSetting("foo.bar", 1, true, Setting.Scope.CLUSTER); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, Setting.Scope.CLUSTER); + Setting testSetting = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, SettingsProperty.ClusterScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, Collections.singleton(testSetting)); AtomicInteger consumer = new AtomicInteger(); @@ -66,8 +67,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testApply() { - Setting testSetting = Setting.intSetting("foo.bar", 1, true, Setting.Scope.CLUSTER); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, Setting.Scope.CLUSTER); + Setting testSetting = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, SettingsProperty.ClusterScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(testSetting, testSetting2))); AtomicInteger consumer = new AtomicInteger(); @@ -136,7 +137,10 @@ public class ScopedSettingsTests extends ESTestCase { } public void testIsDynamic(){ - ClusterSettings settings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, true, Setting.Scope.CLUSTER), Setting.intSetting("foo.bar.baz", 1, false, Setting.Scope.CLUSTER)))); + ClusterSettings settings = + new ClusterSettings(Settings.EMPTY, + new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope), + Setting.intSetting("foo.bar.baz", 1, false, SettingsProperty.ClusterScope)))); assertFalse(settings.hasDynamicSetting("foo.bar.baz")); assertTrue(settings.hasDynamicSetting("foo.bar")); assertNotNull(settings.get("foo.bar.baz")); @@ -147,8 +151,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testDiff() throws IOException { - Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, false, Setting.Scope.CLUSTER); - Setting foobar = Setting.intSetting("foo.bar", 1, true, Setting.Scope.CLUSTER); + Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, false, SettingsProperty.ClusterScope); + Setting foobar = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); ClusterSettings settings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(foobar, foobarbaz))); Settings diff = settings.diff(Settings.builder().put("foo.bar", 5).build(), Settings.EMPTY); assertEquals(diff.getAsMap().size(), 1); @@ -237,22 +241,22 @@ public class ScopedSettingsTests extends ESTestCase { try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", false, Setting.Scope.INDEX))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", false, SettingsProperty.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo .]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", false, Setting.Scope.INDEX))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", false, SettingsProperty.IndexScope))); try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, false, Setting.Scope.INDEX))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, false, SettingsProperty.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo.]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, false, Setting.Scope.INDEX))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, false, SettingsProperty.IndexScope))); } public void testLoggingUpdates() { diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index f5b84fb366f..ed9213d392a 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.common.settings; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.test.ESTestCase; @@ -27,26 +28,28 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import static org.hamcrest.Matchers.is; + public class SettingTests extends ESTestCase { public void testGet() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, Setting.Scope.CLUSTER); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); assertFalse(booleanSetting.get(Settings.EMPTY)); assertFalse(booleanSetting.get(Settings.builder().put("foo.bar", false).build())); assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", true).build())); } public void testByteSize() { - Setting byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), true, Setting.Scope.CLUSTER); + Setting byteSizeValueSetting = + Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), true, SettingsProperty.ClusterScope); assertFalse(byteSizeValueSetting.isGroupSetting()); ByteSizeValue byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 1024); - byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", true, Setting.Scope.CLUSTER); + byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", true, SettingsProperty.ClusterScope); byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 2048); @@ -65,7 +68,7 @@ public class SettingTests extends ESTestCase { } public void testSimpleUpdate() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, Setting.Scope.CLUSTER); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); AtomicReference atomicBoolean = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(atomicBoolean::set, logger); Settings build = Settings.builder().put("foo.bar", false).build(); @@ -86,7 +89,7 @@ public class SettingTests extends ESTestCase { } public void testUpdateNotDynamic() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, false, Setting.Scope.CLUSTER); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, false, SettingsProperty.ClusterScope); assertFalse(booleanSetting.isGroupSetting()); AtomicReference atomicBoolean = new AtomicReference<>(null); try { @@ -98,7 +101,7 @@ public class SettingTests extends ESTestCase { } public void testUpdaterIsIsolated() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, Setting.Scope.CLUSTER); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); AtomicReference ab1 = new AtomicReference<>(null); AtomicReference ab2 = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(ab1::set, logger); @@ -109,24 +112,27 @@ public class SettingTests extends ESTestCase { public void testDefault() { TimeValue defautlValue = TimeValue.timeValueMillis(randomIntBetween(0, 1000000)); - Setting setting = Setting.positiveTimeSetting("my.time.value", defautlValue, randomBoolean(), Setting.Scope.CLUSTER); + Setting setting = + Setting.positiveTimeSetting("my.time.value", defautlValue, randomBoolean(), SettingsProperty.ClusterScope); assertFalse(setting.isGroupSetting()); String aDefault = setting.getDefaultRaw(Settings.EMPTY); assertEquals(defautlValue.millis() + "ms", aDefault); assertEquals(defautlValue.millis(), setting.get(Settings.EMPTY).millis()); assertEquals(defautlValue, setting.getDefault(Settings.EMPTY)); - Setting secondaryDefault = new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), (s) -> s, randomBoolean(), Setting.Scope.CLUSTER); + Setting secondaryDefault = + new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), (s) -> s, randomBoolean(), SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefault.get(Settings.EMPTY)); assertEquals("42", secondaryDefault.get(Settings.builder().put("old.foo.bar", 42).build())); - Setting secondaryDefaultViaSettings = new Setting<>("foo.bar", secondaryDefault, (s) -> s, randomBoolean(), Setting.Scope.CLUSTER); + Setting secondaryDefaultViaSettings = + new Setting<>("foo.bar", secondaryDefault, (s) -> s, randomBoolean(), SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefaultViaSettings.get(Settings.EMPTY)); assertEquals("42", secondaryDefaultViaSettings.get(Settings.builder().put("old.foo.bar", 42).build())); } public void testComplexType() { AtomicReference ref = new AtomicReference<>(null); - Setting setting = new Setting<>("foo.bar", (s) -> "", (s) -> new ComplexType(s), true, Setting.Scope.CLUSTER); + Setting setting = new Setting<>("foo.bar", (s) -> "", (s) -> new ComplexType(s), true, SettingsProperty.ClusterScope); assertFalse(setting.isGroupSetting()); ref.set(setting.get(Settings.EMPTY)); ComplexType type = ref.get(); @@ -147,15 +153,19 @@ public class SettingTests extends ESTestCase { } public void testType() { - Setting integerSetting = Setting.intSetting("foo.int.bar", 1, true, Setting.Scope.CLUSTER); - assertEquals(integerSetting.getScope(), Setting.Scope.CLUSTER); - integerSetting = Setting.intSetting("foo.int.bar", 1, true, Setting.Scope.INDEX); - assertEquals(integerSetting.getScope(), Setting.Scope.INDEX); + Setting integerSetting = Setting.intSetting("foo.int.bar", 1, true, SettingsProperty.ClusterScope); + assertThat(integerSetting.hasClusterScope(), is(true)); + assertThat(integerSetting.hasIndexScope(), is(false)); + assertThat(integerSetting.hasNodeScope(), is(false)); + integerSetting = Setting.intSetting("foo.int.bar", 1, true, SettingsProperty.IndexScope); + assertThat(integerSetting.hasIndexScope(), is(true)); + assertThat(integerSetting.hasClusterScope(), is(false)); + assertThat(integerSetting.hasNodeScope(), is(false)); } public void testGroups() { AtomicReference ref = new AtomicReference<>(null); - Setting setting = Setting.groupSetting("foo.bar.", true, Setting.Scope.CLUSTER); + Setting setting = Setting.groupSetting("foo.bar.", true, SettingsProperty.ClusterScope); assertTrue(setting.isGroupSetting()); ClusterSettings.SettingUpdater settingUpdater = setting.newUpdater(ref::set, logger); @@ -233,8 +243,8 @@ public class SettingTests extends ESTestCase { public void testComposite() { Composite c = new Composite(); - Setting a = Setting.intSetting("foo.int.bar.a", 1, true, Setting.Scope.CLUSTER); - Setting b = Setting.intSetting("foo.int.bar.b", 1, true, Setting.Scope.CLUSTER); + Setting a = Setting.intSetting("foo.int.bar.a", 1, true, SettingsProperty.ClusterScope); + Setting b = Setting.intSetting("foo.int.bar.b", 1, true, SettingsProperty.ClusterScope); ClusterSettings.SettingUpdater> settingUpdater = Setting.compoundUpdater(c::set, a, b, logger); assertFalse(settingUpdater.apply(Settings.EMPTY, Settings.EMPTY)); assertNull(c.a); @@ -262,7 +272,7 @@ public class SettingTests extends ESTestCase { } public void testListSettings() { - Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, Setting.Scope.CLUSTER); + Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, SettingsProperty.ClusterScope); List value = listSetting.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -301,7 +311,7 @@ public class SettingTests extends ESTestCase { assertEquals(1, ref.get().size()); assertEquals("foo,bar", ref.get().get(0)); - Setting> otherSettings = Setting.listSetting("foo.bar", Collections.emptyList(), Integer::parseInt, true, Setting.Scope.CLUSTER); + Setting> otherSettings = Setting.listSetting("foo.bar", Collections.emptyList(), Integer::parseInt, true, SettingsProperty.ClusterScope); List defaultValue = otherSettings.get(Settings.EMPTY); assertEquals(0, defaultValue.size()); List intValues = otherSettings.get(Settings.builder().put("foo.bar", "0,1,2,3").build()); @@ -310,7 +320,7 @@ public class SettingTests extends ESTestCase { assertEquals(i, intValues.get(i).intValue()); } - Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, s -> s, true, Setting.Scope.CLUSTER); + Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, s -> s, true, SettingsProperty.ClusterScope); value = settingWithFallback.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -332,7 +342,7 @@ public class SettingTests extends ESTestCase { } public void testListSettingAcceptsNumberSyntax() { - Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, Setting.Scope.CLUSTER); + Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, SettingsProperty.ClusterScope); List input = Arrays.asList("test", "test1, test2", "test", ",,,,"); Settings.Builder builder = Settings.builder().putArray("foo.bar", input.toArray(new String[0])); // try to parse this really annoying format @@ -350,7 +360,7 @@ public class SettingTests extends ESTestCase { } public void testDynamicKeySetting() { - Setting setting = Setting.dynamicKeySetting("foo.", "false", Boolean::parseBoolean, false, Setting.Scope.CLUSTER); + Setting setting = Setting.dynamicKeySetting("foo.", "false", Boolean::parseBoolean, false, SettingsProperty.ClusterScope); assertTrue(setting.hasComplexMatcher()); assertTrue(setting.match("foo.bar")); assertFalse(setting.match("foo")); @@ -367,7 +377,7 @@ public class SettingTests extends ESTestCase { } public void testMinMaxInt() { - Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, false, Setting.Scope.CLUSTER); + Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, false, SettingsProperty.ClusterScope); try { integerSetting.get(Settings.builder().put("foo.bar", 11).build()); fail(); diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java index ce32be6c935..3cd2bb2d021 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.common.settings; import org.elasticsearch.common.inject.ModuleTestCase; +import org.elasticsearch.common.settings.Setting.SettingsProperty; public class SettingsModuleTests extends ModuleTestCase { @@ -45,13 +46,13 @@ public class SettingsModuleTests extends ModuleTestCase { { Settings settings = Settings.builder().put("some.custom.setting", "2.0").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, Setting.Scope.CLUSTER)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, SettingsProperty.ClusterScope)); assertInstanceBinding(module, Settings.class, (s) -> s == settings); } { Settings settings = Settings.builder().put("some.custom.setting", "false").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, Setting.Scope.CLUSTER)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, SettingsProperty.ClusterScope)); try { assertInstanceBinding(module, Settings.class, (s) -> s == settings); fail(); @@ -131,9 +132,9 @@ public class SettingsModuleTests extends ModuleTestCase { public void testRegisterSettingsFilter() { Settings settings = Settings.builder().put("foo.bar", "false").put("bar.foo", false).put("bar.baz", false).build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.boolSetting("foo.bar", true, false, Setting.Scope.CLUSTER)); - module.registerSetting(Setting.boolSetting("bar.foo", true, false, Setting.Scope.CLUSTER, true)); - module.registerSetting(Setting.boolSetting("bar.baz", true, false, Setting.Scope.CLUSTER)); + module.registerSetting(Setting.boolSetting("foo.bar", true, false, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("bar.foo", true, false, SettingsProperty.ClusterScope, SettingsProperty.Filtered)); + module.registerSetting(Setting.boolSetting("bar.baz", true, false, SettingsProperty.ClusterScope)); module.registerSettingsFilter("foo.*"); try { diff --git a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java index 9e0c3776bf1..5a17caff67d 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java @@ -34,6 +34,7 @@ import org.elasticsearch.cache.recycler.PageCacheRecycler; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.env.Environment; @@ -194,9 +195,9 @@ public class IndexModuleTests extends ESTestCase { public void testListener() throws IOException { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, Setting.Scope.INDEX); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.IndexScope); IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(index, settings, booleanSetting), null, new AnalysisRegistry(null, environment)); - Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, true, Setting.Scope.INDEX); + Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, true, SettingsProperty.IndexScope); AtomicBoolean atomicBoolean = new AtomicBoolean(false); module.addSettingsUpdateConsumer(booleanSetting, atomicBoolean::set); diff --git a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java index 677c8358fb0..ad8edee61bf 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java @@ -23,6 +23,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -44,7 +45,7 @@ public class IndexSettingsTests extends ESTestCase { Version version = VersionUtils.getPreviousVersion(); Settings theSettings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).put(IndexMetaData.SETTING_INDEX_UUID, "0xdeadbeef").build(); final AtomicInteger integer = new AtomicInteger(0); - Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, Setting.Scope.INDEX); + Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, SettingsProperty.IndexScope); IndexMetaData metaData = newIndexMeta("index", theSettings); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -65,8 +66,8 @@ public class IndexSettingsTests extends ESTestCase { .put(IndexMetaData.SETTING_INDEX_UUID, "0xdeadbeef").build(); final AtomicInteger integer = new AtomicInteger(0); final StringBuilder builder = new StringBuilder(); - Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, Setting.Scope.INDEX); - Setting notUpdated = new Setting<>("index.not.updated", "", Function.identity(), true, Setting.Scope.INDEX); + Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, SettingsProperty.IndexScope); + Setting notUpdated = new Setting<>("index.not.updated", "", Function.identity(), true, SettingsProperty.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting, notUpdated); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -128,7 +129,7 @@ public class IndexSettingsTests extends ESTestCase { Settings nodeSettings = Settings.settingsBuilder().put("index.foo.bar", 43).build(); final AtomicInteger indexValue = new AtomicInteger(0); - Setting integerSetting = Setting.intSetting("index.foo.bar", -1, true, Setting.Scope.INDEX); + Setting integerSetting = Setting.intSetting("index.foo.bar", -1, true, SettingsProperty.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), nodeSettings, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, indexValue::set); assertEquals(numReplicas, settings.getNumberOfReplicas()); diff --git a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java index 7dbff244fcc..69f5316d4d0 100644 --- a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java +++ b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java @@ -21,6 +21,7 @@ package org.elasticsearch.index; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; @@ -43,7 +44,7 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsListenerPlugin extends Plugin { private final SettingsTestingService service = new SettingsTestingService(); - private static final Setting SETTING = Setting.intSetting("index.test.new.setting", 0, true, Setting.Scope.INDEX); + private static final Setting SETTING = Setting.intSetting("index.test.new.setting", 0, true, SettingsProperty.IndexScope); /** * The name of the plugin. */ @@ -93,7 +94,7 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsTestingService { public volatile int value; - public static Setting VALUE = Setting.intSetting("index.test.new.setting", -1, -1, true, Setting.Scope.INDEX); + public static Setting VALUE = Setting.intSetting("index.test.new.setting", -1, -1, true, SettingsProperty.IndexScope); public void setValue(int value) { this.value = value; diff --git a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java index aad4e34c3da..8dee6712833 100644 --- a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java @@ -47,6 +47,7 @@ import org.elasticsearch.action.suggest.SuggestRequestBuilder; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.index.IndexNotFoundException; @@ -642,9 +643,12 @@ public class IndicesOptionsIntegrationIT extends ESIntegTestCase { return "a plugin that adds a dynamic tst setting"; } - private static final Setting INDEX_A = new Setting<>("index.a", "", Function.identity(), true, Setting.Scope.INDEX); - private static final Setting INDEX_C = new Setting<>("index.c", "", Function.identity(), true, Setting.Scope.INDEX); - private static final Setting INDEX_E = new Setting<>("index.e", "", Function.identity(), false, Setting.Scope.INDEX); + private static final Setting INDEX_A = + new Setting<>("index.a", "", Function.identity(), true, SettingsProperty.IndexScope); + private static final Setting INDEX_C = + new Setting<>("index.c", "", Function.identity(), true, SettingsProperty.IndexScope); + private static final Setting INDEX_E = + new Setting<>("index.e", "", Function.identity(), false, SettingsProperty.IndexScope); public void onModule(SettingsModule module) { diff --git a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java index 35ed7a2c657..d1ad28101ff 100644 --- a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java +++ b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java @@ -31,6 +31,7 @@ import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.Requests; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.unit.TimeValue; @@ -197,8 +198,10 @@ public class RandomExceptionCircuitBreakerIT extends ESIntegTestCase { // TODO: Generalize this class and add it as a utility public static class RandomExceptionDirectoryReaderWrapper extends MockEngineSupport.DirectoryReaderWrapper { - public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, Setting.Scope.INDEX); - public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, Setting.Scope.INDEX); + public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); public static class TestPlugin extends Plugin { @Override public String name() { diff --git a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java index d342402e4bf..ee260a51b04 100644 --- a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java +++ b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java @@ -29,6 +29,7 @@ import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings.Builder; import org.elasticsearch.common.settings.SettingsModule; @@ -152,8 +153,10 @@ public class SearchWithRandomExceptionsIT extends ESIntegTestCase { public static class RandomExceptionDirectoryReaderWrapper extends MockEngineSupport.DirectoryReaderWrapper { public static class TestPlugin extends Plugin { - public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, Setting.Scope.INDEX); - public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, Setting.Scope.INDEX); + public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); @Override public String name() { return "random-exception-reader-wrapper"; diff --git a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java index 1e383290753..02fd27a952d 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java +++ b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java @@ -28,13 +28,11 @@ import org.elasticsearch.common.blobstore.BlobMetaData; import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsFilter; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.env.Environment; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -50,8 +48,6 @@ import java.io.UnsupportedEncodingException; import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -65,9 +61,9 @@ public class MockRepository extends FsRepository { public static class Plugin extends org.elasticsearch.plugins.Plugin { public static final Setting USERNAME_SETTING = - Setting.simpleString("secret.mock.username", false, Setting.Scope.CLUSTER); + Setting.simpleString("secret.mock.username", false, SettingsProperty.ClusterScope); public static final Setting PASSWORD_SETTING = - Setting.simpleString("secret.mock.password", false, Setting.Scope.CLUSTER, true); + Setting.simpleString("secret.mock.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); @Override public String name() { diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java index 027caaccebc..0a6a752908f 100644 --- a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java +++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java @@ -22,7 +22,7 @@ package org.elasticsearch.cloud.azure.management; import com.microsoft.windowsazure.core.utils.KeyStoreType; import com.microsoft.windowsazure.management.compute.models.HostedServiceGetDetailedResponse; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.Scope; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.azure.AzureUnicastHostsProvider; @@ -30,27 +30,29 @@ public interface AzureComputeService { final class Management { public static final Setting SUBSCRIPTION_ID_SETTING = - Setting.simpleString("cloud.azure.management.subscription.id", false, Scope.CLUSTER, true); + Setting.simpleString("cloud.azure.management.subscription.id", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting SERVICE_NAME_SETTING = - Setting.simpleString("cloud.azure.management.cloud.service.name", false, Scope.CLUSTER); + Setting.simpleString("cloud.azure.management.cloud.service.name", false, SettingsProperty.ClusterScope); // Keystore settings public static final Setting KEYSTORE_PATH_SETTING = - Setting.simpleString("cloud.azure.management.keystore.path", false, Scope.CLUSTER, true); + Setting.simpleString("cloud.azure.management.keystore.path", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting KEYSTORE_PASSWORD_SETTING = - Setting.simpleString("cloud.azure.management.keystore.password", false, Scope.CLUSTER, true); + Setting.simpleString("cloud.azure.management.keystore.password", false, SettingsProperty.ClusterScope, + SettingsProperty.Filtered); public static final Setting KEYSTORE_TYPE_SETTING = new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, false, - Scope.CLUSTER, false); + SettingsProperty.ClusterScope, SettingsProperty.Filtered); } final class Discovery { public static final Setting REFRESH_SETTING = - Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), false, Scope.CLUSTER); + Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), false, + SettingsProperty.ClusterScope); public static final Setting HOST_TYPE_SETTING = new Setting<>("discovery.azure.host.type", AzureUnicastHostsProvider.HostType.PRIVATE_IP.name(), - AzureUnicastHostsProvider.HostType::fromString, false, Scope.CLUSTER); + AzureUnicastHostsProvider.HostType::fromString, false, SettingsProperty.ClusterScope); public static final String ENDPOINT_NAME = "discovery.azure.endpoint.name"; public static final String DEPLOYMENT_NAME = "discovery.azure.deployment.name"; diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java index ce34dd61f40..b88704e18db 100644 --- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java +++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java @@ -22,6 +22,7 @@ package org.elasticsearch.cloud.aws; import com.amazonaws.Protocol; import com.amazonaws.services.ec2.AmazonEC2; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -32,7 +33,8 @@ import java.util.Locale; import java.util.function.Function; public interface AwsEc2Service { - Setting AUTO_ATTRIBUTE_SETTING = Setting.boolSetting("cloud.node.auto_attributes", false, false, Setting.Scope.CLUSTER); + Setting AUTO_ATTRIBUTE_SETTING = + Setting.boolSetting("cloud.node.auto_attributes", false, false, SettingsProperty.ClusterScope); // Global AWS settings (shared between discovery-ec2 and repository-s3) // Each setting starting with `cloud.aws` also exists in repository-s3 project. Don't forget to update @@ -40,40 +42,44 @@ public interface AwsEc2Service { /** * cloud.aws.access_key: AWS Access key. Shared with repository-s3 plugin */ - Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER, true); + Setting KEY_SETTING = + Setting.simpleString("cloud.aws.access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with repository-s3 plugin */ - Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER, true); + Setting SECRET_SETTING = + Setting.simpleString("cloud.aws.secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with repository-s3 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - false, Setting.Scope.CLUSTER); + false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with repository-s3 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, Setting.Scope.CLUSTER); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with repository-s3 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, Setting.Scope.CLUSTER); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with repository-s3 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, Setting.Scope.CLUSTER); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with repository-s3 plugin */ - Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER, true); + Setting PROXY_PASSWORD_SETTING = + Setting.simpleString("cloud.aws.proxy.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with repository-s3 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, Setting.Scope.CLUSTER); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, SettingsProperty.ClusterScope); /** * cloud.aws.region: Region. Shared with repository-s3 plugin */ - Setting REGION_SETTING = new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + Setting REGION_SETTING = + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * Defines specific ec2 settings starting with cloud.aws.ec2. @@ -84,62 +90,62 @@ public interface AwsEc2Service { * @see AwsEc2Service#KEY_SETTING */ Setting KEY_SETTING = new Setting<>("cloud.aws.ec2.access_key", AwsEc2Service.KEY_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER, true); + SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.secret_key: AWS Secret key specific for EC2 API calls. Defaults to cloud.aws.secret_key. * @see AwsEc2Service#SECRET_SETTING */ Setting SECRET_SETTING = new Setting<>("cloud.aws.ec2.secret_key", AwsEc2Service.SECRET_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER, true); + SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.protocol: Protocol for AWS API specific for EC2 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsEc2Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.ec2.protocol", AwsEc2Service.PROTOCOL_SETTING, - s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, Setting.Scope.CLUSTER); + s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.host: In case of proxy, define its hostname/IP specific for EC2 API calls. Defaults to cloud.aws.proxy.host. * @see AwsEc2Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = new Setting<>("cloud.aws.ec2.proxy.host", AwsEc2Service.PROXY_HOST_SETTING, - Function.identity(), false, Setting.Scope.CLUSTER); + Function.identity(), false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.port: In case of proxy, define its port specific for EC2 API calls. Defaults to cloud.aws.proxy.port. * @see AwsEc2Service#PROXY_PORT_SETTING */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.ec2.proxy.port", AwsEc2Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), false, Setting.Scope.CLUSTER); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.username: In case of proxy with auth, define the username specific for EC2 API calls. * Defaults to cloud.aws.proxy.username. * @see AwsEc2Service#PROXY_USERNAME_SETTING */ Setting PROXY_USERNAME_SETTING = new Setting<>("cloud.aws.ec2.proxy.username", AwsEc2Service.PROXY_USERNAME_SETTING, - Function.identity(), false, Setting.Scope.CLUSTER); + Function.identity(), false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.password: In case of proxy with auth, define the password specific for EC2 API calls. * Defaults to cloud.aws.proxy.password. * @see AwsEc2Service#PROXY_PASSWORD_SETTING */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.ec2.proxy.password", AwsEc2Service.PROXY_PASSWORD_SETTING, - Function.identity(), false, Setting.Scope.CLUSTER, true); + Function.identity(), false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.signer: If you are using an old AWS API version, you can define a Signer. Specific for EC2 API calls. * Defaults to cloud.aws.signer. * @see AwsEc2Service#SIGNER_SETTING */ Setting SIGNER_SETTING = new Setting<>("cloud.aws.ec2.signer", AwsEc2Service.SIGNER_SETTING, Function.identity(), - false, Setting.Scope.CLUSTER); + false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.region: Region specific for EC2 API calls. Defaults to cloud.aws.region. * @see AwsEc2Service#REGION_SETTING */ Setting REGION_SETTING = new Setting<>("cloud.aws.ec2.region", AwsEc2Service.REGION_SETTING, - s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * cloud.aws.ec2.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ - Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", false, Setting.Scope.CLUSTER); + Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", false, SettingsProperty.ClusterScope); } /** @@ -159,31 +165,31 @@ public interface AwsEc2Service { */ Setting HOST_TYPE_SETTING = new Setting<>("discovery.ec2.host_type", HostType.PRIVATE_IP.name(), s -> HostType.valueOf(s.toUpperCase(Locale.ROOT)), false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * discovery.ec2.any_group: If set to false, will require all security groups to be present for the instance to be used for the * discovery. Defaults to true. */ Setting ANY_GROUP_SETTING = - Setting.boolSetting("discovery.ec2.any_group", true, false, Setting.Scope.CLUSTER); + Setting.boolSetting("discovery.ec2.any_group", true, false, SettingsProperty.ClusterScope); /** * discovery.ec2.groups: Either a comma separated list or array based list of (security) groups. Only instances with the provided * security groups will be used in the cluster discovery. (NOTE: You could provide either group NAME or group ID.) */ Setting> GROUPS_SETTING = - Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), false, Setting.Scope.CLUSTER); + Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), false, SettingsProperty.ClusterScope); /** * discovery.ec2.availability_zones: Either a comma separated list or array based list of availability zones. Only instances within * the provided availability zones will be used in the cluster discovery. */ Setting> AVAILABILITY_ZONES_SETTING = Setting.listSetting("discovery.ec2.availability_zones", Collections.emptyList(), s -> s.toString(), false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * discovery.ec2.node_cache_time: How long the list of hosts is cached to prevent further requests to the AWS API. Defaults to 10s. */ Setting NODE_CACHE_TIME_SETTING = - Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), false, Setting.Scope.CLUSTER); + Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), false, SettingsProperty.ClusterScope); /** * discovery.ec2.tag.*: The ec2 discovery can filter machines to include in the cluster based on tags (and not just groups). @@ -191,7 +197,7 @@ public interface AwsEc2Service { * instances with a tag key set to stage, and a value of dev. Several tags set will require all of those tags to be set for the * instance to be included. */ - Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", false,Setting.Scope.CLUSTER); + Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", false, SettingsProperty.ClusterScope); } AmazonEC2 client(); diff --git a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java index 58e93c9dd64..53e0c10d058 100644 --- a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java +++ b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.collect.Iterators; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -71,9 +72,12 @@ import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField; public class AttachmentMapper extends FieldMapper { private static ESLogger logger = ESLoggerFactory.getLogger("mapper.attachment"); - public static final Setting INDEX_ATTACHMENT_IGNORE_ERRORS_SETTING = Setting.boolSetting("index.mapping.attachment.ignore_errors", true, false, Setting.Scope.INDEX); - public static final Setting INDEX_ATTACHMENT_DETECT_LANGUAGE_SETTING = Setting.boolSetting("index.mapping.attachment.detect_language", false, false, Setting.Scope.INDEX); - public static final Setting INDEX_ATTACHMENT_INDEXED_CHARS_SETTING = Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, false, Setting.Scope.INDEX); + public static final Setting INDEX_ATTACHMENT_IGNORE_ERRORS_SETTING = + Setting.boolSetting("index.mapping.attachment.ignore_errors", true, false, SettingsProperty.IndexScope); + public static final Setting INDEX_ATTACHMENT_DETECT_LANGUAGE_SETTING = + Setting.boolSetting("index.mapping.attachment.detect_language", false, false, SettingsProperty.IndexScope); + public static final Setting INDEX_ATTACHMENT_INDEXED_CHARS_SETTING = + Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, false, SettingsProperty.IndexScope); public static final String CONTENT_TYPE = "attachment"; diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java index 2c5521887d8..f16e9b6729c 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java @@ -24,6 +24,7 @@ import com.microsoft.azure.storage.StorageException; import org.elasticsearch.common.blobstore.BlobMetaData; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -31,7 +32,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URISyntaxException; import java.util.Map; -import java.util.function.Function; /** * Azure Storage Service interface @@ -42,19 +42,19 @@ public interface AzureStorageService { final class Storage { public static final String PREFIX = "cloud.azure.storage."; public static final Setting TIMEOUT_SETTING = - Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), false, Setting.Scope.CLUSTER); + Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), false, SettingsProperty.ClusterScope); public static final Setting ACCOUNT_SETTING = - Setting.simpleString("repositories.azure.account", false, Setting.Scope.CLUSTER, true); + Setting.simpleString("repositories.azure.account", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting CONTAINER_SETTING = - Setting.simpleString("repositories.azure.container", false, Setting.Scope.CLUSTER); + Setting.simpleString("repositories.azure.container", false, SettingsProperty.ClusterScope); public static final Setting BASE_PATH_SETTING = - Setting.simpleString("repositories.azure.base_path", false, Setting.Scope.CLUSTER); + Setting.simpleString("repositories.azure.base_path", false, SettingsProperty.ClusterScope); public static final Setting LOCATION_MODE_SETTING = - Setting.simpleString("repositories.azure.location_mode", false, Setting.Scope.CLUSTER); + Setting.simpleString("repositories.azure.location_mode", false, SettingsProperty.ClusterScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), false, Setting.Scope.CLUSTER); + Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); public static final Setting COMPRESS_SETTING = - Setting.boolSetting("repositories.azure.compress", false, false, Setting.Scope.CLUSTER); + Setting.boolSetting("repositories.azure.compress", false, false, SettingsProperty.ClusterScope); } boolean doesContainerExist(String account, LocationMode mode, String container); diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index f2773bccbbd..013007a84a7 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -30,6 +30,7 @@ import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -67,12 +68,17 @@ public class AzureRepository extends BlobStoreRepository { public final static String TYPE = "azure"; public static final class Repository { - public static final Setting ACCOUNT_SETTING = Setting.simpleString("account", false, Setting.Scope.CLUSTER); - public static final Setting CONTAINER_SETTING = new Setting<>("container", "elasticsearch-snapshots", Function.identity(), false, Setting.Scope.CLUSTER); - public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, Setting.Scope.CLUSTER); - public static final Setting LOCATION_MODE_SETTING = Setting.simpleString("location_mode", false, Setting.Scope.CLUSTER); - public static final Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, false, Setting.Scope.CLUSTER); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, Setting.Scope.CLUSTER); + public static final Setting ACCOUNT_SETTING = + Setting.simpleString("account", false, SettingsProperty.ClusterScope); + public static final Setting CONTAINER_SETTING = + new Setting<>("container", "elasticsearch-snapshots", Function.identity(), false, SettingsProperty.ClusterScope); + public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, SettingsProperty.ClusterScope); + public static final Setting LOCATION_MODE_SETTING = + Setting.simpleString("location_mode", false, SettingsProperty.ClusterScope); + public static final Setting CHUNK_SIZE_SETTING = + Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, false, SettingsProperty.ClusterScope); + public static final Setting COMPRESS_SETTING = + Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); } private final AzureBlobStore blobStore; diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java index 3af9446fbe9..22bc136523b 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java @@ -23,6 +23,7 @@ import com.amazonaws.Protocol; import com.amazonaws.services.s3.AmazonS3; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import java.util.Locale; import java.util.function.Function; @@ -38,40 +39,44 @@ public interface AwsS3Service extends LifecycleComponent { /** * cloud.aws.access_key: AWS Access key. Shared with discovery-ec2 plugin */ - Setting KEY_SETTING = Setting.simpleString("cloud.aws.access_key", false, Setting.Scope.CLUSTER, true); + Setting KEY_SETTING = + Setting.simpleString("cloud.aws.access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with discovery-ec2 plugin */ - Setting SECRET_SETTING = Setting.simpleString("cloud.aws.secret_key", false, Setting.Scope.CLUSTER, true); + Setting SECRET_SETTING = + Setting.simpleString("cloud.aws.secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with discovery-ec2 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - false, Setting.Scope.CLUSTER); + false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with discovery-ec2 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, Setting.Scope.CLUSTER); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with discovery-ec2 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, Setting.Scope.CLUSTER); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with discovery-ec2 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, Setting.Scope.CLUSTER); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with discovery-ec2 plugin */ - Setting PROXY_PASSWORD_SETTING = Setting.simpleString("cloud.aws.proxy.password", false, Setting.Scope.CLUSTER, true); + Setting PROXY_PASSWORD_SETTING = + Setting.simpleString("cloud.aws.proxy.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with discovery-ec2 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, Setting.Scope.CLUSTER); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, SettingsProperty.ClusterScope); /** * cloud.aws.region: Region. Shared with discovery-ec2 plugin */ - Setting REGION_SETTING = new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + Setting REGION_SETTING = + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * Defines specific s3 settings starting with cloud.aws.s3. @@ -82,33 +87,36 @@ public interface AwsS3Service extends LifecycleComponent { * @see AwsS3Service#KEY_SETTING */ Setting KEY_SETTING = - new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), false, Setting.Scope.CLUSTER, true); + new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), false, + SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.secret_key: AWS Secret key specific for S3 API calls. Defaults to cloud.aws.secret_key. * @see AwsS3Service#SECRET_SETTING */ Setting SECRET_SETTING = - new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), false, Setting.Scope.CLUSTER, true); + new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), false, + SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.protocol: Protocol for AWS API specific for S3 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsS3Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.s3.protocol", AwsS3Service.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.host: In case of proxy, define its hostname/IP specific for S3 API calls. Defaults to cloud.aws.proxy.host. * @see AwsS3Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = - new Setting<>("cloud.aws.s3.proxy.host", AwsS3Service.PROXY_HOST_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.aws.s3.proxy.host", AwsS3Service.PROXY_HOST_SETTING, Function.identity(), false, + SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.port: In case of proxy, define its port specific for S3 API calls. Defaults to cloud.aws.proxy.port. * @see AwsS3Service#PROXY_PORT_SETTING */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.s3.proxy.port", AwsS3Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), false, Setting.Scope.CLUSTER); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), false, SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.username: In case of proxy with auth, define the username specific for S3 API calls. * Defaults to cloud.aws.proxy.username. @@ -116,7 +124,7 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_USERNAME_SETTING = new Setting<>("cloud.aws.s3.proxy.username", AwsS3Service.PROXY_USERNAME_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.password: In case of proxy with auth, define the password specific for S3 API calls. * Defaults to cloud.aws.proxy.password. @@ -124,26 +132,26 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.s3.proxy.password", AwsS3Service.PROXY_PASSWORD_SETTING, Function.identity(), false, - Setting.Scope.CLUSTER, true); + SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.signer: If you are using an old AWS API version, you can define a Signer. Specific for S3 API calls. * Defaults to cloud.aws.signer. * @see AwsS3Service#SIGNER_SETTING */ Setting SIGNER_SETTING = - new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); /** * cloud.aws.s3.region: Region specific for S3 API calls. Defaults to cloud.aws.region. * @see AwsS3Service#REGION_SETTING */ Setting REGION_SETTING = new Setting<>("cloud.aws.s3.region", AwsS3Service.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), false, - Setting.Scope.CLUSTER); + SettingsProperty.ClusterScope); /** * cloud.aws.s3.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ Setting ENDPOINT_SETTING = - Setting.simpleString("cloud.aws.s3.endpoint", false, Setting.Scope.CLUSTER); + Setting.simpleString("cloud.aws.s3.endpoint", false, SettingsProperty.ClusterScope); } AmazonS3 client(String endpoint, Protocol protocol, String region, String account, String key, Integer maxRetries); diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index 6b3b5bf943a..3fdc8a487aa 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -65,70 +66,78 @@ public class S3Repository extends BlobStoreRepository { * repositories.s3.access_key: AWS Access key specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.access_key. * @see CLOUD_S3#KEY_SETTING */ - Setting KEY_SETTING = new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + Setting KEY_SETTING = + new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); /** * repositories.s3.secret_key: AWS Secret key specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.secret_key. * @see CLOUD_S3#SECRET_SETTING */ - Setting SECRET_SETTING = new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), false, Setting.Scope.CLUSTER); + Setting SECRET_SETTING = + new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); /** * repositories.s3.region: Region specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.region. * @see CLOUD_S3#REGION_SETTING */ - Setting REGION_SETTING = new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + Setting REGION_SETTING = + new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * repositories.s3.endpoint: Endpoint specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.endpoint. * @see CLOUD_S3#ENDPOINT_SETTING */ - Setting ENDPOINT_SETTING = new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + Setting ENDPOINT_SETTING = + new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * repositories.s3.protocol: Protocol specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.protocol. * @see CLOUD_S3#PROTOCOL_SETTING */ - Setting PROTOCOL_SETTING = new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, Setting.Scope.CLUSTER); + Setting PROTOCOL_SETTING = + new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); /** * repositories.s3.bucket: The name of the bucket to be used for snapshots. */ - Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", false, Setting.Scope.CLUSTER); + Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", false, SettingsProperty.ClusterScope); /** * repositories.s3.server_side_encryption: When set to true files are encrypted on server side using AES256 algorithm. * Defaults to false. */ - Setting SERVER_SIDE_ENCRYPTION_SETTING = Setting.boolSetting("repositories.s3.server_side_encryption", false, false, Setting.Scope.CLUSTER); + Setting SERVER_SIDE_ENCRYPTION_SETTING = + Setting.boolSetting("repositories.s3.server_side_encryption", false, false, SettingsProperty.ClusterScope); /** * repositories.s3.buffer_size: Minimum threshold below which the chunk is uploaded using a single request. Beyond this threshold, * the S3 repository will use the AWS Multipart Upload API to split the chunk into several parts, each of buffer_size length, and * to upload each part in its own request. Note that setting a buffer size lower than 5mb is not allowed since it will prevents the * use of the Multipart API and may result in upload errors. Defaults to 5mb. */ - Setting BUFFER_SIZE_SETTING = Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, Setting.Scope.CLUSTER); + Setting BUFFER_SIZE_SETTING = + Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, SettingsProperty.ClusterScope); /** * repositories.s3.max_retries: Number of retries in case of S3 errors. Defaults to 3. */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, false, Setting.Scope.CLUSTER); + Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, false, SettingsProperty.ClusterScope); /** * repositories.s3.chunk_size: Big files can be broken down into chunks during snapshotting if needed. Defaults to 100m. */ - Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), false, Setting.Scope.CLUSTER); + Setting CHUNK_SIZE_SETTING = + Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), false, SettingsProperty.ClusterScope); /** * repositories.s3.compress: When set to true metadata files are stored in compressed format. This setting doesn’t affect index * files that are already compressed by default. Defaults to false. */ - Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, false, Setting.Scope.CLUSTER); + Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, false, SettingsProperty.ClusterScope); /** * repositories.s3.storage_class: Sets the S3 storage class type for the backup files. Values may be standard, reduced_redundancy, * standard_ia. Defaults to standard. */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", false, Setting.Scope.CLUSTER); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", false, SettingsProperty.ClusterScope); /** * repositories.s3.canned_acl: The S3 repository supports all S3 canned ACLs : private, public-read, public-read-write, * authenticated-read, log-delivery-write, bucket-owner-read, bucket-owner-full-control. Defaults to private. */ - Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", false, Setting.Scope.CLUSTER); + Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", false, SettingsProperty.ClusterScope); /** * repositories.s3.base_path: Specifies the path within bucket to repository data. Defaults to root directory. */ - Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", false, Setting.Scope.CLUSTER); + Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", false, SettingsProperty.ClusterScope); } /** @@ -140,72 +149,77 @@ public class S3Repository extends BlobStoreRepository { * access_key * @see Repositories#KEY_SETTING */ - Setting KEY_SETTING = Setting.simpleString("access_key", false, Setting.Scope.CLUSTER, true); + Setting KEY_SETTING = + Setting.simpleString("access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * secret_key * @see Repositories#SECRET_SETTING */ - Setting SECRET_SETTING = Setting.simpleString("secret_key", false, Setting.Scope.CLUSTER, true); + Setting SECRET_SETTING = + Setting.simpleString("secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * bucket * @see Repositories#BUCKET_SETTING */ - Setting BUCKET_SETTING = Setting.simpleString("bucket", false, Setting.Scope.CLUSTER); + Setting BUCKET_SETTING = Setting.simpleString("bucket", false, SettingsProperty.ClusterScope); /** * endpoint * @see Repositories#ENDPOINT_SETTING */ - Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", false, Setting.Scope.CLUSTER); + Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", false, SettingsProperty.ClusterScope); /** * protocol * @see Repositories#PROTOCOL_SETTING */ - Setting PROTOCOL_SETTING = new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, Setting.Scope.CLUSTER); + Setting PROTOCOL_SETTING = + new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); /** * region * @see Repositories#REGION_SETTING */ - Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), false, Setting.Scope.CLUSTER); + Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); /** * server_side_encryption * @see Repositories#SERVER_SIDE_ENCRYPTION_SETTING */ - Setting SERVER_SIDE_ENCRYPTION_SETTING = Setting.boolSetting("server_side_encryption", false, false, Setting.Scope.CLUSTER); + Setting SERVER_SIDE_ENCRYPTION_SETTING = + Setting.boolSetting("server_side_encryption", false, false, SettingsProperty.ClusterScope); /** * buffer_size * @see Repositories#BUFFER_SIZE_SETTING */ - Setting BUFFER_SIZE_SETTING = Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, Setting.Scope.CLUSTER); + Setting BUFFER_SIZE_SETTING = + Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, SettingsProperty.ClusterScope); /** * max_retries * @see Repositories#MAX_RETRIES_SETTING */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, false, Setting.Scope.CLUSTER); + Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, false, SettingsProperty.ClusterScope); /** * chunk_size * @see Repositories#CHUNK_SIZE_SETTING */ - Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", false, Setting.Scope.CLUSTER); + Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", false, SettingsProperty.ClusterScope); /** * compress * @see Repositories#COMPRESS_SETTING */ - Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, Setting.Scope.CLUSTER); + Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); /** * storage_class * @see Repositories#STORAGE_CLASS_SETTING */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", false, Setting.Scope.CLUSTER); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", false, SettingsProperty.ClusterScope); /** * canned_acl * @see Repositories#CANNED_ACL_SETTING */ - Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", false, Setting.Scope.CLUSTER); + Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", false, SettingsProperty.ClusterScope); /** * base_path * @see Repositories#BASE_PATH_SETTING */ - Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, Setting.Scope.CLUSTER); + Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, SettingsProperty.ClusterScope); } private final S3BlobStore blobStore; diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index a3161f4090f..4273c202779 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -77,6 +77,7 @@ import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -268,7 +269,8 @@ public abstract class ESIntegTestCase extends ESTestCase { * The value of this seed can be used to initialize a random context for a specific index. * It's set once per test via a generic index template. */ - public static final Setting INDEX_TEST_SEED_SETTING = Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, false, Setting.Scope.INDEX); + public static final Setting INDEX_TEST_SEED_SETTING = + Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, false, SettingsProperty.IndexScope); /** * A boolean value to enable or disable mock modules. This is useful to test the diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java index 64719f0f9de..4b4692be90c 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java @@ -20,6 +20,7 @@ package org.elasticsearch.test; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; @@ -34,9 +35,12 @@ public final class InternalSettingsPlugin extends Plugin { return "a plugin that allows to set values for internal settings which are can't be set via the ordinary API without this pluging installed"; } - public static final Setting VERSION_CREATED = Setting.intSetting("index.version.created", 0, false, Setting.Scope.INDEX); - public static final Setting MERGE_ENABLED = Setting.boolSetting("index.merge.enabled", true, false, Setting.Scope.INDEX); - public static final Setting INDEX_CREATION_DATE_SETTING = Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, false, Setting.Scope.INDEX); + public static final Setting VERSION_CREATED = + Setting.intSetting("index.version.created", 0, false, SettingsProperty.IndexScope); + public static final Setting MERGE_ENABLED = + Setting.boolSetting("index.merge.enabled", true, false, SettingsProperty.IndexScope); + public static final Setting INDEX_CREATION_DATE_SETTING = + Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, false, SettingsProperty.IndexScope); public void onModule(SettingsModule module) { module.registerSetting(VERSION_CREATED); diff --git a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java index 13f533a583e..b94e7c7e854 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java +++ b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java @@ -22,6 +22,7 @@ import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.index.Index; @@ -63,7 +64,7 @@ public final class MockIndexEventListener { /** * For tests to pass in to fail on listener invocation */ - public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, false, Setting.Scope.INDEX); + public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, false, SettingsProperty.IndexScope); public void onModule(SettingsModule module) { module.registerSetting(INDEX_FAIL); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java index ddccfe88e38..cde26a5b55f 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java +++ b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java @@ -31,6 +31,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.engine.EngineConfig; @@ -55,11 +56,13 @@ public final class MockEngineSupport { * Allows tests to wrap an index reader randomly with a given ratio. This is disabled by default ie. 0.0d since reader wrapping is insanely * slow if {@link org.apache.lucene.index.AssertingDirectoryReader} is used. */ - public static final Setting WRAP_READER_RATIO = Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, false, Setting.Scope.INDEX); + public static final Setting WRAP_READER_RATIO = + Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, false, SettingsProperty.IndexScope); /** * Allows tests to prevent an engine from being flushed on close ie. to test translog recovery... */ - public static final Setting DISABLE_FLUSH_ON_CLOSE = Setting.boolSetting("index.mock.disable_flush_on_close", false, false, Setting.Scope.INDEX); + public static final Setting DISABLE_FLUSH_ON_CLOSE = + Setting.boolSetting("index.mock.disable_flush_on_close", false, false, SettingsProperty.IndexScope); private final AtomicBoolean closing = new AtomicBoolean(false); diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java index ef3be122cdb..6f0e6d51d10 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java +++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java @@ -39,6 +39,7 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; @@ -57,17 +58,20 @@ import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Arrays; -import java.util.Collections; import java.util.Random; -import java.util.Set; public class MockFSDirectoryService extends FsDirectoryService { - public static final Setting RANDOM_IO_EXCEPTION_RATE_ON_OPEN_SETTING = Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d, 0.0d, false, Setting.Scope.INDEX); - public static final Setting RANDOM_IO_EXCEPTION_RATE_SETTING = Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d, 0.0d, false, Setting.Scope.INDEX); - public static final Setting RANDOM_PREVENT_DOUBLE_WRITE_SETTING = Setting.boolSetting("index.store.mock.random.prevent_double_write", true, false, Setting.Scope.INDEX);// true is default in MDW - public static final Setting RANDOM_NO_DELETE_OPEN_FILE_SETTING = Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, false, Setting.Scope.INDEX);// true is default in MDW - public static final Setting CRASH_INDEX_SETTING = Setting.boolSetting("index.store.mock.random.crash_index", true, false, Setting.Scope.INDEX);// true is default in MDW + public static final Setting RANDOM_IO_EXCEPTION_RATE_ON_OPEN_SETTING = + Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d, 0.0d, false, SettingsProperty.IndexScope); + public static final Setting RANDOM_IO_EXCEPTION_RATE_SETTING = + Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d, 0.0d, false, SettingsProperty.IndexScope); + public static final Setting RANDOM_PREVENT_DOUBLE_WRITE_SETTING = + Setting.boolSetting("index.store.mock.random.prevent_double_write", true, false, SettingsProperty.IndexScope);// true is default in MDW + public static final Setting RANDOM_NO_DELETE_OPEN_FILE_SETTING = + Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, false, SettingsProperty.IndexScope);// true is default in MDW + public static final Setting CRASH_INDEX_SETTING = + Setting.boolSetting("index.store.mock.random.crash_index", true, false, SettingsProperty.IndexScope);// true is default in MDW private final FsDirectoryService delegateService; private final Random random; diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java index 80251d54951..8d1a2beed89 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java +++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.index.IndexModule; @@ -44,7 +45,8 @@ import java.util.Map; public class MockFSIndexStore extends IndexStore { - public static final Setting INDEX_CHECK_INDEX_ON_CLOSE_SETTING = Setting.boolSetting("index.store.mock.check_index_on_close", true, false, Setting.Scope.INDEX); + public static final Setting INDEX_CHECK_INDEX_ON_CLOSE_SETTING = + Setting.boolSetting("index.store.mock.check_index_on_close", true, false, SettingsProperty.IndexScope); public static class TestPlugin extends Plugin { @Override diff --git a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java index 4c48f990d6a..bdafa98b6ac 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java +++ b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java @@ -20,6 +20,7 @@ package org.elasticsearch.test.tasks; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskManager; @@ -33,7 +34,8 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class MockTaskManager extends TaskManager { - public static final Setting USE_MOCK_TASK_MANAGER_SETTING = Setting.boolSetting("tests.mock.taskmanager.enabled", false, false, Setting.Scope.CLUSTER); + public static final Setting USE_MOCK_TASK_MANAGER_SETTING = + Setting.boolSetting("tests.mock.taskmanager.enabled", false, false, SettingsProperty.ClusterScope); private final Collection listeners = new CopyOnWriteArrayList<>(); diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java index fb310239155..49a89977e95 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java +++ b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; @@ -67,10 +68,12 @@ public class AssertingLocalTransport extends LocalTransport { } } - public static final Setting ASSERTING_TRANSPORT_MIN_VERSION_KEY = new Setting<>("transport.asserting.version.min", - Integer.toString(Version.CURRENT.minimumCompatibilityVersion().id), (s) -> Version.fromId(Integer.parseInt(s)), false, Setting.Scope.CLUSTER); - public static final Setting ASSERTING_TRANSPORT_MAX_VERSION_KEY = new Setting<>("transport.asserting.version.max", - Integer.toString(Version.CURRENT.id), (s) -> Version.fromId(Integer.parseInt(s)), false, Setting.Scope.CLUSTER); + public static final Setting ASSERTING_TRANSPORT_MIN_VERSION_KEY = + new Setting<>("transport.asserting.version.min", Integer.toString(Version.CURRENT.minimumCompatibilityVersion().id), + (s) -> Version.fromId(Integer.parseInt(s)), false, SettingsProperty.ClusterScope); + public static final Setting ASSERTING_TRANSPORT_MAX_VERSION_KEY = + new Setting<>("transport.asserting.version.max", Integer.toString(Version.CURRENT.id), + (s) -> Version.fromId(Integer.parseInt(s)), false, SettingsProperty.ClusterScope); private final Random random; private final Version minVersion; private final Version maxVersion; From d77daf386124ea90acfb9a1dd5a8e1d262a33325 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Sun, 28 Feb 2016 11:06:45 +0100 Subject: [PATCH 04/49] Use an SettingsProperty.Dynamic for dynamic properties --- .../close/TransportCloseIndexAction.java | 2 +- .../action/support/AutoCreateIndex.java | 2 +- .../action/support/DestructiveOperations.java | 2 +- .../master/TransportMasterNodeReadAction.java | 2 +- .../bootstrap/BootstrapSettings.java | 8 +- .../cache/recycler/PageCacheRecycler.java | 12 +- .../java/org/elasticsearch/client/Client.java | 2 +- .../TransportClientNodesService.java | 8 +- .../elasticsearch/cluster/ClusterModule.java | 2 +- .../elasticsearch/cluster/ClusterName.java | 2 +- .../cluster/InternalClusterInfoService.java | 7 +- .../action/index/MappingUpdatedAction.java | 3 +- .../cluster/metadata/AutoExpandReplicas.java | 2 +- .../cluster/metadata/IndexMetaData.java | 28 ++-- .../cluster/metadata/MetaData.java | 2 +- .../cluster/routing/UnassignedInfo.java | 2 +- .../allocator/BalancedShardsAllocator.java | 7 +- .../decider/AwarenessAllocationDecider.java | 4 +- .../ClusterRebalanceAllocationDecider.java | 2 +- .../ConcurrentRebalanceAllocationDecider.java | 3 +- .../decider/DiskThresholdDecider.java | 17 +- .../decider/EnableAllocationDecider.java | 12 +- .../decider/FilterAllocationDecider.java | 6 +- .../decider/ShardsLimitAllocationDecider.java | 6 +- .../SnapshotInProgressAllocationDecider.java | 3 +- .../decider/ThrottlingAllocationDecider.java | 14 +- .../service/InternalClusterService.java | 7 +- .../common/logging/ESLoggerFactory.java | 5 +- .../common/network/NetworkModule.java | 9 +- .../common/network/NetworkService.java | 26 +-- .../common/settings/IndexScopedSettings.java | 4 +- .../common/settings/Setting.java | 153 ++++++++++-------- .../common/util/concurrent/EsExecutors.java | 2 +- .../common/util/concurrent/ThreadContext.java | 3 +- .../discovery/DiscoveryModule.java | 4 +- .../discovery/DiscoveryService.java | 5 +- .../discovery/DiscoverySettings.java | 12 +- .../discovery/zen/ZenDiscovery.java | 18 +-- .../zen/elect/ElectMasterService.java | 2 +- .../discovery/zen/fd/FaultDetection.java | 10 +- .../zen/ping/unicast/UnicastZenPing.java | 4 +- .../org/elasticsearch/env/Environment.java | 19 ++- .../elasticsearch/env/NodeEnvironment.java | 10 +- .../elasticsearch/gateway/GatewayService.java | 14 +- .../gateway/PrimaryShardAllocator.java | 6 +- .../http/HttpTransportSettings.java | 42 ++--- .../http/netty/NettyHttpServerTransport.java | 26 ++- .../org/elasticsearch/index/IndexModule.java | 6 +- .../elasticsearch/index/IndexSettings.java | 30 ++-- .../org/elasticsearch/index/IndexWarmer.java | 2 +- .../elasticsearch/index/IndexingSlowLog.java | 14 +- .../index/MergePolicyConfig.java | 26 +-- .../index/MergeSchedulerConfig.java | 6 +- .../elasticsearch/index/SearchSlowLog.java | 20 +-- .../index/cache/bitset/BitsetFilterCache.java | 2 +- .../index/engine/EngineConfig.java | 2 +- .../fielddata/IndexFieldDataService.java | 2 +- .../index/mapper/FieldMapper.java | 4 +- .../index/mapper/MapperService.java | 4 +- .../index/mapper/core/NumberFieldMapper.java | 2 +- .../percolator/PercolatorQueriesRegistry.java | 2 +- .../index/store/FsDirectoryService.java | 2 +- .../elasticsearch/index/store/IndexStore.java | 6 +- .../index/store/IndexStoreConfig.java | 7 +- .../org/elasticsearch/index/store/Store.java | 2 +- .../indices/IndicesQueryCache.java | 4 +- .../indices/IndicesRequestCache.java | 6 +- .../elasticsearch/indices/IndicesService.java | 2 +- .../indices/analysis/HunspellService.java | 6 +- .../HierarchyCircuitBreakerService.java | 14 +- .../cache/IndicesFieldDataCache.java | 2 +- .../indices/recovery/RecoverySettings.java | 22 +-- .../indices/store/IndicesStore.java | 2 +- .../indices/ttl/IndicesTTLService.java | 3 +- .../elasticsearch/monitor/fs/FsService.java | 2 +- .../monitor/jvm/JvmGcMonitorService.java | 6 +- .../elasticsearch/monitor/jvm/JvmService.java | 2 +- .../elasticsearch/monitor/os/OsService.java | 2 +- .../monitor/process/ProcessService.java | 2 +- .../java/org/elasticsearch/node/Node.java | 18 +-- .../internal/InternalSettingsPreparer.java | 2 +- .../elasticsearch/plugins/PluginsService.java | 2 +- .../repositories/fs/FsRepository.java | 12 +- .../repositories/uri/URLRepository.java | 14 +- .../elasticsearch/rest/BaseRestHandler.java | 2 +- .../elasticsearch/script/ScriptService.java | 6 +- .../elasticsearch/script/ScriptSettings.java | 5 +- .../elasticsearch/search/SearchService.java | 6 +- .../elasticsearch/threadpool/ThreadPool.java | 2 +- .../elasticsearch/transport/Transport.java | 2 +- .../transport/TransportService.java | 4 +- .../transport/TransportSettings.java | 12 +- .../transport/netty/NettyTransport.java | 43 +++-- .../org/elasticsearch/tribe/TribeService.java | 17 +- .../cluster/ClusterModuleTests.java | 4 +- .../cluster/settings/SettingsFilteringIT.java | 6 +- .../common/settings/ScopedSettingsTests.java | 24 +-- .../common/settings/SettingTests.java | 49 +++--- .../common/settings/SettingsModuleTests.java | 10 +- .../elasticsearch/index/IndexModuleTests.java | 4 +- .../index/IndexSettingsTests.java | 11 +- .../index/SettingsListenerIT.java | 6 +- .../indices/IndicesOptionsIntegrationIT.java | 6 +- .../RandomExceptionCircuitBreakerIT.java | 4 +- .../basic/SearchWithRandomExceptionsIT.java | 4 +- .../snapshots/mockstore/MockRepository.java | 5 +- .../azure/management/AzureComputeService.java | 15 +- .../cloud/aws/AwsEc2Service.java | 53 +++--- .../mapper/attachments/AttachmentMapper.java | 6 +- .../azure/storage/AzureStorageService.java | 14 +- .../repositories/azure/AzureRepository.java | 15 +- .../elasticsearch/cloud/aws/AwsS3Service.java | 39 +++-- .../repositories/s3/S3Repository.java | 58 ++++--- .../elasticsearch/test/ESIntegTestCase.java | 2 +- .../test/InternalSettingsPlugin.java | 6 +- .../test/MockIndexEventListener.java | 2 +- .../test/engine/MockEngineSupport.java | 4 +- .../test/store/MockFSDirectoryService.java | 10 +- .../test/store/MockFSIndexStore.java | 2 +- .../test/tasks/MockTaskManager.java | 2 +- .../transport/AssertingLocalTransport.java | 4 +- 121 files changed, 647 insertions(+), 620 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java index 82602a10c00..6065a2ec66e 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java @@ -48,7 +48,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeAction CLUSTER_INDICES_CLOSE_ENABLE_SETTING = - Setting.boolSetting("cluster.indices.close.enable", true, true, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.indices.close.enable", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); @Inject public TransportCloseIndexAction(Settings settings, TransportService transportService, ClusterService clusterService, diff --git a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java index ee304dd05f2..2169d3a1521 100644 --- a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java +++ b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java @@ -41,7 +41,7 @@ import java.util.List; public final class AutoCreateIndex { public static final Setting AUTO_CREATE_INDEX_SETTING = - new Setting<>("action.auto_create_index", "true", AutoCreate::new, false, SettingsProperty.ClusterScope); + new Setting<>("action.auto_create_index", "true", AutoCreate::new, SettingsProperty.ClusterScope); private final boolean dynamicMappingDisabled; private final IndexNameExpressionResolver resolver; diff --git a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java index cfdd45cdfa1..6591384271b 100644 --- a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java +++ b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java @@ -35,7 +35,7 @@ public final class DestructiveOperations extends AbstractComponent { * Setting which controls whether wildcard usage (*, prefix*, _all) is allowed. */ public static final Setting REQUIRES_NAME_SETTING = - Setting.boolSetting("action.destructive_requires_name", false, true, SettingsProperty.ClusterScope); + Setting.boolSetting("action.destructive_requires_name", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile boolean destructiveRequiresName; @Inject diff --git a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java index 5c15acbbdca..08ba0defd73 100644 --- a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java +++ b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java @@ -39,7 +39,7 @@ public abstract class TransportMasterNodeReadAction { public static final Setting FORCE_LOCAL_SETTING = - Setting.boolSetting("action.master.force_local", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("action.master.force_local", false, SettingsProperty.ClusterScope); private final boolean forceLocal; diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java index 9c0bdcbd2c9..dd9263330e6 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java @@ -29,13 +29,13 @@ public final class BootstrapSettings { // TODO: remove this hack when insecure defaults are removed from java public static final Setting SECURITY_FILTER_BAD_DEFAULTS_SETTING = - Setting.boolSetting("security.manager.filter_bad_defaults", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("security.manager.filter_bad_defaults", true, SettingsProperty.ClusterScope); public static final Setting MLOCKALL_SETTING = - Setting.boolSetting("bootstrap.mlockall", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.mlockall", false, SettingsProperty.ClusterScope); public static final Setting SECCOMP_SETTING = - Setting.boolSetting("bootstrap.seccomp", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.seccomp", true, SettingsProperty.ClusterScope); public static final Setting CTRLHANDLER_SETTING = - Setting.boolSetting("bootstrap.ctrlhandler", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.ctrlhandler", true, SettingsProperty.ClusterScope); } diff --git a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java index 9cec74115f6..f58947409e9 100644 --- a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java +++ b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java @@ -45,18 +45,18 @@ import static org.elasticsearch.common.recycler.Recyclers.none; public class PageCacheRecycler extends AbstractComponent implements Releasable { public static final Setting TYPE_SETTING = - new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, false, SettingsProperty.ClusterScope); + new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, SettingsProperty.ClusterScope); public static final Setting LIMIT_HEAP_SETTING = - Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", SettingsProperty.ClusterScope); public static final Setting WEIGHT_BYTES_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, false, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, SettingsProperty.ClusterScope); public static final Setting WEIGHT_LONG_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, false, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, SettingsProperty.ClusterScope); public static final Setting WEIGHT_INT_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, false, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, SettingsProperty.ClusterScope); // object pages are less useful to us so we give them a lower weight by default public static final Setting WEIGHT_OBJECTS_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, false, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, SettingsProperty.ClusterScope); private final Recycler bytePage; private final Recycler intPage; diff --git a/core/src/main/java/org/elasticsearch/client/Client.java b/core/src/main/java/org/elasticsearch/client/Client.java index 859a15e2c5b..1ced0f2b019 100644 --- a/core/src/main/java/org/elasticsearch/client/Client.java +++ b/core/src/main/java/org/elasticsearch/client/Client.java @@ -115,7 +115,7 @@ public interface Client extends ElasticsearchClient, Releasable { default: throw new IllegalArgumentException("Can't parse [client.type] must be one of [node, transport]"); } - }, false, SettingsProperty.ClusterScope); + }, SettingsProperty.ClusterScope); /** * The admin client that can be used to perform administrative operations. diff --git a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java index 2e495633329..28c921333ca 100644 --- a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java +++ b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java @@ -102,13 +102,13 @@ public class TransportClientNodesService extends AbstractComponent { public static final Setting CLIENT_TRANSPORT_NODES_SAMPLER_INTERVAL = - Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), SettingsProperty.ClusterScope); public static final Setting CLIENT_TRANSPORT_PING_TIMEOUT = - Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), SettingsProperty.ClusterScope); public static final Setting CLIENT_TRANSPORT_IGNORE_CLUSTER_NAME = - Setting.boolSetting("client.transport.ignore_cluster_name", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("client.transport.ignore_cluster_name", false, SettingsProperty.ClusterScope); public static final Setting CLIENT_TRANSPORT_SNIFF = - Setting.boolSetting("client.transport.sniff", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("client.transport.sniff", false, SettingsProperty.ClusterScope); @Inject public TransportClientNodesService(Settings settings, ClusterName clusterName, TransportService transportService, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java index ec27ed3a4d4..c57549236e8 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java @@ -76,7 +76,7 @@ public class ClusterModule extends AbstractModule { public static final String EVEN_SHARD_COUNT_ALLOCATOR = "even_shard"; public static final String BALANCED_ALLOCATOR = "balanced"; // default public static final Setting SHARDS_ALLOCATOR_TYPE_SETTING = - new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), SettingsProperty.ClusterScope); public static final List> DEFAULT_ALLOCATION_DECIDERS = Collections.unmodifiableList(Arrays.asList( SameShardAllocationDecider.class, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java index 9012b9b0278..185c68e075c 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java @@ -38,7 +38,7 @@ public class ClusterName implements Streamable { throw new IllegalArgumentException("[cluster.name] must not be empty"); } return s; - }, false, SettingsProperty.ClusterScope); + }, SettingsProperty.ClusterScope); public static final ClusterName DEFAULT = new ClusterName(CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY).intern()); diff --git a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java index e6d9c27c1c2..32f521a6782 100644 --- a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java +++ b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java @@ -66,10 +66,11 @@ import java.util.concurrent.TimeUnit; public class InternalClusterInfoService extends AbstractComponent implements ClusterInfoService, LocalNodeMasterListener, ClusterStateListener { public static final Setting INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING = - Setting.timeSetting("cluster.info.update.interval", TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(10), true, - SettingsProperty.ClusterScope); + Setting.timeSetting("cluster.info.update.interval", TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(10), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING = - Setting.positiveTimeSetting("cluster.info.update.timeout", TimeValue.timeValueSeconds(15), true, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("cluster.info.update.timeout", TimeValue.timeValueSeconds(15), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile TimeValue updateFrequency; diff --git a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java index 647f5df1cd4..4005631d5af 100644 --- a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java +++ b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java @@ -43,7 +43,8 @@ import java.util.concurrent.TimeoutException; public class MappingUpdatedAction extends AbstractComponent { public static final Setting INDICES_MAPPING_DYNAMIC_TIMEOUT_SETTING = - Setting.positiveTimeSetting("indices.mapping.dynamic_timeout", TimeValue.timeValueSeconds(30), true, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.mapping.dynamic_timeout", TimeValue.timeValueSeconds(30), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private IndicesAdminClient client; private volatile TimeValue dynamicMappingUpdateTimeout; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java index dac44814a92..9a8499832ea 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java @@ -57,7 +57,7 @@ final class AutoExpandReplicas { } } return new AutoExpandReplicas(min, max, true); - }, true, SettingsProperty.IndexScope); + }, SettingsProperty.Dynamic, SettingsProperty.IndexScope); private final int minReplicas; private final int maxReplicas; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index f9982384d6e..37e0ad97002 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -154,35 +154,35 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String INDEX_SETTING_PREFIX = "index."; public static final String SETTING_NUMBER_OF_SHARDS = "index.number_of_shards"; public static final Setting INDEX_NUMBER_OF_SHARDS_SETTING = - Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, false, SettingsProperty.IndexScope); + Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, SettingsProperty.IndexScope); public static final String SETTING_NUMBER_OF_REPLICAS = "index.number_of_replicas"; public static final Setting INDEX_NUMBER_OF_REPLICAS_SETTING = - Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, true, SettingsProperty.IndexScope); + Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_SHADOW_REPLICAS = "index.shadow_replicas"; public static final Setting INDEX_SHADOW_REPLICAS_SETTING = - Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, false, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, SettingsProperty.IndexScope); public static final String SETTING_SHARED_FILESYSTEM = "index.shared_filesystem"; public static final Setting INDEX_SHARED_FILESYSTEM_SETTING = - Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, false, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, SettingsProperty.IndexScope); public static final String SETTING_AUTO_EXPAND_REPLICAS = "index.auto_expand_replicas"; public static final Setting INDEX_AUTO_EXPAND_REPLICAS_SETTING = AutoExpandReplicas.SETTING; public static final String SETTING_READ_ONLY = "index.blocks.read_only"; public static final Setting INDEX_READ_ONLY_SETTING = - Setting.boolSetting(SETTING_READ_ONLY, false, true, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_READ_ONLY, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_READ = "index.blocks.read"; public static final Setting INDEX_BLOCKS_READ_SETTING = - Setting.boolSetting(SETTING_BLOCKS_READ, false, true, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_READ, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_WRITE = "index.blocks.write"; public static final Setting INDEX_BLOCKS_WRITE_SETTING = - Setting.boolSetting(SETTING_BLOCKS_WRITE, false, true, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_WRITE, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_BLOCKS_METADATA = "index.blocks.metadata"; public static final Setting INDEX_BLOCKS_METADATA_SETTING = - Setting.boolSetting(SETTING_BLOCKS_METADATA, false, true, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_METADATA, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_VERSION_CREATED = "index.version.created"; public static final String SETTING_VERSION_CREATED_STRING = "index.version.created_string"; @@ -192,23 +192,23 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String SETTING_CREATION_DATE = "index.creation_date"; public static final String SETTING_PRIORITY = "index.priority"; public static final Setting INDEX_PRIORITY_SETTING = - Setting.intSetting("index.priority", 1, 0, true, SettingsProperty.IndexScope); + Setting.intSetting("index.priority", 1, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string"; public static final String SETTING_INDEX_UUID = "index.uuid"; public static final String SETTING_DATA_PATH = "index.data_path"; public static final Setting INDEX_DATA_PATH_SETTING = - new Setting<>(SETTING_DATA_PATH, "", Function.identity(), false, SettingsProperty.IndexScope); + new Setting<>(SETTING_DATA_PATH, "", Function.identity(), SettingsProperty.IndexScope); public static final String SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE = "index.shared_filesystem.recover_on_any_node"; public static final Setting INDEX_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE_SETTING = - Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, true, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String INDEX_UUID_NA_VALUE = "_na_"; public static final Setting INDEX_ROUTING_REQUIRE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.require.", true, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.require.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_ROUTING_INCLUDE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.include.", true, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.include.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_ROUTING_EXCLUDE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.exclude.", true, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.exclude.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final IndexMetaData PROTO = IndexMetaData.builder("") .settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index f729cc4cabc..d74cf06c533 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -141,7 +141,7 @@ public class MetaData implements Iterable, Diffable, Fr public static final Setting SETTING_READ_ONLY_SETTING = - Setting.boolSetting("cluster.blocks.read_only", false, true, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.blocks.read_only", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE)); diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java index d7cfe1a39d9..1b7fcf96779 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java @@ -46,7 +46,7 @@ public class UnassignedInfo implements ToXContent, Writeable { private static final TimeValue DEFAULT_DELAYED_NODE_LEFT_TIMEOUT = TimeValue.timeValueMinutes(1); public static final Setting INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING = - Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, true, + Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, SettingsProperty.Dynamic, SettingsProperty.IndexScope); /** diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java index 248d5aa25c9..ccbf47b675e 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java @@ -74,11 +74,12 @@ import static org.elasticsearch.cluster.routing.ShardRoutingState.RELOCATING; public class BalancedShardsAllocator extends AbstractComponent implements ShardsAllocator { public static final Setting INDEX_BALANCE_FACTOR_SETTING = - Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, true, SettingsProperty.ClusterScope); + Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting SHARD_BALANCE_FACTOR_SETTING = - Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, true, SettingsProperty.ClusterScope); + Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting THRESHOLD_SETTING = - Setting.floatSetting("cluster.routing.allocation.balance.threshold", 1.0f, 0.0f, true, SettingsProperty.ClusterScope); + Setting.floatSetting("cluster.routing.allocation.balance.threshold", 1.0f, 0.0f, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile WeightFunction weightFunction; private volatile float threshold; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java index 792f670dcf2..235cfd84186 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java @@ -79,10 +79,10 @@ public class AwarenessAllocationDecider extends AllocationDecider { public static final String NAME = "awareness"; public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING = - new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , true, + new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.awareness.force.", true, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.awareness.force.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private String[] awarenessAttributes; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java index 2c59fee3af6..58966dd62a6 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java @@ -51,7 +51,7 @@ public class ClusterRebalanceAllocationDecider extends AllocationDecider { public static final String NAME = "cluster_rebalance"; public static final Setting CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING = new Setting<>("cluster.routing.allocation.allow_rebalance", ClusterRebalanceType.INDICES_ALL_ACTIVE.name().toLowerCase(Locale.ROOT), - ClusterRebalanceType::parseString, true, SettingsProperty.ClusterScope); + ClusterRebalanceType::parseString, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * An enum representation for the configured re-balance type. diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java index cda5e628dec..cab73958b75 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java @@ -44,7 +44,8 @@ public class ConcurrentRebalanceAllocationDecider extends AllocationDecider { public static final String NAME = "concurrent_rebalance"; public static final Setting CLUSTER_ROUTING_ALLOCATION_CLUSTER_CONCURRENT_REBALANCE_SETTING = - Setting.intSetting("cluster.routing.allocation.cluster_concurrent_rebalance", 2, -1, true, SettingsProperty.ClusterScope); + Setting.intSetting("cluster.routing.allocation.cluster_concurrent_rebalance", 2, -1, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile int clusterConcurrentRebalance; @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java index 051eab81ec8..e8b5a3dba04 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java @@ -83,16 +83,21 @@ public class DiskThresholdDecider extends AllocationDecider { private volatile TimeValue rerouteInterval; public static final Setting CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING = - Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, true, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING = - new Setting<>("cluster.routing.allocation.disk.watermark.low", "85%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.low"), true, SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.disk.watermark.low", "85%", + (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.low"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING = - new Setting<>("cluster.routing.allocation.disk.watermark.high", "90%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.high"), true, SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.disk.watermark.high", "90%", + (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.high"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING = - Setting.boolSetting("cluster.routing.allocation.disk.include_relocations", true, true, SettingsProperty.ClusterScope);; + Setting.boolSetting("cluster.routing.allocation.disk.include_relocations", true, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope);; public static final Setting CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING = - Setting.positiveTimeSetting("cluster.routing.allocation.disk.reroute_interval", TimeValue.timeValueSeconds(60), true, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("cluster.routing.allocation.disk.reroute_interval", TimeValue.timeValueSeconds(60), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * Listens for a node to go over the high watermark and kicks off an empty diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java index edece247c8b..0cca4cac480 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java @@ -62,14 +62,18 @@ public class EnableAllocationDecider extends AllocationDecider { public static final String NAME = "enable"; public static final Setting CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING = - new Setting<>("cluster.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting INDEX_ROUTING_ALLOCATION_ENABLE_SETTING = - new Setting<>("index.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, true, SettingsProperty.IndexScope); + new Setting<>("index.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING = - new Setting<>("cluster.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting INDEX_ROUTING_REBALANCE_ENABLE_SETTING = - new Setting<>("index.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, true, SettingsProperty.IndexScope); + new Setting<>("index.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); private volatile Rebalance enableRebalance; private volatile Allocation enableAllocation; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java index 59f6ec1531a..b4c50d1849b 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java @@ -62,11 +62,11 @@ public class FilterAllocationDecider extends AllocationDecider { public static final String NAME = "filter"; public static final Setting CLUSTER_ROUTING_REQUIRE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.require.", true, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.require.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_INCLUDE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.include.", true, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.include.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.exclude.", true, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.exclude.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile DiscoveryNodeFilters clusterRequireFilters; private volatile DiscoveryNodeFilters clusterIncludeFilters; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java index be6c98d147b..03a383830ce 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java @@ -61,14 +61,16 @@ public class ShardsLimitAllocationDecider extends AllocationDecider { * node. Negative values are interpreted as unlimited. */ public static final Setting INDEX_TOTAL_SHARDS_PER_NODE_SETTING = - Setting.intSetting("index.routing.allocation.total_shards_per_node", -1, -1, true, SettingsProperty.IndexScope); + Setting.intSetting("index.routing.allocation.total_shards_per_node", -1, -1, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); /** * Controls the maximum number of shards per node on a global level. * Negative values are interpreted as unlimited. */ public static final Setting CLUSTER_TOTAL_SHARDS_PER_NODE_SETTING = - Setting.intSetting("cluster.routing.allocation.total_shards_per_node", -1, -1, true, SettingsProperty.ClusterScope); + Setting.intSetting("cluster.routing.allocation.total_shards_per_node", -1, -1, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java index b4927b6c5c7..a9d269d3b3a 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java @@ -41,7 +41,8 @@ public class SnapshotInProgressAllocationDecider extends AllocationDecider { * Disables relocation of shards that are currently being snapshotted. */ public static final Setting CLUSTER_ROUTING_ALLOCATION_SNAPSHOT_RELOCATION_ENABLED_SETTING = - Setting.boolSetting("cluster.routing.allocation.snapshot.relocation_enabled", false, true, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.routing.allocation.snapshot.relocation_enabled", false, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile boolean enableRelocation = false; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java index 1e12eb406b8..64900236291 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java @@ -54,20 +54,22 @@ public class ThrottlingAllocationDecider extends AllocationDecider { public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_recoveries", Integer.toString(DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES), - (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_recoveries"), true, SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_recoveries"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES_SETTING = Setting.intSetting("cluster.routing.allocation.node_initial_primaries_recoveries", - DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES, 0, true, SettingsProperty.ClusterScope); + DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES, 0, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_incoming_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), - (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_incoming_recoveries"), true, - SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_incoming_recoveries"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_outgoing_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), - (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_outgoing_recoveries"), true, - SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_outgoing_recoveries"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile int primariesInitialRecoveries; diff --git a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java index 0b0fd5e2b99..fbf4d0b67e3 100644 --- a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java +++ b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java @@ -95,11 +95,10 @@ import static org.elasticsearch.common.util.concurrent.EsExecutors.daemonThreadF public class InternalClusterService extends AbstractLifecycleComponent implements ClusterService { public static final Setting CLUSTER_SERVICE_SLOW_TASK_LOGGING_THRESHOLD_SETTING = - Setting.positiveTimeSetting("cluster.service.slow_task_logging_threshold", TimeValue.timeValueSeconds(30), true, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("cluster.service.slow_task_logging_threshold", TimeValue.timeValueSeconds(30), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting CLUSTER_SERVICE_RECONNECT_INTERVAL_SETTING = - Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), false, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), SettingsProperty.ClusterScope); public static final String UPDATE_THREAD_NAME = "clusterService#updateTask"; private final ThreadPool threadPool; diff --git a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java index 98d75c86482..a5d8e7e4960 100644 --- a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java +++ b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java @@ -38,9 +38,10 @@ import java.util.regex.Pattern; public abstract class ESLoggerFactory { public static final Setting LOG_DEFAULT_LEVEL_SETTING = - new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, false, SettingsProperty.ClusterScope); + new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, SettingsProperty.ClusterScope); public static final Setting LOG_LEVEL_SETTING = - Setting.dynamicKeySetting("logger.", LogLevel.INFO.name(), LogLevel::parse, true, SettingsProperty.ClusterScope); + Setting.dynamicKeySetting("logger.", LogLevel.INFO.name(), LogLevel::parse, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private static volatile ESLoggerFactory defaultFactory = new JdkESLoggerFactory(); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java index ea2cc1b4267..c79e8dd3af5 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java @@ -155,12 +155,11 @@ public class NetworkModule extends AbstractModule { public static final String LOCAL_TRANSPORT = "local"; public static final String NETTY_TRANSPORT = "netty"; - public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", false, SettingsProperty.ClusterScope); - public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, false, SettingsProperty.ClusterScope); + public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", SettingsProperty.ClusterScope); + public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, SettingsProperty.ClusterScope); public static final Setting TRANSPORT_SERVICE_TYPE_SETTING = - Setting.simpleString("transport.service.type", false, SettingsProperty.ClusterScope); - public static final Setting TRANSPORT_TYPE_SETTING = - Setting.simpleString("transport.type", false, SettingsProperty.ClusterScope); + Setting.simpleString("transport.service.type", SettingsProperty.ClusterScope); + public static final Setting TRANSPORT_TYPE_SETTING = Setting.simpleString("transport.type", SettingsProperty.ClusterScope); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java index abb7795f12a..fc192225222 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java @@ -45,32 +45,32 @@ public class NetworkService extends AbstractComponent { public static final String DEFAULT_NETWORK_HOST = "_local_"; public static final Setting> GLOBAL_NETWORK_HOST_SETTING = - Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), s -> s, false, SettingsProperty.ClusterScope); + Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), s -> s, SettingsProperty.ClusterScope); public static final Setting> GLOBAL_NETWORK_BINDHOST_SETTING = - Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, false, SettingsProperty.ClusterScope); + Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, SettingsProperty.ClusterScope); public static final Setting> GLOBAL_NETWORK_PUBLISHHOST_SETTING = - Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, false, SettingsProperty.ClusterScope); - public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, false, SettingsProperty.ClusterScope); + Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, SettingsProperty.ClusterScope); + public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, SettingsProperty.ClusterScope); public static final class TcpSettings { public static final Setting TCP_NO_DELAY = - Setting.boolSetting("network.tcp.no_delay", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.no_delay", true, SettingsProperty.ClusterScope); public static final Setting TCP_KEEP_ALIVE = - Setting.boolSetting("network.tcp.keep_alive", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.keep_alive", true, SettingsProperty.ClusterScope); public static final Setting TCP_REUSE_ADDRESS = - Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), SettingsProperty.ClusterScope); public static final Setting TCP_SEND_BUFFER_SIZE = - Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); public static final Setting TCP_RECEIVE_BUFFER_SIZE = - Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); public static final Setting TCP_BLOCKING = - Setting.boolSetting("network.tcp.blocking", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking", false, SettingsProperty.ClusterScope); public static final Setting TCP_BLOCKING_SERVER = - Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, SettingsProperty.ClusterScope); public static final Setting TCP_BLOCKING_CLIENT = - Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, SettingsProperty.ClusterScope); public static final Setting TCP_CONNECT_TIMEOUT = - Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), false, SettingsProperty.ClusterScope); + Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), SettingsProperty.ClusterScope); } /** diff --git a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index a8f06fd9cf5..ae056460cd8 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -135,8 +135,8 @@ public final class IndexScopedSettings extends AbstractScopedSettings { EngineConfig.INDEX_CODEC_SETTING, IndexWarmer.INDEX_NORMS_LOADING_SETTING, // this sucks but we can't really validate all the analyzers/similarity in here - Setting.groupSetting("index.similarity.", false, SettingsProperty.IndexScope), // this allows similarity settings to be passed - Setting.groupSetting("index.analysis.", false, SettingsProperty.IndexScope) // this allows analysis settings to be passed + Setting.groupSetting("index.similarity.", SettingsProperty.IndexScope), // this allows similarity settings to be passed + Setting.groupSetting("index.analysis.", SettingsProperty.IndexScope) // this allows analysis settings to be passed ))); diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index ce66eda1766..ce20c521932 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -47,12 +47,12 @@ import java.util.stream.Collectors; /** * A setting. Encapsulates typical stuff like default value, parsing, and scope. - * Some (dynamic=true) can by modified at run time using the API. + * Some (SettingsProperty.Dynamic) can by modified at run time using the API. * All settings inside elasticsearch or in any of the plugins should use this type-safe and generic settings infrastructure * together with {@link AbstractScopedSettings}. This class contains several utility methods that makes it straight forward * to add settings for the majority of the cases. For instance a simple boolean settings can be defined like this: *
{@code
- * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, false, SettingsProperty.ClusterScope);}
+ * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, SettingsProperty.ClusterScope);}
  * 
* To retrieve the value of the setting a {@link Settings} object can be passed directly to the {@link Setting#get(Settings)} method. *
@@ -64,24 +64,48 @@ import java.util.stream.Collectors;
  *     RED, GREEN, BLUE;
  * }
  * public static final Setting MY_BOOLEAN =
- *     new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, false, SettingsProperty.ClusterScope);
+ *     new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, SettingsProperty.ClusterScope);
  * }
  * 
*/ public class Setting extends ToXContentToBytes { public enum SettingsProperty { + /** + * should be filtered in some api (mask password/credentials) + */ Filtered, + + /** + * iff this setting can be dynamically updateable + */ Dynamic, + + /** + * Cluster scope. + * @See IndexScope + * @See NodeScope + */ ClusterScope, + + /** + * Node scope. + * @See ClusterScope + * @See IndexScope + */ NodeScope, + + /** + * Index scope. + * @See ClusterScope + * @See NodeScope + */ IndexScope; } private final String key; protected final Function defaultValue; private final Function parser; - private final boolean dynamic; private final EnumSet properties; /** @@ -89,16 +113,13 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Function defaultValue, Function parser, boolean dynamic, - SettingsProperty... properties) { + public Setting(String key, Function defaultValue, Function parser, SettingsProperty... properties) { assert parser.apply(defaultValue.apply(Settings.EMPTY)) != null || this.isGroupSetting(): "parser returned null"; this.key = key; this.defaultValue = defaultValue; this.parser = parser; - this.dynamic = dynamic; if (properties.length == 0) { this.properties = EnumSet.of(SettingsProperty.NodeScope); } else { @@ -111,11 +132,10 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param defaultValue a default value. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, String defaultValue, Function parser, boolean dynamic, SettingsProperty... properties) { - this(key, s -> defaultValue, parser, dynamic, properties); + public Setting(String key, String defaultValue, Function parser, SettingsProperty... properties) { + this(key, s -> defaultValue, parser, properties); } /** @@ -123,11 +143,10 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param fallBackSetting a setting to fall back to if the current setting is not set. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Setting fallBackSetting, Function parser, boolean dynamic, SettingsProperty... properties) { - this(key, fallBackSetting::getRaw, parser, dynamic, properties); + public Setting(String key, Setting fallBackSetting, Function parser, SettingsProperty... properties) { + this(key, fallBackSetting::getRaw, parser, properties); } /** @@ -145,7 +164,7 @@ public class Setting extends ToXContentToBytes { * Returns true if this setting is dynamically updateable, otherwise false */ public final boolean isDynamic() { - return dynamic; + return properties.contains(SettingsProperty.Dynamic); } /** @@ -261,7 +280,6 @@ public class Setting extends ToXContentToBytes { builder.startObject(); builder.field("key", key); builder.field("properties", properties); - builder.field("dynamic", dynamic); builder.field("is_group_setting", isGroupSetting()); builder.field("default", defaultValue.apply(Settings.EMPTY)); builder.endObject(); @@ -380,35 +398,34 @@ public class Setting extends ToXContentToBytes { } - public static Setting floatSetting(String key, float defaultValue, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> Float.toString(defaultValue), Float::parseFloat, dynamic, properties); + public static Setting floatSetting(String key, float defaultValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Float.toString(defaultValue), Float::parseFloat, properties); } - public static Setting floatSetting(String key, float defaultValue, float minValue, boolean dynamic, SettingsProperty... properties) { + public static Setting floatSetting(String key, float defaultValue, float minValue, SettingsProperty... properties) { return new Setting<>(key, (s) -> Float.toString(defaultValue), (s) -> { float value = Float.parseFloat(s); if (value < minValue) { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return value; - }, dynamic, properties); + }, properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, boolean dynamic, - SettingsProperty... properties) { - return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, maxValue, key), dynamic, properties); + public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, maxValue, key), properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key), dynamic, properties); + public static Setting intSetting(String key, int defaultValue, int minValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key), properties); } - public static Setting longSetting(String key, long defaultValue, long minValue, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), dynamic, properties); + public static Setting longSetting(String key, long defaultValue, long minValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), properties); } - public static Setting simpleString(String key, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, s -> "", Function.identity(), dynamic, properties); + public static Setting simpleString(String key, SettingsProperty... properties) { + return new Setting<>(key, s -> "", Function.identity(), properties); } public static int parseInt(String s, int minValue, String key) { @@ -434,58 +451,57 @@ public class Setting extends ToXContentToBytes { return value; } - public static Setting intSetting(String key, int defaultValue, boolean dynamic, SettingsProperty... properties) { - return intSetting(key, defaultValue, Integer.MIN_VALUE, dynamic, properties); + public static Setting intSetting(String key, int defaultValue, SettingsProperty... properties) { + return intSetting(key, defaultValue, Integer.MIN_VALUE, properties); } - public static Setting boolSetting(String key, boolean defaultValue, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, dynamic, properties); + public static Setting boolSetting(String key, boolean defaultValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, properties); } - public static Setting boolSetting(String key, Setting fallbackSetting, boolean dynamic, - SettingsProperty... properties) { - return new Setting<>(key, fallbackSetting, Booleans::parseBooleanExact, dynamic, properties); + public static Setting boolSetting(String key, Setting fallbackSetting, SettingsProperty... properties) { + return new Setting<>(key, fallbackSetting, Booleans::parseBooleanExact, properties); } - public static Setting byteSizeSetting(String key, String percentage, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> percentage, (s) -> MemorySizeValue.parseBytesSizeValueOrHeapRatio(s, key), dynamic, properties); + public static Setting byteSizeSetting(String key, String percentage, SettingsProperty... properties) { + return new Setting<>(key, (s) -> percentage, (s) -> MemorySizeValue.parseBytesSizeValueOrHeapRatio(s, key), properties); } - public static Setting byteSizeSetting(String key, ByteSizeValue value, boolean dynamic, SettingsProperty... properties) { - return byteSizeSetting(key, (s) -> value.toString(), dynamic, properties); + public static Setting byteSizeSetting(String key, ByteSizeValue value, SettingsProperty... properties) { + return byteSizeSetting(key, (s) -> value.toString(), properties); } - public static Setting byteSizeSetting(String key, Setting fallbackSettings, boolean dynamic, + public static Setting byteSizeSetting(String key, Setting fallbackSettings, SettingsProperty... properties) { - return byteSizeSetting(key, fallbackSettings::getRaw, dynamic, properties); + return byteSizeSetting(key, fallbackSettings::getRaw, properties); } - public static Setting byteSizeSetting(String key, Function defaultValue, boolean dynamic, + public static Setting byteSizeSetting(String key, Function defaultValue, SettingsProperty... properties) { - return new Setting<>(key, defaultValue, (s) -> ByteSizeValue.parseBytesSizeValue(s, key), dynamic, properties); + return new Setting<>(key, defaultValue, (s) -> ByteSizeValue.parseBytesSizeValue(s, key), properties); } - public static Setting positiveTimeSetting(String key, TimeValue defaultValue, boolean dynamic, SettingsProperty... properties) { - return timeSetting(key, defaultValue, TimeValue.timeValueMillis(0), dynamic, properties); + public static Setting positiveTimeSetting(String key, TimeValue defaultValue, SettingsProperty... properties) { + return timeSetting(key, defaultValue, TimeValue.timeValueMillis(0), properties); } public static Setting> listSetting(String key, List defaultStringValue, Function singleValueParser, - boolean dynamic, SettingsProperty... properties) { - return listSetting(key, (s) -> defaultStringValue, singleValueParser, dynamic, properties); + SettingsProperty... properties) { + return listSetting(key, (s) -> defaultStringValue, singleValueParser, properties); } public static Setting> listSetting(String key, Setting> fallbackSetting, Function singleValueParser, - boolean dynamic, SettingsProperty... properties) { - return listSetting(key, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), singleValueParser, dynamic, properties); + SettingsProperty... properties) { + return listSetting(key, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), singleValueParser, properties); } public static Setting> listSetting(String key, Function> defaultStringValue, - Function singleValueParser, boolean dynamic, SettingsProperty... properties) { + Function singleValueParser, SettingsProperty... properties) { Function> parser = (s) -> parseableStringToList(s).stream().map(singleValueParser).collect(Collectors.toList()); return new Setting>(key, (s) -> arrayToParsableString(defaultStringValue.apply(s).toArray(Strings.EMPTY_ARRAY)), parser, - dynamic, properties) { + properties) { private final Pattern pattern = Pattern.compile(Pattern.quote(key)+"(\\.\\d+)?"); @Override public String getRaw(Settings settings) { @@ -539,11 +555,11 @@ public class Setting extends ToXContentToBytes { } } - public static Setting groupSetting(String key, boolean dynamic, SettingsProperty... properties) { + public static Setting groupSetting(String key, SettingsProperty... properties) { if (key.endsWith(".") == false) { throw new IllegalArgumentException("key must end with a '.'"); } - return new Setting(key, "", (s) -> null, dynamic, properties) { + return new Setting(key, "", (s) -> null, properties) { @Override public boolean isGroupSetting() { @@ -602,7 +618,7 @@ public class Setting extends ToXContentToBytes { }; } - public static Setting timeSetting(String key, Function defaultValue, TimeValue minValue, boolean dynamic, + public static Setting timeSetting(String key, Function defaultValue, TimeValue minValue, SettingsProperty... properties) { return new Setting<>(key, defaultValue, (s) -> { TimeValue timeValue = TimeValue.parseTimeValue(s, null, key); @@ -610,32 +626,29 @@ public class Setting extends ToXContentToBytes { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return timeValue; - }, dynamic, properties); + }, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, boolean dynamic, - SettingsProperty... properties) { - return timeSetting(key, (s) -> defaultValue.getStringRep(), minValue, dynamic, properties); + public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, SettingsProperty... properties) { + return timeSetting(key, (s) -> defaultValue.getStringRep(), minValue, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, boolean dynamic, SettingsProperty... properties) { - return new Setting<>(key, (s) -> defaultValue.toString(), (s) -> TimeValue.parseTimeValue(s, key), dynamic, properties); + public static Setting timeSetting(String key, TimeValue defaultValue, SettingsProperty... properties) { + return new Setting<>(key, (s) -> defaultValue.toString(), (s) -> TimeValue.parseTimeValue(s, key), properties); } - public static Setting timeSetting(String key, Setting fallbackSetting, boolean dynamic, - SettingsProperty... properties) { - return new Setting<>(key, fallbackSetting::getRaw, (s) -> TimeValue.parseTimeValue(s, key), dynamic, properties); + public static Setting timeSetting(String key, Setting fallbackSetting, SettingsProperty... properties) { + return new Setting<>(key, fallbackSetting::getRaw, (s) -> TimeValue.parseTimeValue(s, key), properties); } - public static Setting doubleSetting(String key, double defaultValue, double minValue, boolean dynamic, - SettingsProperty... properties) { + public static Setting doubleSetting(String key, double defaultValue, double minValue, SettingsProperty... properties) { return new Setting<>(key, (s) -> Double.toString(defaultValue), (s) -> { final double d = Double.parseDouble(s); if (d < minValue) { throw new IllegalArgumentException("Failed to parse value [" + s + "] for setting [" + key + "] must be >= " + minValue); } return d; - }, dynamic, properties); + }, properties); } @Override @@ -656,9 +669,9 @@ public class Setting extends ToXContentToBytes { * can easily be added with this setting. Yet, dynamic key settings don't support updaters our of the box unless {@link #getConcreteSetting(String)} * is used to pull the updater. */ - public static Setting dynamicKeySetting(String key, String defaultValue, Function parser, boolean dynamic, + public static Setting dynamicKeySetting(String key, String defaultValue, Function parser, SettingsProperty... properties) { - return new Setting(key, defaultValue, parser, dynamic, properties) { + return new Setting(key, defaultValue, parser, properties) { @Override boolean isGroupSetting() { @@ -678,7 +691,7 @@ public class Setting extends ToXContentToBytes { @Override public Setting getConcreteSetting(String key) { if (match(key)) { - return new Setting<>(key, defaultValue, parser, dynamic, properties); + return new Setting<>(key, defaultValue, parser, properties); } else { throw new IllegalArgumentException("key must match setting but didn't ["+key +"]"); } diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java index 6f055e3cf04..7f4e9c8b6d1 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java @@ -43,7 +43,7 @@ public class EsExecutors { * This is used to adjust thread pools sizes etc. per node. */ public static final Setting PROCESSORS_SETTING = - Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, false, SettingsProperty.ClusterScope); + Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, SettingsProperty.ClusterScope); /** * Returns the number of processors available but at most 32. diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java index 798cd7462af..47c115a47e0 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java @@ -64,8 +64,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class ThreadContext implements Closeable, Writeable{ public static final String PREFIX = "request.headers"; - public static final Setting DEFAULT_HEADERS_SETTING = - Setting.groupSetting(PREFIX + ".", false, SettingsProperty.ClusterScope); + public static final Setting DEFAULT_HEADERS_SETTING = Setting.groupSetting(PREFIX + ".", SettingsProperty.ClusterScope); private final Map defaultHeader; private static final ThreadContextStruct DEFAULT_CONTEXT = new ThreadContextStruct(Collections.emptyMap()); private final ContextThreadLocal threadLocal; diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java index 57ae63c1104..bc0f9740025 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java @@ -46,10 +46,10 @@ import java.util.function.Function; public class DiscoveryModule extends AbstractModule { public static final Setting DISCOVERY_TYPE_SETTING = - new Setting<>("discovery.type", settings -> DiscoveryNode.localNode(settings) ? "local" : "zen", Function.identity(), false, + new Setting<>("discovery.type", settings -> DiscoveryNode.localNode(settings) ? "local" : "zen", Function.identity(), SettingsProperty.ClusterScope); public static final Setting ZEN_MASTER_SERVICE_TYPE_SETTING = - new Setting<>("discovery.zen.masterservice.type", "zen", Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("discovery.zen.masterservice.type", "zen", Function.identity(), SettingsProperty.ClusterScope); private final Settings settings; private final List> unicastHostProviders = new ArrayList<>(); diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java index 181ee8253c0..6360c9b7757 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryService.java @@ -42,10 +42,9 @@ import java.util.concurrent.TimeUnit; public class DiscoveryService extends AbstractLifecycleComponent { public static final Setting INITIAL_STATE_TIMEOUT_SETTING = - Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), false, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), SettingsProperty.ClusterScope); public static final Setting DISCOVERY_SEED_SETTING = - Setting.longSetting("discovery.id.seed", 0L, Long.MIN_VALUE, false, SettingsProperty.ClusterScope); + Setting.longSetting("discovery.id.seed", 0L, Long.MIN_VALUE, SettingsProperty.ClusterScope); private static class InitialStateListener implements InitialStateDiscoveryListener { diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java index 64c13fabe7c..c303882a53a 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java @@ -45,7 +45,8 @@ public class DiscoverySettings extends AbstractComponent { * will continue to process the next cluster state update after this time has elapsed **/ public static final Setting PUBLISH_TIMEOUT_SETTING = - Setting.positiveTimeSetting("discovery.zen.publish_timeout", TimeValue.timeValueSeconds(30), true, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.publish_timeout", TimeValue.timeValueSeconds(30), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * sets the timeout for receiving enough acks for a specific cluster state and committing it. failing @@ -53,12 +54,13 @@ public class DiscoverySettings extends AbstractComponent { */ public static final Setting COMMIT_TIMEOUT_SETTING = new Setting<>("discovery.zen.commit_timeout", (s) -> PUBLISH_TIMEOUT_SETTING.getRaw(s), - (s) -> TimeValue.parseTimeValue(s, TimeValue.timeValueSeconds(30), "discovery.zen.commit_timeout"), true, - SettingsProperty.ClusterScope); + (s) -> TimeValue.parseTimeValue(s, TimeValue.timeValueSeconds(30), "discovery.zen.commit_timeout"), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting NO_MASTER_BLOCK_SETTING = - new Setting<>("discovery.zen.no_master_block", "write", DiscoverySettings::parseNoMasterBlock, true, SettingsProperty.ClusterScope); + new Setting<>("discovery.zen.no_master_block", "write", DiscoverySettings::parseNoMasterBlock, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting PUBLISH_DIFF_ENABLE_SETTING = - Setting.boolSetting("discovery.zen.publish_diff.enable", true, true, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.publish_diff.enable", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile ClusterBlock noMasterBlock; private volatile TimeValue publishTimeout; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java index 653c77945c9..038d63ee0ad 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java @@ -91,27 +91,27 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; public class ZenDiscovery extends AbstractLifecycleComponent implements Discovery, PingContextProvider { public final static Setting PING_TIMEOUT_SETTING = - Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), SettingsProperty.ClusterScope); public final static Setting JOIN_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.join_timeout", settings -> TimeValue.timeValueMillis(PING_TIMEOUT_SETTING.get(settings).millis() * 20).toString(), - TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); + TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); public final static Setting JOIN_RETRY_ATTEMPTS_SETTING = - Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, false, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, SettingsProperty.ClusterScope); public final static Setting JOIN_RETRY_DELAY_SETTING = - Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), SettingsProperty.ClusterScope); public final static Setting MAX_PINGS_FROM_ANOTHER_MASTER_SETTING = - Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, false, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, SettingsProperty.ClusterScope); public final static Setting SEND_LEAVE_REQUEST_SETTING = - Setting.boolSetting("discovery.zen.send_leave_request", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.send_leave_request", true, SettingsProperty.ClusterScope); public final static Setting MASTER_ELECTION_FILTER_CLIENT_SETTING = - Setting.boolSetting("discovery.zen.master_election.filter_client", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.master_election.filter_client", true, SettingsProperty.ClusterScope); public final static Setting MASTER_ELECTION_WAIT_FOR_JOINS_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.master_election.wait_for_joins_timeout", settings -> TimeValue.timeValueMillis(JOIN_TIMEOUT_SETTING.get(settings).millis() / 2).toString(), TimeValue.timeValueMillis(0), - false, SettingsProperty.ClusterScope); + SettingsProperty.ClusterScope); public final static Setting MASTER_ELECTION_FILTER_DATA_SETTING = - Setting.boolSetting("discovery.zen.master_election.filter_data", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.master_election.filter_data", false, SettingsProperty.ClusterScope); public static final String DISCOVERY_REJOIN_ACTION_NAME = "internal:discovery/zen/rejoin"; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java index cd418e369c4..8a35c6615e7 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java @@ -42,7 +42,7 @@ import java.util.List; public class ElectMasterService extends AbstractComponent { public static final Setting DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING = - Setting.intSetting("discovery.zen.minimum_master_nodes", -1, true, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.minimum_master_nodes", -1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); // This is the minimum version a master needs to be on, otherwise it gets ignored // This is based on the minimum compatible version of the current version this node is on diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java index c4247ea15df..6fc575d51cd 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java @@ -38,15 +38,15 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; public abstract class FaultDetection extends AbstractComponent { public static final Setting CONNECT_ON_NETWORK_DISCONNECT_SETTING = - Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, SettingsProperty.ClusterScope); public static final Setting PING_INTERVAL_SETTING = - Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), SettingsProperty.ClusterScope); public static final Setting PING_TIMEOUT_SETTING = - Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), false, SettingsProperty.ClusterScope); + Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), SettingsProperty.ClusterScope); public static final Setting PING_RETRIES_SETTING = - Setting.intSetting("discovery.zen.fd.ping_retries", 3, false, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.fd.ping_retries", 3, SettingsProperty.ClusterScope); public static final Setting REGISTER_CONNECTION_LISTENER_SETTING = - Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, SettingsProperty.ClusterScope); protected final ThreadPool threadPool; protected final ClusterName clusterName; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java index 24191ccf4fc..35e5688f2aa 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java @@ -88,10 +88,10 @@ public class UnicastZenPing extends AbstractLifecycleComponent implemen public static final String ACTION_NAME = "internal:discovery/zen/unicast"; public static final Setting> DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING = - Setting.listSetting("discovery.zen.ping.unicast.hosts", Collections.emptyList(), Function.identity(), false, + Setting.listSetting("discovery.zen.ping.unicast.hosts", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Setting DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING = - Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, false, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, SettingsProperty.ClusterScope); // these limits are per-address public static final int LIMIT_FOREIGN_PORTS_COUNT = 1; diff --git a/core/src/main/java/org/elasticsearch/env/Environment.java b/core/src/main/java/org/elasticsearch/env/Environment.java index 143ddf69901..0e0ab1ace20 100644 --- a/core/src/main/java/org/elasticsearch/env/Environment.java +++ b/core/src/main/java/org/elasticsearch/env/Environment.java @@ -47,18 +47,17 @@ import static org.elasticsearch.common.Strings.cleanPath; // TODO: move PathUtils to be package-private here instead of // public+forbidden api! public class Environment { - public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", false, SettingsProperty.ClusterScope); - public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", false, SettingsProperty.ClusterScope); - public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", false, SettingsProperty.ClusterScope); + public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", SettingsProperty.ClusterScope); + public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", SettingsProperty.ClusterScope); + public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", SettingsProperty.ClusterScope); public static final Setting> PATH_DATA_SETTING = - Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); - public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", false, SettingsProperty.ClusterScope); - public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", false, SettingsProperty.ClusterScope); + Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", SettingsProperty.ClusterScope); + public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", SettingsProperty.ClusterScope); public static final Setting> PATH_REPO_SETTING = - Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); - public static final Setting PATH_SHARED_DATA_SETTING = - Setting.simpleString("path.shared_data", false, SettingsProperty.ClusterScope); - public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", false, SettingsProperty.ClusterScope); + Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + public static final Setting PATH_SHARED_DATA_SETTING = Setting.simpleString("path.shared_data", SettingsProperty.ClusterScope); + public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", SettingsProperty.ClusterScope); private final Settings settings; diff --git a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java index f6d64b3406b..70bcad3c556 100644 --- a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java +++ b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java @@ -135,20 +135,20 @@ public class NodeEnvironment extends AbstractComponent implements Closeable { /** * Maximum number of data nodes that should run in an environment. */ - public static final Setting MAX_LOCAL_STORAGE_NODES_SETTING = Setting.intSetting("node.max_local_storage_nodes", 50, 1, false, + public static final Setting MAX_LOCAL_STORAGE_NODES_SETTING = Setting.intSetting("node.max_local_storage_nodes", 50, 1, SettingsProperty.ClusterScope); /** * If true automatically append node id to custom data paths. */ - public static final Setting ADD_NODE_ID_TO_CUSTOM_PATH = Setting.boolSetting("node.add_id_to_custom_path", true, false, - SettingsProperty.ClusterScope); + public static final Setting ADD_NODE_ID_TO_CUSTOM_PATH = + Setting.boolSetting("node.add_id_to_custom_path", true, SettingsProperty.ClusterScope); /** * If true the [verbose] SegmentInfos.infoStream logging is sent to System.out. */ - public static final Setting ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING = Setting - .boolSetting("node.enable_lucene_segment_infos_trace", false, false, SettingsProperty.ClusterScope); + public static final Setting ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING = + Setting.boolSetting("node.enable_lucene_segment_infos_trace", false, SettingsProperty.ClusterScope); public static final String NODES_FOLDER = "nodes"; public static final String INDICES_FOLDER = "indices"; diff --git a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java index 8c17325c08c..219c0725b6b 100644 --- a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java +++ b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java @@ -54,19 +54,19 @@ import java.util.concurrent.atomic.AtomicBoolean; public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener { public static final Setting EXPECTED_NODES_SETTING = - Setting.intSetting("gateway.expected_nodes", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_nodes", -1, -1, SettingsProperty.ClusterScope); public static final Setting EXPECTED_DATA_NODES_SETTING = - Setting.intSetting("gateway.expected_data_nodes", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_data_nodes", -1, -1, SettingsProperty.ClusterScope); public static final Setting EXPECTED_MASTER_NODES_SETTING = - Setting.intSetting("gateway.expected_master_nodes", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_master_nodes", -1, -1, SettingsProperty.ClusterScope); public static final Setting RECOVER_AFTER_TIME_SETTING = - Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); public static final Setting RECOVER_AFTER_NODES_SETTING = - Setting.intSetting("gateway.recover_after_nodes", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_nodes", -1, -1, SettingsProperty.ClusterScope); public static final Setting RECOVER_AFTER_DATA_NODES_SETTING = - Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, SettingsProperty.ClusterScope); public static final Setting RECOVER_AFTER_MASTER_NODES_SETTING = - Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, false, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, SettingsProperty.ClusterScope); public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); diff --git a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java index 018262c0304..8c4068fe262 100644 --- a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java @@ -70,11 +70,11 @@ public abstract class PrimaryShardAllocator extends AbstractComponent { public static final Setting NODE_INITIAL_SHARDS_SETTING = new Setting<>("gateway.initial_shards", (settings) -> settings.get("gateway.local.initial_shards", "quorum"), INITIAL_SHARDS_PARSER, - true, SettingsProperty.ClusterScope); + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); @Deprecated public static final Setting INDEX_RECOVERY_INITIAL_SHARDS_SETTING = - new Setting<>("index.recovery.initial_shards", (settings) -> NODE_INITIAL_SHARDS_SETTING.get(settings) , INITIAL_SHARDS_PARSER, true, - SettingsProperty.IndexScope); + new Setting<>("index.recovery.initial_shards", (settings) -> NODE_INITIAL_SHARDS_SETTING.get(settings) , INITIAL_SHARDS_PARSER, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public PrimaryShardAllocator(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java index 2332d8704e6..1a315b717aa 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java +++ b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java @@ -33,50 +33,50 @@ import static org.elasticsearch.common.settings.Setting.listSetting; public final class HttpTransportSettings { public static final Setting SETTING_CORS_ENABLED = - Setting.boolSetting("http.cors.enabled", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.cors.enabled", false, SettingsProperty.ClusterScope); public static final Setting SETTING_CORS_ALLOW_ORIGIN = - new Setting("http.cors.allow-origin", "", (value) -> value, false, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-origin", "", (value) -> value, SettingsProperty.ClusterScope); public static final Setting SETTING_CORS_MAX_AGE = - Setting.intSetting("http.cors.max-age", 1728000, false, SettingsProperty.ClusterScope); + Setting.intSetting("http.cors.max-age", 1728000, SettingsProperty.ClusterScope); public static final Setting SETTING_CORS_ALLOW_METHODS = - new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, false, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, SettingsProperty.ClusterScope); public static final Setting SETTING_CORS_ALLOW_HEADERS = - new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, false, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, SettingsProperty.ClusterScope); public static final Setting SETTING_CORS_ALLOW_CREDENTIALS = - Setting.boolSetting("http.cors.allow-credentials", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.cors.allow-credentials", false, SettingsProperty.ClusterScope); public static final Setting SETTING_PIPELINING = - Setting.boolSetting("http.pipelining", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.pipelining", true, SettingsProperty.ClusterScope); public static final Setting SETTING_PIPELINING_MAX_EVENTS = - Setting.intSetting("http.pipelining.max_events", 10000, false, SettingsProperty.ClusterScope); + Setting.intSetting("http.pipelining.max_events", 10000, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_COMPRESSION = - Setting.boolSetting("http.compression", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.compression", false, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_COMPRESSION_LEVEL = - Setting.intSetting("http.compression_level", 6, false, SettingsProperty.ClusterScope); + Setting.intSetting("http.compression_level", 6, SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_HOST = - listSetting("http.host", emptyList(), s -> s, false, SettingsProperty.ClusterScope); + listSetting("http.host", emptyList(), s -> s, SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_PUBLISH_HOST = - listSetting("http.publish_host", SETTING_HTTP_HOST, s -> s, false, SettingsProperty.ClusterScope); + listSetting("http.publish_host", SETTING_HTTP_HOST, s -> s, SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_BIND_HOST = - listSetting("http.bind_host", SETTING_HTTP_HOST, s -> s, false, SettingsProperty.ClusterScope); + listSetting("http.bind_host", SETTING_HTTP_HOST, s -> s, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_PORT = - new Setting("http.port", "9200-9300", PortsRange::new, false, SettingsProperty.ClusterScope); + new Setting("http.port", "9200-9300", PortsRange::new, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_PUBLISH_PORT = - Setting.intSetting("http.publish_port", 0, 0, false, SettingsProperty.ClusterScope); + Setting.intSetting("http.publish_port", 0, 0, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_DETAILED_ERRORS_ENABLED = - Setting.boolSetting("http.detailed_errors.enabled", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.detailed_errors.enabled", true, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_MAX_CONTENT_LENGTH = - Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_MAX_CHUNK_SIZE = - Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_MAX_HEADER_SIZE = - Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_MAX_INITIAL_LINE_LENGTH = - Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), SettingsProperty.ClusterScope); // don't reset cookies by default, since I don't think we really need to // note, parsing cookies was fixed in netty 3.5.1 regarding stack allocation, but still, currently, we don't need cookies public static final Setting SETTING_HTTP_RESET_COOKIES = - Setting.boolSetting("http.reset_cookies", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.reset_cookies", false, SettingsProperty.ClusterScope); private HttpTransportSettings() { } diff --git a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java index f021ea812f9..e955c8f1433 100644 --- a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java +++ b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java @@ -117,29 +117,29 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_MAX_CUMULATION_BUFFER_CAPACITY = - Setting.byteSizeSetting("http.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, + Setting.byteSizeSetting("http.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), SettingsProperty.ClusterScope); public static Setting SETTING_HTTP_NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = - Setting.intSetting("http.netty.max_composite_buffer_components", -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("http.netty.max_composite_buffer_components", -1, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_WORKER_COUNT = new Setting<>("http.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), false, SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_NO_DELAY = - boolSetting("http.tcp_no_delay", NetworkService.TcpSettings.TCP_NO_DELAY, false, SettingsProperty.ClusterScope); + boolSetting("http.tcp_no_delay", NetworkService.TcpSettings.TCP_NO_DELAY, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_KEEP_ALIVE = - boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings.TCP_KEEP_ALIVE, false, SettingsProperty.ClusterScope); + boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings.TCP_KEEP_ALIVE, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_BLOCKING_SERVER = - boolSetting("http.tcp.blocking_server", NetworkService.TcpSettings.TCP_BLOCKING_SERVER, false, SettingsProperty.ClusterScope); + boolSetting("http.tcp.blocking_server", NetworkService.TcpSettings.TCP_BLOCKING_SERVER, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_REUSE_ADDRESS = - boolSetting("http.tcp.reuse_address", NetworkService.TcpSettings.TCP_REUSE_ADDRESS, false, SettingsProperty.ClusterScope); + boolSetting("http.tcp.reuse_address", NetworkService.TcpSettings.TCP_REUSE_ADDRESS, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_SEND_BUFFER_SIZE = - Setting.byteSizeSetting("http.tcp.send_buffer_size", NetworkService.TcpSettings.TCP_SEND_BUFFER_SIZE, false, + Setting.byteSizeSetting("http.tcp.send_buffer_size", NetworkService.TcpSettings.TCP_SEND_BUFFER_SIZE, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE = - Setting.byteSizeSetting("http.tcp.receive_buffer_size", NetworkService.TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, + Setting.byteSizeSetting("http.tcp.receive_buffer_size", NetworkService.TcpSettings.TCP_RECEIVE_BUFFER_SIZE, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting("transport.netty.receive_predictor_size", @@ -152,13 +152,11 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MIN = - byteSizeSetting("http.netty.receive_predictor_min", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, - SettingsProperty.ClusterScope); + byteSizeSetting("http.netty.receive_predictor_min", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MAX = - byteSizeSetting("http.netty.receive_predictor_max", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, false, - SettingsProperty.ClusterScope); + byteSizeSetting("http.netty.receive_predictor_max", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); protected final NetworkService networkService; diff --git a/core/src/main/java/org/elasticsearch/index/IndexModule.java b/core/src/main/java/org/elasticsearch/index/IndexModule.java index 3586e726a40..36bc5e1d3e9 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexModule.java +++ b/core/src/main/java/org/elasticsearch/index/IndexModule.java @@ -67,15 +67,15 @@ import java.util.function.Function; public final class IndexModule { public static final Setting INDEX_STORE_TYPE_SETTING = - new Setting<>("index.store.type", "", Function.identity(), false, SettingsProperty.IndexScope); + new Setting<>("index.store.type", "", Function.identity(), SettingsProperty.IndexScope); public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity"; public static final String INDEX_QUERY_CACHE = "index"; public static final String NONE_QUERY_CACHE = "none"; public static final Setting INDEX_QUERY_CACHE_TYPE_SETTING = - new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), false, SettingsProperty.IndexScope); + new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), SettingsProperty.IndexScope); // for test purposes only public static final Setting INDEX_QUERY_CACHE_EVERYTHING_SETTING = - Setting.boolSetting("index.queries.cache.everything", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.queries.cache.everything", false, SettingsProperty.IndexScope); private final IndexSettings indexSettings; private final IndexStoreConfig indexStoreConfig; private final AnalysisRegistry analysisRegistry; diff --git a/core/src/main/java/org/elasticsearch/index/IndexSettings.java b/core/src/main/java/org/elasticsearch/index/IndexSettings.java index dbf298e16f1..bb859f04652 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/core/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -51,25 +51,25 @@ import java.util.function.Predicate; public final class IndexSettings { public static final Setting DEFAULT_FIELD_SETTING = - new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), false, SettingsProperty.IndexScope); + new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), SettingsProperty.IndexScope); public static final Setting QUERY_STRING_LENIENT_SETTING = - Setting.boolSetting("index.query_string.lenient", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.query_string.lenient", false, SettingsProperty.IndexScope); public static final Setting QUERY_STRING_ANALYZE_WILDCARD = - Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, SettingsProperty.ClusterScope); public static final Setting QUERY_STRING_ALLOW_LEADING_WILDCARD = - Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, SettingsProperty.ClusterScope); public static final Setting ALLOW_UNMAPPED = - Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, SettingsProperty.IndexScope); public static final Setting INDEX_TRANSLOG_SYNC_INTERVAL_SETTING = - Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), false, + Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), SettingsProperty.IndexScope); public static final Setting INDEX_TRANSLOG_DURABILITY_SETTING = new Setting<>("index.translog.durability", Translog.Durability.REQUEST.name(), - (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), true, SettingsProperty.IndexScope); + (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_WARMER_ENABLED_SETTING = - Setting.boolSetting("index.warmer.enabled", true, true, SettingsProperty.IndexScope); + Setting.boolSetting("index.warmer.enabled", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_TTL_DISABLE_PURGE_SETTING = - Setting.boolSetting("index.ttl.disable_purge", false, true, SettingsProperty.IndexScope); + Setting.boolSetting("index.ttl.disable_purge", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_CHECK_ON_STARTUP = new Setting<>("index.shard.check_on_startup", "false", (s) -> { switch(s) { case "false": @@ -80,7 +80,7 @@ public final class IndexSettings { default: throw new IllegalArgumentException("unknown value for [index.shard.check_on_startup] must be one of [true, false, fix, checksum] but was: " + s); } - }, false, SettingsProperty.IndexScope); + }, SettingsProperty.IndexScope); /** * Index setting describing the maximum value of from + size on a query. @@ -91,13 +91,13 @@ public final class IndexSettings { * safely. */ public static final Setting MAX_RESULT_WINDOW_SETTING = - Setting.intSetting("index.max_result_window", 10000, 1, true, SettingsProperty.IndexScope); + Setting.intSetting("index.max_result_window", 10000, 1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final TimeValue DEFAULT_REFRESH_INTERVAL = new TimeValue(1, TimeUnit.SECONDS); public static final Setting INDEX_REFRESH_INTERVAL_SETTING = - Setting.timeSetting("index.refresh_interval", DEFAULT_REFRESH_INTERVAL, new TimeValue(-1, TimeUnit.MILLISECONDS), true, - SettingsProperty.IndexScope); + Setting.timeSetting("index.refresh_interval", DEFAULT_REFRESH_INTERVAL, new TimeValue(-1, TimeUnit.MILLISECONDS), + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING = - Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), true, + Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), SettingsProperty.Dynamic, SettingsProperty.IndexScope); @@ -107,7 +107,7 @@ public final class IndexSettings { */ public static final TimeValue DEFAULT_GC_DELETES = TimeValue.timeValueSeconds(60); public static final Setting INDEX_GC_DELETES_SETTING = - Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), true, + Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), SettingsProperty.Dynamic, SettingsProperty.IndexScope); private final Index index; diff --git a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java index 1b790240587..b0b06e7ec67 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java +++ b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java @@ -57,7 +57,7 @@ public final class IndexWarmer extends AbstractComponent { public static final Setting INDEX_NORMS_LOADING_SETTING = new Setting<>("index.norms.loading", MappedFieldType.Loading.LAZY.toString(), (s) -> MappedFieldType.Loading.parse(s, MappedFieldType.Loading.LAZY), - false, SettingsProperty.IndexScope); + SettingsProperty.IndexScope); private final List listeners; IndexWarmer(Settings settings, ThreadPool threadPool, Listener... listeners) { diff --git a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java index c66e05a6c79..eff27e6e04d 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java @@ -57,20 +57,20 @@ public final class IndexingSlowLog implements IndexingOperationListener { private static final String INDEX_INDEXING_SLOWLOG_PREFIX = "index.indexing.slowlog"; public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_REFORMAT_SETTING = - Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, true, SettingsProperty.IndexScope); + Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_LEVEL_SETTING = - new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, + new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, SettingsProperty.Dynamic, SettingsProperty.IndexScope); /** * Reads how much of the source to log. The user can specify any value they @@ -84,7 +84,7 @@ public final class IndexingSlowLog implements IndexingOperationListener { } catch (NumberFormatException e) { return Booleans.parseBoolean(value, true) ? Integer.MAX_VALUE : 0; } - }, true, SettingsProperty.IndexScope); + }, SettingsProperty.Dynamic, SettingsProperty.IndexScope); IndexingSlowLog(IndexSettings indexSettings) { this(indexSettings, Loggers.getLogger(INDEX_INDEXING_SLOWLOG_PREFIX + ".index"), diff --git a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java index 5d2dc7e5bf2..35ead01981c 100644 --- a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java @@ -129,25 +129,29 @@ public final class MergePolicyConfig { public static final double DEFAULT_RECLAIM_DELETES_WEIGHT = 2.0d; public static final Setting INDEX_COMPOUND_FORMAT_SETTING = new Setting<>("index.compound_format", Double.toString(TieredMergePolicy.DEFAULT_NO_CFS_RATIO), MergePolicyConfig::parseNoCFSRatio, - true, SettingsProperty.IndexScope); + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED_SETTING = - Setting.doubleSetting("index.merge.policy.expunge_deletes_allowed", DEFAULT_EXPUNGE_DELETES_ALLOWED, 0.0d, true, - SettingsProperty.IndexScope); + Setting.doubleSetting("index.merge.policy.expunge_deletes_allowed", DEFAULT_EXPUNGE_DELETES_ALLOWED, 0.0d, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING = - Setting.byteSizeSetting("index.merge.policy.floor_segment", DEFAULT_FLOOR_SEGMENT, true, SettingsProperty.IndexScope); + Setting.byteSizeSetting("index.merge.policy.floor_segment", DEFAULT_FLOOR_SEGMENT, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_SETTING = - Setting.intSetting("index.merge.policy.max_merge_at_once", DEFAULT_MAX_MERGE_AT_ONCE, 2, true, SettingsProperty.IndexScope); + Setting.intSetting("index.merge.policy.max_merge_at_once", DEFAULT_MAX_MERGE_AT_ONCE, 2, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT_SETTING = - Setting.intSetting("index.merge.policy.max_merge_at_once_explicit", DEFAULT_MAX_MERGE_AT_ONCE_EXPLICIT, 2, true, - SettingsProperty.IndexScope); + Setting.intSetting("index.merge.policy.max_merge_at_once_explicit", DEFAULT_MAX_MERGE_AT_ONCE_EXPLICIT, 2, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT_SETTING = - Setting.byteSizeSetting("index.merge.policy.max_merged_segment", DEFAULT_MAX_MERGED_SEGMENT, true, SettingsProperty.IndexScope); + Setting.byteSizeSetting("index.merge.policy.max_merged_segment", DEFAULT_MAX_MERGED_SEGMENT, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_SEGMENTS_PER_TIER_SETTING = - Setting.doubleSetting("index.merge.policy.segments_per_tier", DEFAULT_SEGMENTS_PER_TIER, 2.0d, true, SettingsProperty.IndexScope); + Setting.doubleSetting("index.merge.policy.segments_per_tier", DEFAULT_SEGMENTS_PER_TIER, 2.0d, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT_SETTING = - Setting.doubleSetting("index.merge.policy.reclaim_deletes_weight", DEFAULT_RECLAIM_DELETES_WEIGHT, 0.0d, true, - SettingsProperty.IndexScope); + Setting.doubleSetting("index.merge.policy.reclaim_deletes_weight", DEFAULT_RECLAIM_DELETES_WEIGHT, 0.0d, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final String INDEX_MERGE_ENABLED = "index.merge.enabled"; // don't convert to Setting<> and register... we only set this in tests and register via a plugin diff --git a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java index e53315c0249..1cfc5c82a70 100644 --- a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java @@ -55,14 +55,14 @@ public final class MergeSchedulerConfig { public static final Setting MAX_THREAD_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_thread_count", (s) -> Integer.toString(Math.max(1, Math.min(4, EsExecutors.boundedNumberOfProcessors(s) / 2))), - (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), true, + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting MAX_MERGE_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_merge_count", (s) -> Integer.toString(MAX_THREAD_COUNT_SETTING.get(s) + 5), - (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), true, SettingsProperty.IndexScope); + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting AUTO_THROTTLE_SETTING = - Setting.boolSetting("index.merge.scheduler.auto_throttle", true, true, SettingsProperty.IndexScope); + Setting.boolSetting("index.merge.scheduler.auto_throttle", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); private volatile boolean autoThrottle; private volatile int maxThreadCount; diff --git a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java index ae26eab2de1..2770f7e6e08 100644 --- a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java @@ -53,32 +53,32 @@ public final class SearchSlowLog { private static final String INDEX_SEARCH_SLOWLOG_PREFIX = "index.search.slowlog"; public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), true, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_REFORMAT = - Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, true, SettingsProperty.IndexScope); + Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_LEVEL = - new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, true, + new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public SearchSlowLog(IndexSettings indexSettings) { diff --git a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java index 72435d90fd9..88afe96aff9 100644 --- a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java +++ b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java @@ -72,7 +72,7 @@ import java.util.concurrent.Executor; public final class BitsetFilterCache extends AbstractIndexComponent implements LeafReader.CoreClosedListener, RemovalListener>, Closeable { public static final Setting INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING = - Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, SettingsProperty.IndexScope); private final boolean loadRandomAccessFiltersEagerly; private final Cache> loadedFilters; diff --git a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java index 47110c62bfb..e1bcd5bb698 100644 --- a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java +++ b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java @@ -84,7 +84,7 @@ public final class EngineConfig { } return s; } - }, false, SettingsProperty.IndexScope); + }, SettingsProperty.IndexScope); /** if set to true the engine will start even if the translog id in the commit point can not be found */ public static final String INDEX_FORCE_NEW_TRANSLOG = "index.engine.force_new_translog"; diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index 6d12de8c395..caa5ce416b0 100644 --- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -67,7 +67,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo default: throw new IllegalArgumentException("failed to parse [" + s + "] must be one of [node,node]"); } - }, false, SettingsProperty.IndexScope); + }, SettingsProperty.IndexScope); private static final IndexFieldData.Builder MISSING_DOC_VALUES_BUILDER = (indexProperties, fieldType, cache, breakerService, mapperService1) -> { throw new IllegalStateException("Can't load fielddata on [" + fieldType.name() diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 9fba8c0529e..9796a26d740 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -51,9 +51,9 @@ import java.util.stream.StreamSupport; public abstract class FieldMapper extends Mapper implements Cloneable { public static final Setting IGNORE_MALFORMED_SETTING = - Setting.boolSetting("index.mapping.ignore_malformed", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.ignore_malformed", false, SettingsProperty.IndexScope); public static final Setting COERCE_SETTING = - Setting.boolSetting("index.mapping.coerce", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.coerce", false, SettingsProperty.IndexScope); public abstract static class Builder extends Mapper.Builder { protected final MappedFieldType fieldType; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index c86219cc05a..0acf52b8728 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -83,10 +83,10 @@ public class MapperService extends AbstractIndexComponent implements Closeable { public static final String DEFAULT_MAPPING = "_default_"; public static final Setting INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING = - Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, true, SettingsProperty.IndexScope); + Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final boolean INDEX_MAPPER_DYNAMIC_DEFAULT = true; public static final Setting INDEX_MAPPER_DYNAMIC_SETTING = - Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, SettingsProperty.IndexScope); private static ObjectHashSet META_FIELDS = ObjectHashSet.from( "_uid", "_id", "_type", "_all", "_parent", "_routing", "_index", "_size", "_timestamp", "_ttl" diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java index 5f928043688..02974157aed 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java @@ -55,7 +55,7 @@ import java.util.List; public abstract class NumberFieldMapper extends FieldMapper implements AllFieldMapper.IncludeInAll { // this is private since it has a different default private static final Setting COERCE_SETTING = - Setting.boolSetting("index.mapping.coerce", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.coerce", true, SettingsProperty.IndexScope); public static class Defaults { diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java index 62d5da92259..17e54ced15f 100644 --- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java +++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java @@ -63,7 +63,7 @@ import java.util.concurrent.TimeUnit; public final class PercolatorQueriesRegistry extends AbstractIndexShardComponent implements Closeable { public final static Setting INDEX_MAP_UNMAPPED_FIELDS_AS_STRING_SETTING = - Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, SettingsProperty.IndexScope); private final ConcurrentMap percolateQueries = ConcurrentCollections.newConcurrentMapWithAggressiveConcurrency(); private final QueryShardContext queryShardContext; diff --git a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java index 914979eac05..4c452d15928 100644 --- a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java +++ b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java @@ -61,7 +61,7 @@ public class FsDirectoryService extends DirectoryService implements StoreRateLim default: throw new IllegalArgumentException("unrecognized [index.store.fs.fs_lock] \"" + s + "\": must be native or simple"); } - }, false, SettingsProperty.IndexScope); + }, SettingsProperty.IndexScope); private final CounterMetric rateLimitingTimeInNanos = new CounterMetric(); private final ShardPath path; diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java index 783ed980646..be4e6966226 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java @@ -31,9 +31,11 @@ import org.elasticsearch.index.shard.ShardPath; */ public class IndexStore extends AbstractIndexComponent { public static final Setting INDEX_STORE_THROTTLE_TYPE_SETTING = - new Setting<>("index.store.throttle.type", "none", IndexRateLimitingType::fromString, true, SettingsProperty.IndexScope); + new Setting<>("index.store.throttle.type", "none", IndexRateLimitingType::fromString, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = - Setting.byteSizeSetting("index.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, SettingsProperty.IndexScope); + Setting.byteSizeSetting("index.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), + SettingsProperty.Dynamic, SettingsProperty.IndexScope); protected final IndexStoreConfig indexStoreConfig; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java index 328d7604bcf..28a4c32ab75 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java @@ -38,13 +38,14 @@ public class IndexStoreConfig { * Configures the node / cluster level throttle type. See {@link StoreRateLimiting.Type}. */ public static final Setting INDICES_STORE_THROTTLE_TYPE_SETTING = - new Setting<>("indices.store.throttle.type", StoreRateLimiting.Type.NONE.name(),StoreRateLimiting.Type::fromString, true, - SettingsProperty.ClusterScope); + new Setting<>("indices.store.throttle.type", StoreRateLimiting.Type.NONE.name(),StoreRateLimiting.Type::fromString, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * Configures the node / cluster level throttle intensity. The default is 10240 MB */ public static final Setting INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = - Setting.byteSizeSetting("indices.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), true, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile StoreRateLimiting.Type rateLimitingType; private volatile ByteSizeValue rateLimitingThrottle; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/Store.java b/core/src/main/java/org/elasticsearch/index/store/Store.java index b1d806d520e..a0cc8f11419 100644 --- a/core/src/main/java/org/elasticsearch/index/store/Store.java +++ b/core/src/main/java/org/elasticsearch/index/store/Store.java @@ -131,7 +131,7 @@ public class Store extends AbstractIndexShardComponent implements Closeable, Ref static final int VERSION = VERSION_WRITE_THROWABLE; static final String CORRUPTED = "corrupted_"; public static final Setting INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING = - Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), false, SettingsProperty.IndexScope); + Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), SettingsProperty.IndexScope); private final AtomicBoolean isClosed = new AtomicBoolean(false); private final StoreDirectory directory; diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java index 15eb19fc416..9dbb673fa5b 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java @@ -49,9 +49,9 @@ import java.util.concurrent.ConcurrentHashMap; public class IndicesQueryCache extends AbstractComponent implements QueryCache, Closeable { public static final Setting INDICES_CACHE_QUERY_SIZE_SETTING = Setting.byteSizeSetting( - "indices.queries.cache.size", "10%", false, SettingsProperty.ClusterScope); + "indices.queries.cache.size", "10%", SettingsProperty.ClusterScope); public static final Setting INDICES_CACHE_QUERY_COUNT_SETTING = Setting.intSetting( - "indices.queries.cache.count", 10000, 1, false, SettingsProperty.ClusterScope); + "indices.queries.cache.count", 10000, 1, SettingsProperty.ClusterScope); private final LRUQueryCache cache; private final ShardCoreKeyMap shardKeyMap = new ShardCoreKeyMap(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java index 8ebe52a2c19..02aa09f138c 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java @@ -70,11 +70,11 @@ public final class IndicesRequestCache extends AbstractComponent implements Remo * since we are checking on the cluster state IndexMetaData always. */ public static final Setting INDEX_CACHE_REQUEST_ENABLED_SETTING = - Setting.boolSetting("index.requests.cache.enable", false, true, SettingsProperty.IndexScope); + Setting.boolSetting("index.requests.cache.enable", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); public static final Setting INDICES_CACHE_QUERY_SIZE = - Setting.byteSizeSetting("indices.requests.cache.size", "1%", false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.requests.cache.size", "1%", SettingsProperty.ClusterScope); public static final Setting INDICES_CACHE_QUERY_EXPIRE = - Setting.positiveTimeSetting("indices.requests.cache.expire", new TimeValue(0), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.requests.cache.expire", new TimeValue(0), SettingsProperty.ClusterScope); private final ConcurrentMap registeredClosedListeners = ConcurrentCollections.newConcurrentMap(); private final Set keysToClean = ConcurrentCollections.newConcurrentSet(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesService.java b/core/src/main/java/org/elasticsearch/indices/IndicesService.java index d64bb3f0c4c..585d1d31bc5 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesService.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesService.java @@ -117,7 +117,7 @@ public class IndicesService extends AbstractLifecycleComponent i public static final String INDICES_SHARDS_CLOSED_TIMEOUT = "indices.shards_closed_timeout"; public static final Setting INDICES_CACHE_CLEAN_INTERVAL_SETTING = - Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), SettingsProperty.ClusterScope); private final PluginsService pluginsService; private final NodeEnvironment nodeEnv; private final TimeValue shardsClosedTimeout; diff --git a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java index 3b7b9782849..b1189fbd286 100644 --- a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java +++ b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java @@ -73,11 +73,11 @@ import java.util.function.Function; public class HunspellService extends AbstractComponent { public final static Setting HUNSPELL_LAZY_LOAD = - Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, false, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, SettingsProperty.ClusterScope); public final static Setting HUNSPELL_IGNORE_CASE = - Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, false, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, SettingsProperty.ClusterScope); public final static Setting HUNSPELL_DICTIONARY_OPTIONS = - Setting.groupSetting("indices.analysis.hunspell.dictionary.", false, SettingsProperty.ClusterScope); + Setting.groupSetting("indices.analysis.hunspell.dictionary.", SettingsProperty.ClusterScope); private final ConcurrentHashMap dictionaries = new ConcurrentHashMap<>(); private final Map knownDictionaries; private final boolean defaultIgnoreCase; diff --git a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java index fdee0b03343..3a3fede9af0 100644 --- a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java +++ b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java @@ -48,21 +48,21 @@ public class HierarchyCircuitBreakerService extends CircuitBreakerService { private final ConcurrentMap breakers = new ConcurrentHashMap(); public static final Setting TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.total.limit", "70%", true, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.total.limit", "70%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", true, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING = - Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, true, SettingsProperty.ClusterScope); + Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_TYPE_SETTING = - new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, false, SettingsProperty.ClusterScope); + new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, SettingsProperty.ClusterScope); public static final Setting REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.request.limit", "40%", true, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.request.limit", "40%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING = - Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, true, SettingsProperty.ClusterScope); + Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting REQUEST_CIRCUIT_BREAKER_TYPE_SETTING = - new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, false, SettingsProperty.ClusterScope); + new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, SettingsProperty.ClusterScope); diff --git a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java index dd60c628223..a5bb8696999 100644 --- a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java +++ b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java @@ -54,7 +54,7 @@ import java.util.function.ToLongBiFunction; public class IndicesFieldDataCache extends AbstractComponent implements RemovalListener, Releasable{ public static final Setting INDICES_FIELDDATA_CACHE_SIZE_KEY = - Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); private final IndexFieldDataCache.Listener indicesFieldDataCacheListener; private final Cache cache; diff --git a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java index 742b1b78945..f58dc1ca8b8 100644 --- a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java +++ b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java @@ -34,26 +34,26 @@ import org.elasticsearch.common.unit.TimeValue; public class RecoverySettings extends AbstractComponent { public static final Setting INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING = - Setting.byteSizeSetting("indices.recovery.max_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB), true, - SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.recovery.max_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * how long to wait before retrying after issues cause by cluster state syncing between nodes * i.e., local node is not yet known on remote node, remote shard not yet started etc. */ public static final Setting INDICES_RECOVERY_RETRY_DELAY_STATE_SYNC_SETTING = - Setting.positiveTimeSetting("indices.recovery.retry_delay_state_sync", TimeValue.timeValueMillis(500), true, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.recovery.retry_delay_state_sync", TimeValue.timeValueMillis(500), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** how long to wait before retrying after network related issues */ public static final Setting INDICES_RECOVERY_RETRY_DELAY_NETWORK_SETTING = - Setting.positiveTimeSetting("indices.recovery.retry_delay_network", TimeValue.timeValueSeconds(5), true, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.recovery.retry_delay_network", TimeValue.timeValueSeconds(5), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** timeout value to use for requests made as part of the recovery process */ public static final Setting INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING = - Setting.positiveTimeSetting("indices.recovery.internal_action_timeout", TimeValue.timeValueMinutes(15), true, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.recovery.internal_action_timeout", TimeValue.timeValueMinutes(15), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * timeout value to use for requests made as part of the recovery process that are expected to take long time. @@ -62,7 +62,7 @@ public class RecoverySettings extends AbstractComponent { public static final Setting INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.internal_action_long_timeout", (s) -> TimeValue.timeValueMillis(INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING.get(s).millis() * 2).toString(), - TimeValue.timeValueSeconds(0), true, SettingsProperty.ClusterScope); + TimeValue.timeValueSeconds(0), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); /** * recoveries that don't show any activity for more then this interval will be failed. @@ -70,8 +70,8 @@ public class RecoverySettings extends AbstractComponent { */ public static final Setting INDICES_RECOVERY_ACTIVITY_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.recovery_activity_timeout", - (s) -> INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING.getRaw(s) , TimeValue.timeValueSeconds(0), true, - SettingsProperty.ClusterScope); + (s) -> INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING.getRaw(s) , TimeValue.timeValueSeconds(0), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final ByteSizeValue DEFAULT_CHUNK_SIZE = new ByteSizeValue(512, ByteSizeUnit.KB); diff --git a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java index 23e007c5366..3851b4571b6 100644 --- a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java +++ b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java @@ -71,7 +71,7 @@ public class IndicesStore extends AbstractComponent implements ClusterStateListe // TODO this class can be foled into either IndicesService and partially into IndicesClusterStateService there is no need for a separate public service public static final Setting INDICES_STORE_DELETE_SHARD_TIMEOUT = - Setting.positiveTimeSetting("indices.store.delete.shard.timeout", new TimeValue(30, TimeUnit.SECONDS), false, + Setting.positiveTimeSetting("indices.store.delete.shard.timeout", new TimeValue(30, TimeUnit.SECONDS), SettingsProperty.ClusterScope); public static final String ACTION_SHARD_EXISTS = "internal:index/shard/exists"; private static final EnumSet ACTIVE_STATES = EnumSet.of(IndexShardState.STARTED, IndexShardState.RELOCATED); diff --git a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java index 6eb34adc9f8..0f9c9d425e1 100644 --- a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java +++ b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java @@ -69,7 +69,8 @@ import java.util.concurrent.locks.ReentrantLock; public class IndicesTTLService extends AbstractLifecycleComponent { public static final Setting INDICES_TTL_INTERVAL_SETTING = - Setting.positiveTimeSetting("indices.ttl.interval", TimeValue.timeValueSeconds(60), true, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.ttl.interval", TimeValue.timeValueSeconds(60), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private final ClusterService clusterService; private final IndicesService indicesService; diff --git a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java index be985cb7020..71a9743f78a 100644 --- a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java @@ -38,7 +38,7 @@ public class FsService extends AbstractComponent { private final SingleObjectCache fsStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.fs.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + Setting.timeSetting("monitor.fs.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), SettingsProperty.ClusterScope); public FsService(Settings settings, NodeEnvironment nodeEnvironment) throws IOException { diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java index 03c6c00d539..301b86674c6 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java @@ -48,13 +48,13 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent ENABLED_SETTING = - Setting.boolSetting("monitor.jvm.gc.enabled", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("monitor.jvm.gc.enabled", true, SettingsProperty.ClusterScope); public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), SettingsProperty.ClusterScope); private static String GC_COLLECTOR_PREFIX = "monitor.jvm.gc.collector."; - public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, false, SettingsProperty.ClusterScope); + public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, SettingsProperty.ClusterScope); static class GcThreshold { public final String name; diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java index e816e51911e..5e03ab3e31c 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java @@ -37,7 +37,7 @@ public class JvmService extends AbstractComponent { private JvmStats jvmStats; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.jvm.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + Setting.timeSetting("monitor.jvm.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), SettingsProperty.ClusterScope); public JvmService(Settings settings) { diff --git a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java index 1cd0910ab3e..df750c7247c 100644 --- a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java @@ -39,7 +39,7 @@ public class OsService extends AbstractComponent { private SingleObjectCache osStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.os.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + Setting.timeSetting("monitor.os.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), SettingsProperty.ClusterScope); public OsService(Settings settings) { diff --git a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java index 316c8a8131f..0370011e7c0 100644 --- a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java +++ b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java @@ -36,7 +36,7 @@ public final class ProcessService extends AbstractComponent { private final SingleObjectCache processStatsCache; public final static Setting REFRESH_INTERVAL_SETTING = - Setting.timeSetting("monitor.process.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, + Setting.timeSetting("monitor.process.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), SettingsProperty.ClusterScope); public ProcessService(Settings settings) { diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index 4b0c806749f..6fc34955dad 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -126,22 +126,22 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder; public class Node implements Closeable { public static final Setting WRITE_PORTS_FIELD_SETTING = - Setting.boolSetting("node.portsfile", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.portsfile", false, SettingsProperty.ClusterScope); public static final Setting NODE_CLIENT_SETTING = - Setting.boolSetting("node.client", false, false, SettingsProperty.ClusterScope); - public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.client", false, SettingsProperty.ClusterScope); + public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, SettingsProperty.ClusterScope); public static final Setting NODE_MASTER_SETTING = - Setting.boolSetting("node.master", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.master", true, SettingsProperty.ClusterScope); public static final Setting NODE_LOCAL_SETTING = - Setting.boolSetting("node.local", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.local", false, SettingsProperty.ClusterScope); public static final Setting NODE_MODE_SETTING = - new Setting<>("node.mode", "network", Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("node.mode", "network", Function.identity(), SettingsProperty.ClusterScope); public static final Setting NODE_INGEST_SETTING = - Setting.boolSetting("node.ingest", true, false, SettingsProperty.ClusterScope); - public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.ingest", true, SettingsProperty.ClusterScope); + public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", SettingsProperty.ClusterScope); // this sucks that folks can mistype client etc and get away with it. // TODO: we should move this to node.attribute.${name} = ${value} instead. - public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", false, SettingsProperty.ClusterScope); + public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", SettingsProperty.ClusterScope); private static final String CLIENT_TYPE = "node"; diff --git a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java index 45fd66d6daa..5f8107ba758 100644 --- a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java +++ b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java @@ -59,7 +59,7 @@ public class InternalSettingsPreparer { public static final String SECRET_PROMPT_VALUE = "${prompt.secret}"; public static final String TEXT_PROMPT_VALUE = "${prompt.text}"; public static final Setting IGNORE_SYSTEM_PROPERTIES_SETTING = - Setting.boolSetting("config.ignore_system_properties", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("config.ignore_system_properties", false, SettingsProperty.ClusterScope); /** * Prepares the settings by gathering all elasticsearch system properties and setting defaults. diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index 1fb5875109e..1aafcd0f6fb 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -73,7 +73,7 @@ public class PluginsService extends AbstractComponent { private final List> plugins; private final PluginsAndModules info; public static final Setting> MANDATORY_SETTING = - Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), false, SettingsProperty.ClusterScope); + Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); private final Map> onModuleReferences; diff --git a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java index 8b364105718..8ac297e072f 100644 --- a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java @@ -53,16 +53,16 @@ public class FsRepository extends BlobStoreRepository { public final static String TYPE = "fs"; public static final Setting LOCATION_SETTING = - new Setting<>("location", "", Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("location", "", Function.identity(), SettingsProperty.ClusterScope); public static final Setting REPOSITORIES_LOCATION_SETTING = - new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), SettingsProperty.ClusterScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("chunk_size", "-1", false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("chunk_size", "-1", SettingsProperty.ClusterScope); public static final Setting REPOSITORIES_CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", false, SettingsProperty.ClusterScope); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", SettingsProperty.ClusterScope); + public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); public static final Setting REPOSITORIES_COMPRESS_SETTING = - Setting.boolSetting("repositories.fs.compress", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.fs.compress", false, SettingsProperty.ClusterScope); private final FsBlobStore blobStore; diff --git a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java index c5255fd8b5e..5086902d9fc 100644 --- a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java @@ -58,22 +58,20 @@ public class URLRepository extends BlobStoreRepository { public static final Setting> SUPPORTED_PROTOCOLS_SETTING = Setting.listSetting("repositories.url.supported_protocols", Arrays.asList("http", "https", "ftp", "file", "jar"), - Function.identity(), false, SettingsProperty.ClusterScope); + Function.identity(), SettingsProperty.ClusterScope); public static final Setting> ALLOWED_URLS_SETTING = - Setting.listSetting("repositories.url.allowed_urls", Collections.emptyList(), URIPattern::new, false, - SettingsProperty.ClusterScope); + Setting.listSetting("repositories.url.allowed_urls", Collections.emptyList(), URIPattern::new, SettingsProperty.ClusterScope); - public static final Setting URL_SETTING = - new Setting<>("url", "http:", URLRepository::parseURL, false, SettingsProperty.ClusterScope); + public static final Setting URL_SETTING = new Setting<>("url", "http:", URLRepository::parseURL, SettingsProperty.ClusterScope); public static final Setting REPOSITORIES_URL_SETTING = - new Setting<>("repositories.url.url", (s) -> s.get("repositories.uri.url", "http:"), URLRepository::parseURL, false, + new Setting<>("repositories.url.url", (s) -> s.get("repositories.uri.url", "http:"), URLRepository::parseURL, SettingsProperty.ClusterScope); public static final Setting LIST_DIRECTORIES_SETTING = - Setting.boolSetting("list_directories", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("list_directories", true, SettingsProperty.ClusterScope); public static final Setting REPOSITORIES_LIST_DIRECTORIES_SETTING = - Setting.boolSetting("repositories.uri.list_directories", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.uri.list_directories", true, SettingsProperty.ClusterScope); private final List supportedProtocols; diff --git a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java index 1ea87c6c61e..5066b4884af 100644 --- a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java +++ b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java @@ -36,7 +36,7 @@ import org.elasticsearch.common.settings.Settings; */ public abstract class BaseRestHandler extends AbstractComponent implements RestHandler { public static final Setting MULTI_ALLOW_EXPLICIT_INDEX = - Setting.boolSetting("rest.action.multi.allow_explicit_index", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("rest.action.multi.allow_explicit_index", true, SettingsProperty.ClusterScope); private final Client client; protected final ParseFieldMatcher parseFieldMatcher; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index 058deadcf4c..4ef8b4e4bae 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -86,12 +86,12 @@ public class ScriptService extends AbstractComponent implements Closeable { static final String DISABLE_DYNAMIC_SCRIPTING_SETTING = "script.disable_dynamic"; public static final Setting SCRIPT_CACHE_SIZE_SETTING = - Setting.intSetting("script.cache.max_size", 100, 0, false, SettingsProperty.ClusterScope); + Setting.intSetting("script.cache.max_size", 100, 0, SettingsProperty.ClusterScope); public static final Setting SCRIPT_CACHE_EXPIRE_SETTING = - Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); public static final String SCRIPT_INDEX = ".scripts"; public static final Setting SCRIPT_AUTO_RELOAD_ENABLED_SETTING = - Setting.boolSetting("script.auto_reload_enabled", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("script.auto_reload_enabled", true, SettingsProperty.ClusterScope); private final String defaultLang; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java index a2ab5f9c269..26cb7eaa278 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java @@ -45,7 +45,6 @@ public class ScriptSettings { ScriptModes.sourceKey(scriptType), scriptType.getDefaultScriptMode().getMode(), ScriptMode::parse, - false, SettingsProperty.ClusterScope)); } SCRIPT_TYPE_SETTING_MAP = Collections.unmodifiableMap(scriptTypeSettingMap); @@ -67,7 +66,7 @@ public class ScriptSettings { throw new IllegalArgumentException("unregistered default language [" + setting + "]"); } return setting; - }, false, SettingsProperty.ClusterScope); + }, SettingsProperty.ClusterScope); } private static Map> contextSettings(ScriptContextRegistry scriptContextRegistry) { @@ -77,7 +76,6 @@ public class ScriptSettings { ScriptModes.operationKey(scriptContext), ScriptMode.OFF.getMode(), ScriptMode::parse, - false, SettingsProperty.ClusterScope )); } @@ -138,7 +136,6 @@ public class ScriptSettings { ScriptModes.getKey(language, scriptType, scriptContext), defaultSetting, ScriptMode::parse, - false, SettingsProperty.ClusterScope); scriptModeSettings.add(setting); } diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index a4106feb231..b92e271a149 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -108,13 +108,13 @@ public class SearchService extends AbstractLifecycleComponent imp // we can have 5 minutes here, since we make sure to clean with search requests and when shard/index closes public static final Setting DEFAULT_KEEPALIVE_SETTING = - Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), SettingsProperty.ClusterScope); public static final Setting KEEPALIVE_INTERVAL_SETTING = - Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), false, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), SettingsProperty.ClusterScope); public static final TimeValue NO_TIMEOUT = timeValueMillis(-1); public static final Setting DEFAULT_SEARCH_TIMEOUT_SETTING = - Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, true, SettingsProperty.ClusterScope); + Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private final ThreadPool threadPool; diff --git a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java index 14c52ab627a..150325ff242 100644 --- a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java +++ b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java @@ -190,7 +190,7 @@ public class ThreadPool extends AbstractComponent implements Closeable { } public static final Setting THREADPOOL_GROUP_SETTING = - Setting.groupSetting("threadpool.", true, SettingsProperty.ClusterScope); + Setting.groupSetting("threadpool.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private volatile Map executors; diff --git a/core/src/main/java/org/elasticsearch/transport/Transport.java b/core/src/main/java/org/elasticsearch/transport/Transport.java index c72bcb2bb54..d6dee1953a4 100644 --- a/core/src/main/java/org/elasticsearch/transport/Transport.java +++ b/core/src/main/java/org/elasticsearch/transport/Transport.java @@ -36,7 +36,7 @@ import java.util.Map; public interface Transport extends LifecycleComponent { - Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, false, SettingsProperty.ClusterScope); + Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, SettingsProperty.ClusterScope); void transportServiceAdapter(TransportServiceAdapter service); diff --git a/core/src/main/java/org/elasticsearch/transport/TransportService.java b/core/src/main/java/org/elasticsearch/transport/TransportService.java index 2a03c516255..8943df12e59 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportService.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportService.java @@ -99,10 +99,10 @@ public class TransportService extends AbstractLifecycleComponent> TRACE_LOG_INCLUDE_SETTING = - listSetting("transport.tracer.include", emptyList(), Function.identity(), true, SettingsProperty.ClusterScope); + listSetting("transport.tracer.include", emptyList(), Function.identity(), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); public static final Setting> TRACE_LOG_EXCLUDE_SETTING = listSetting("transport.tracer.exclude", Arrays.asList("internal:discovery/zen/fd*", TransportLivenessAction.NAME), - Function.identity(), true, SettingsProperty.ClusterScope); + Function.identity(), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private final ESLogger tracerLog; diff --git a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java index e5fb9f7e14d..eaa3f004188 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java @@ -36,18 +36,18 @@ import static org.elasticsearch.common.settings.Setting.listSetting; final public class TransportSettings { public static final Setting> HOST = - listSetting("transport.host", emptyList(), s -> s, false, SettingsProperty.ClusterScope); + listSetting("transport.host", emptyList(), s -> s, SettingsProperty.ClusterScope); public static final Setting> PUBLISH_HOST = - listSetting("transport.publish_host", HOST, s -> s, false, SettingsProperty.ClusterScope); + listSetting("transport.publish_host", HOST, s -> s, SettingsProperty.ClusterScope); public static final Setting> BIND_HOST = - listSetting("transport.bind_host", HOST, s -> s, false, SettingsProperty.ClusterScope); + listSetting("transport.bind_host", HOST, s -> s, SettingsProperty.ClusterScope); public static final Setting PORT = - new Setting<>("transport.tcp.port", "9300-9400", s -> s, false, SettingsProperty.ClusterScope); + new Setting<>("transport.tcp.port", "9300-9400", s -> s, SettingsProperty.ClusterScope); public static final Setting PUBLISH_PORT = - intSetting("transport.publish_port", -1, -1, false, SettingsProperty.ClusterScope); + intSetting("transport.publish_port", -1, -1, SettingsProperty.ClusterScope); public static final String DEFAULT_PROFILE = "default"; public static final Setting TRANSPORT_PROFILES_SETTING = - groupSetting("transport.profiles.", true, SettingsProperty.ClusterScope); + groupSetting("transport.profiles.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); private TransportSettings() { diff --git a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java index dd250fabd1d..0e2b38eee67 100644 --- a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java +++ b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java @@ -150,43 +150,42 @@ public class NettyTransport extends AbstractLifecycleComponent implem public static final Setting WORKER_COUNT = new Setting<>("transport.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), false, SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), SettingsProperty.ClusterScope); public static final Setting CONNECTIONS_PER_NODE_RECOVERY = - intSetting("transport.connections_per_node.recovery", 2, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.recovery", 2, 1, SettingsProperty.ClusterScope); public static final Setting CONNECTIONS_PER_NODE_BULK = - intSetting("transport.connections_per_node.bulk", 3, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.bulk", 3, 1, SettingsProperty.ClusterScope); public static final Setting CONNECTIONS_PER_NODE_REG = - intSetting("transport.connections_per_node.reg", 6, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.reg", 6, 1, SettingsProperty.ClusterScope); public static final Setting CONNECTIONS_PER_NODE_STATE = - intSetting("transport.connections_per_node.state", 1, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.state", 1, 1, SettingsProperty.ClusterScope); public static final Setting CONNECTIONS_PER_NODE_PING = - intSetting("transport.connections_per_node.ping", 1, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.ping", 1, 1, SettingsProperty.ClusterScope); // the scheduled internal ping interval setting, defaults to disabled (-1) public static final Setting PING_SCHEDULE = - timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), false, SettingsProperty.ClusterScope); + timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), SettingsProperty.ClusterScope); public static final Setting TCP_BLOCKING_CLIENT = - boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, false, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, SettingsProperty.ClusterScope); public static final Setting TCP_CONNECT_TIMEOUT = - timeSetting("transport.tcp.connect_timeout", TcpSettings.TCP_CONNECT_TIMEOUT, false, SettingsProperty.ClusterScope); + timeSetting("transport.tcp.connect_timeout", TcpSettings.TCP_CONNECT_TIMEOUT, SettingsProperty.ClusterScope); public static final Setting TCP_NO_DELAY = - boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, false, SettingsProperty.ClusterScope); + boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, SettingsProperty.ClusterScope); public static final Setting TCP_KEEP_ALIVE = - boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, false, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, SettingsProperty.ClusterScope); public static final Setting TCP_BLOCKING_SERVER = - boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, false, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, SettingsProperty.ClusterScope); public static final Setting TCP_REUSE_ADDRESS = - boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, false, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, SettingsProperty.ClusterScope); public static final Setting TCP_SEND_BUFFER_SIZE = - Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, SettingsProperty.ClusterScope); public static final Setting TCP_RECEIVE_BUFFER_SIZE = - Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, false, - SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, SettingsProperty.ClusterScope); public static final Setting NETTY_MAX_CUMULATION_BUFFER_CAPACITY = - Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), SettingsProperty.ClusterScope); public static final Setting NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = - Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, false, SettingsProperty.ClusterScope); + Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, SettingsProperty.ClusterScope); // See AdaptiveReceiveBufferSizePredictor#DEFAULT_XXX for default values in netty..., we can use higher ones for us, even fixed one public static final Setting NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting( @@ -199,13 +198,13 @@ public class NettyTransport extends AbstractLifecycleComponent implem defaultReceiverPredictor = Math.min(defaultReceiverPredictor, Math.max(l, 64 * 1024)); } return new ByteSizeValue(defaultReceiverPredictor).toString(); - }, false, SettingsProperty.ClusterScope); + }, SettingsProperty.ClusterScope); public static final Setting NETTY_RECEIVE_PREDICTOR_MIN = - byteSizeSetting("transport.netty.receive_predictor_min", NETTY_RECEIVE_PREDICTOR_SIZE, false, SettingsProperty.ClusterScope); + byteSizeSetting("transport.netty.receive_predictor_min", NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); public static final Setting NETTY_RECEIVE_PREDICTOR_MAX = - byteSizeSetting("transport.netty.receive_predictor_max", NETTY_RECEIVE_PREDICTOR_SIZE, false, SettingsProperty.ClusterScope); + byteSizeSetting("transport.netty.receive_predictor_max", NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); public static final Setting NETTY_BOSS_COUNT = - intSetting("transport.netty.boss_count", 1, 1, false, SettingsProperty.ClusterScope); + intSetting("transport.netty.boss_count", 1, 1, SettingsProperty.ClusterScope); protected final NetworkService networkService; protected final Version version; diff --git a/core/src/main/java/org/elasticsearch/tribe/TribeService.java b/core/src/main/java/org/elasticsearch/tribe/TribeService.java index 0b4f99457eb..fb03153b215 100644 --- a/core/src/main/java/org/elasticsearch/tribe/TribeService.java +++ b/core/src/main/java/org/elasticsearch/tribe/TribeService.java @@ -122,7 +122,7 @@ public class TribeService extends AbstractLifecycleComponent { } // internal settings only - public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", false, SettingsProperty.ClusterScope); + public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", SettingsProperty.ClusterScope); private final ClusterService clusterService; private final String[] blockIndicesWrite; private final String[] blockIndicesRead; @@ -141,21 +141,18 @@ public class TribeService extends AbstractLifecycleComponent { throw new IllegalArgumentException( "Invalid value for [tribe.on_conflict] must be either [any, drop or start with prefer_] but was: [" + s + "]"); } - }, false, SettingsProperty.ClusterScope); + }, SettingsProperty.ClusterScope); public static final Setting BLOCKS_METADATA_SETTING = - Setting.boolSetting("tribe.blocks.metadata", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("tribe.blocks.metadata", false, SettingsProperty.ClusterScope); public static final Setting BLOCKS_WRITE_SETTING = - Setting.boolSetting("tribe.blocks.write", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("tribe.blocks.write", false, SettingsProperty.ClusterScope); public static final Setting> BLOCKS_WRITE_INDICES_SETTING = - Setting.listSetting("tribe.blocks.write.indices", Collections.emptyList(), Function.identity(), false, - SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.write.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Setting> BLOCKS_READ_INDICES_SETTING = - Setting.listSetting("tribe.blocks.read.indices", Collections.emptyList(), Function.identity(), false, - SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.read.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Setting> BLOCKS_METADATA_INDICES_SETTING = - Setting.listSetting("tribe.blocks.metadata.indices", Collections.emptyList(), Function.identity(), false, - SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.metadata.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Set TRIBE_SETTING_KEYS = Sets.newHashSet(TRIBE_NAME_SETTING.getKey(), ON_CONFLICT_SETTING.getKey(), BLOCKS_METADATA_INDICES_SETTING.getKey(), BLOCKS_METADATA_SETTING.getKey(), BLOCKS_READ_INDICES_SETTING.getKey(), BLOCKS_WRITE_INDICES_SETTING.getKey(), BLOCKS_WRITE_SETTING.getKey()); diff --git a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java index 9efccd0afd2..cdf4185c94d 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java @@ -84,7 +84,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterClusterDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope)); assertInstanceBinding(module, ClusterSettings.class, service -> service.hasDynamicSetting("foo.bar")); } @@ -99,7 +99,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterIndexDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, true, SettingsProperty.IndexScope)); + module.registerSetting(Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope)); assertInstanceBinding(module, IndexScopedSettings.class, service -> service.hasDynamicSetting("foo.bar")); } diff --git a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java index 9590d214d5b..811ddc7ae5a 100644 --- a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java @@ -47,9 +47,9 @@ public class SettingsFilteringIT extends ESIntegTestCase { public static class SettingsFilteringPlugin extends Plugin { public static final Setting SOME_NODE_SETTING = - Setting.boolSetting("some.node.setting", false, false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.boolSetting("some.node.setting", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting SOME_OTHER_NODE_SETTING = - Setting.boolSetting("some.other.node.setting", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("some.other.node.setting", false, SettingsProperty.ClusterScope); /** * The name of the plugin. @@ -75,7 +75,7 @@ public class SettingsFilteringIT extends ESIntegTestCase { public void onModule(SettingsModule module) { module.registerSetting(SOME_NODE_SETTING); module.registerSetting(SOME_OTHER_NODE_SETTING); - module.registerSetting(Setting.groupSetting("index.filter_test.", false, SettingsProperty.IndexScope)); + module.registerSetting(Setting.groupSetting("index.filter_test.", SettingsProperty.IndexScope)); module.registerSettingsFilter("index.filter_test.foo"); module.registerSettingsFilter("index.filter_test.bar*"); } diff --git a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index 7a2e424393b..41367621f95 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -39,8 +39,8 @@ import java.util.concurrent.atomic.AtomicReference; public class ScopedSettingsTests extends ESTestCase { public void testAddConsumer() { - Setting testSetting = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, SettingsProperty.ClusterScope); + Setting testSetting = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, Collections.singleton(testSetting)); AtomicInteger consumer = new AtomicInteger(); @@ -67,8 +67,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testApply() { - Setting testSetting = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, true, SettingsProperty.ClusterScope); + Setting testSetting = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(testSetting, testSetting2))); AtomicInteger consumer = new AtomicInteger(); @@ -139,8 +139,8 @@ public class ScopedSettingsTests extends ESTestCase { public void testIsDynamic(){ ClusterSettings settings = new ClusterSettings(Settings.EMPTY, - new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope), - Setting.intSetting("foo.bar.baz", 1, false, SettingsProperty.ClusterScope)))); + new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope), + Setting.intSetting("foo.bar.baz", 1, SettingsProperty.ClusterScope)))); assertFalse(settings.hasDynamicSetting("foo.bar.baz")); assertTrue(settings.hasDynamicSetting("foo.bar")); assertNotNull(settings.get("foo.bar.baz")); @@ -151,8 +151,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testDiff() throws IOException { - Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, false, SettingsProperty.ClusterScope); - Setting foobar = Setting.intSetting("foo.bar", 1, true, SettingsProperty.ClusterScope); + Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.ClusterScope); + Setting foobar = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); ClusterSettings settings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(foobar, foobarbaz))); Settings diff = settings.diff(Settings.builder().put("foo.bar", 5).build(), Settings.EMPTY); assertEquals(diff.getAsMap().size(), 1); @@ -241,22 +241,22 @@ public class ScopedSettingsTests extends ESTestCase { try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", false, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", SettingsProperty.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo .]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", false, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", SettingsProperty.IndexScope))); try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, false, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, SettingsProperty.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo.]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, false, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, SettingsProperty.IndexScope))); } public void testLoggingUpdates() { diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index ed9213d392a..b916783b316 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -36,20 +36,20 @@ public class SettingTests extends ESTestCase { public void testGet() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertFalse(booleanSetting.get(Settings.EMPTY)); assertFalse(booleanSetting.get(Settings.builder().put("foo.bar", false).build())); - assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", true).build())); + assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", SettingsProperty.Dynamic).build())); } public void testByteSize() { Setting byteSizeValueSetting = - Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), true, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertFalse(byteSizeValueSetting.isGroupSetting()); ByteSizeValue byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 1024); - byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", true, SettingsProperty.ClusterScope); + byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 2048); @@ -68,7 +68,7 @@ public class SettingTests extends ESTestCase { } public void testSimpleUpdate() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); AtomicReference atomicBoolean = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(atomicBoolean::set, logger); Settings build = Settings.builder().put("foo.bar", false).build(); @@ -89,7 +89,7 @@ public class SettingTests extends ESTestCase { } public void testUpdateNotDynamic() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, false, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.ClusterScope); assertFalse(booleanSetting.isGroupSetting()); AtomicReference atomicBoolean = new AtomicReference<>(null); try { @@ -101,7 +101,7 @@ public class SettingTests extends ESTestCase { } public void testUpdaterIsIsolated() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); AtomicReference ab1 = new AtomicReference<>(null); AtomicReference ab2 = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(ab1::set, logger); @@ -113,7 +113,7 @@ public class SettingTests extends ESTestCase { public void testDefault() { TimeValue defautlValue = TimeValue.timeValueMillis(randomIntBetween(0, 1000000)); Setting setting = - Setting.positiveTimeSetting("my.time.value", defautlValue, randomBoolean(), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("my.time.value", defautlValue, SettingsProperty.ClusterScope); assertFalse(setting.isGroupSetting()); String aDefault = setting.getDefaultRaw(Settings.EMPTY); assertEquals(defautlValue.millis() + "ms", aDefault); @@ -121,18 +121,19 @@ public class SettingTests extends ESTestCase { assertEquals(defautlValue, setting.getDefault(Settings.EMPTY)); Setting secondaryDefault = - new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), (s) -> s, randomBoolean(), SettingsProperty.ClusterScope); + new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), (s) -> s, SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefault.get(Settings.EMPTY)); assertEquals("42", secondaryDefault.get(Settings.builder().put("old.foo.bar", 42).build())); Setting secondaryDefaultViaSettings = - new Setting<>("foo.bar", secondaryDefault, (s) -> s, randomBoolean(), SettingsProperty.ClusterScope); + new Setting<>("foo.bar", secondaryDefault, (s) -> s, SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefaultViaSettings.get(Settings.EMPTY)); assertEquals("42", secondaryDefaultViaSettings.get(Settings.builder().put("old.foo.bar", 42).build())); } public void testComplexType() { AtomicReference ref = new AtomicReference<>(null); - Setting setting = new Setting<>("foo.bar", (s) -> "", (s) -> new ComplexType(s), true, SettingsProperty.ClusterScope); + Setting setting = new Setting<>("foo.bar", (s) -> "", (s) -> new ComplexType(s), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertFalse(setting.isGroupSetting()); ref.set(setting.get(Settings.EMPTY)); ComplexType type = ref.get(); @@ -153,11 +154,11 @@ public class SettingTests extends ESTestCase { } public void testType() { - Setting integerSetting = Setting.intSetting("foo.int.bar", 1, true, SettingsProperty.ClusterScope); + Setting integerSetting = Setting.intSetting("foo.int.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertThat(integerSetting.hasClusterScope(), is(true)); assertThat(integerSetting.hasIndexScope(), is(false)); assertThat(integerSetting.hasNodeScope(), is(false)); - integerSetting = Setting.intSetting("foo.int.bar", 1, true, SettingsProperty.IndexScope); + integerSetting = Setting.intSetting("foo.int.bar", 1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); assertThat(integerSetting.hasIndexScope(), is(true)); assertThat(integerSetting.hasClusterScope(), is(false)); assertThat(integerSetting.hasNodeScope(), is(false)); @@ -165,7 +166,7 @@ public class SettingTests extends ESTestCase { public void testGroups() { AtomicReference ref = new AtomicReference<>(null); - Setting setting = Setting.groupSetting("foo.bar.", true, SettingsProperty.ClusterScope); + Setting setting = Setting.groupSetting("foo.bar.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertTrue(setting.isGroupSetting()); ClusterSettings.SettingUpdater settingUpdater = setting.newUpdater(ref::set, logger); @@ -243,8 +244,8 @@ public class SettingTests extends ESTestCase { public void testComposite() { Composite c = new Composite(); - Setting a = Setting.intSetting("foo.int.bar.a", 1, true, SettingsProperty.ClusterScope); - Setting b = Setting.intSetting("foo.int.bar.b", 1, true, SettingsProperty.ClusterScope); + Setting a = Setting.intSetting("foo.int.bar.a", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting b = Setting.intSetting("foo.int.bar.b", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); ClusterSettings.SettingUpdater> settingUpdater = Setting.compoundUpdater(c::set, a, b, logger); assertFalse(settingUpdater.apply(Settings.EMPTY, Settings.EMPTY)); assertNull(c.a); @@ -272,7 +273,8 @@ public class SettingTests extends ESTestCase { } public void testListSettings() { - Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, SettingsProperty.ClusterScope); + Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); List value = listSetting.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -311,7 +313,8 @@ public class SettingTests extends ESTestCase { assertEquals(1, ref.get().size()); assertEquals("foo,bar", ref.get().get(0)); - Setting> otherSettings = Setting.listSetting("foo.bar", Collections.emptyList(), Integer::parseInt, true, SettingsProperty.ClusterScope); + Setting> otherSettings = Setting.listSetting("foo.bar", Collections.emptyList(), Integer::parseInt, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); List defaultValue = otherSettings.get(Settings.EMPTY); assertEquals(0, defaultValue.size()); List intValues = otherSettings.get(Settings.builder().put("foo.bar", "0,1,2,3").build()); @@ -320,7 +323,8 @@ public class SettingTests extends ESTestCase { assertEquals(i, intValues.get(i).intValue()); } - Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, s -> s, true, SettingsProperty.ClusterScope); + Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, s -> s, + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); value = settingWithFallback.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -342,7 +346,8 @@ public class SettingTests extends ESTestCase { } public void testListSettingAcceptsNumberSyntax() { - Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), true, SettingsProperty.ClusterScope); + Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), + SettingsProperty.Dynamic, SettingsProperty.ClusterScope); List input = Arrays.asList("test", "test1, test2", "test", ",,,,"); Settings.Builder builder = Settings.builder().putArray("foo.bar", input.toArray(new String[0])); // try to parse this really annoying format @@ -360,7 +365,7 @@ public class SettingTests extends ESTestCase { } public void testDynamicKeySetting() { - Setting setting = Setting.dynamicKeySetting("foo.", "false", Boolean::parseBoolean, false, SettingsProperty.ClusterScope); + Setting setting = Setting.dynamicKeySetting("foo.", "false", Boolean::parseBoolean, SettingsProperty.ClusterScope); assertTrue(setting.hasComplexMatcher()); assertTrue(setting.match("foo.bar")); assertFalse(setting.match("foo")); @@ -377,7 +382,7 @@ public class SettingTests extends ESTestCase { } public void testMinMaxInt() { - Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, false, SettingsProperty.ClusterScope); + Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, SettingsProperty.ClusterScope); try { integerSetting.get(Settings.builder().put("foo.bar", 11).build()); fail(); diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java index 3cd2bb2d021..f5fd760297b 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java @@ -46,13 +46,13 @@ public class SettingsModuleTests extends ModuleTestCase { { Settings settings = Settings.builder().put("some.custom.setting", "2.0").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, SettingsProperty.ClusterScope)); assertInstanceBinding(module, Settings.class, (s) -> s == settings); } { Settings settings = Settings.builder().put("some.custom.setting", "false").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, false, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, SettingsProperty.ClusterScope)); try { assertInstanceBinding(module, Settings.class, (s) -> s == settings); fail(); @@ -132,9 +132,9 @@ public class SettingsModuleTests extends ModuleTestCase { public void testRegisterSettingsFilter() { Settings settings = Settings.builder().put("foo.bar", "false").put("bar.foo", false).put("bar.baz", false).build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.boolSetting("foo.bar", true, false, SettingsProperty.ClusterScope)); - module.registerSetting(Setting.boolSetting("bar.foo", true, false, SettingsProperty.ClusterScope, SettingsProperty.Filtered)); - module.registerSetting(Setting.boolSetting("bar.baz", true, false, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("foo.bar", true, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("bar.foo", true, SettingsProperty.ClusterScope, SettingsProperty.Filtered)); + module.registerSetting(Setting.boolSetting("bar.baz", true, SettingsProperty.ClusterScope)); module.registerSettingsFilter("foo.*"); try { diff --git a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java index 5a17caff67d..7da2b0aaa2d 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java @@ -195,9 +195,9 @@ public class IndexModuleTests extends ESTestCase { public void testListener() throws IOException { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, true, SettingsProperty.IndexScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(index, settings, booleanSetting), null, new AnalysisRegistry(null, environment)); - Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, true, SettingsProperty.IndexScope); + Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); AtomicBoolean atomicBoolean = new AtomicBoolean(false); module.addSettingsUpdateConsumer(booleanSetting, atomicBoolean::set); diff --git a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java index ad8edee61bf..18af7e13f7d 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java @@ -45,7 +45,8 @@ public class IndexSettingsTests extends ESTestCase { Version version = VersionUtils.getPreviousVersion(); Settings theSettings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).put(IndexMetaData.SETTING_INDEX_UUID, "0xdeadbeef").build(); final AtomicInteger integer = new AtomicInteger(0); - Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, SettingsProperty.IndexScope); + Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); IndexMetaData metaData = newIndexMeta("index", theSettings); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -66,8 +67,10 @@ public class IndexSettingsTests extends ESTestCase { .put(IndexMetaData.SETTING_INDEX_UUID, "0xdeadbeef").build(); final AtomicInteger integer = new AtomicInteger(0); final StringBuilder builder = new StringBuilder(); - Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, true, SettingsProperty.IndexScope); - Setting notUpdated = new Setting<>("index.not.updated", "", Function.identity(), true, SettingsProperty.IndexScope); + Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting notUpdated = new Setting<>("index.not.updated", "", Function.identity(), + SettingsProperty.Dynamic, SettingsProperty.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting, notUpdated); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -129,7 +132,7 @@ public class IndexSettingsTests extends ESTestCase { Settings nodeSettings = Settings.settingsBuilder().put("index.foo.bar", 43).build(); final AtomicInteger indexValue = new AtomicInteger(0); - Setting integerSetting = Setting.intSetting("index.foo.bar", -1, true, SettingsProperty.IndexScope); + Setting integerSetting = Setting.intSetting("index.foo.bar", -1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), nodeSettings, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, indexValue::set); assertEquals(numReplicas, settings.getNumberOfReplicas()); diff --git a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java index 69f5316d4d0..666994e823a 100644 --- a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java +++ b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java @@ -44,7 +44,8 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsListenerPlugin extends Plugin { private final SettingsTestingService service = new SettingsTestingService(); - private static final Setting SETTING = Setting.intSetting("index.test.new.setting", 0, true, SettingsProperty.IndexScope); + private static final Setting SETTING = Setting.intSetting("index.test.new.setting", 0, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); /** * The name of the plugin. */ @@ -94,7 +95,8 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsTestingService { public volatile int value; - public static Setting VALUE = Setting.intSetting("index.test.new.setting", -1, -1, true, SettingsProperty.IndexScope); + public static Setting VALUE = Setting.intSetting("index.test.new.setting", -1, -1, + SettingsProperty.Dynamic, SettingsProperty.IndexScope); public void setValue(int value) { this.value = value; diff --git a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java index 8dee6712833..23c9fb43715 100644 --- a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java @@ -644,11 +644,11 @@ public class IndicesOptionsIntegrationIT extends ESIntegTestCase { } private static final Setting INDEX_A = - new Setting<>("index.a", "", Function.identity(), true, SettingsProperty.IndexScope); + new Setting<>("index.a", "", Function.identity(), SettingsProperty.Dynamic, SettingsProperty.IndexScope); private static final Setting INDEX_C = - new Setting<>("index.c", "", Function.identity(), true, SettingsProperty.IndexScope); + new Setting<>("index.c", "", Function.identity(), SettingsProperty.Dynamic, SettingsProperty.IndexScope); private static final Setting INDEX_E = - new Setting<>("index.e", "", Function.identity(), false, SettingsProperty.IndexScope); + new Setting<>("index.e", "", Function.identity(), SettingsProperty.IndexScope); public void onModule(SettingsModule module) { diff --git a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java index d1ad28101ff..e025246a2f0 100644 --- a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java +++ b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java @@ -199,9 +199,9 @@ public class RandomExceptionCircuitBreakerIT extends ESIntegTestCase { public static class RandomExceptionDirectoryReaderWrapper extends MockEngineSupport.DirectoryReaderWrapper { public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); public static class TestPlugin extends Plugin { @Override public String name() { diff --git a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java index ee260a51b04..f53ca39941a 100644 --- a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java +++ b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java @@ -154,9 +154,9 @@ public class SearchWithRandomExceptionsIT extends ESIntegTestCase { public static class TestPlugin extends Plugin { public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); @Override public String name() { return "random-exception-reader-wrapper"; diff --git a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java index 02fd27a952d..8669a38087e 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java +++ b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java @@ -60,10 +60,9 @@ public class MockRepository extends FsRepository { public static class Plugin extends org.elasticsearch.plugins.Plugin { - public static final Setting USERNAME_SETTING = - Setting.simpleString("secret.mock.username", false, SettingsProperty.ClusterScope); + public static final Setting USERNAME_SETTING = Setting.simpleString("secret.mock.username", SettingsProperty.ClusterScope); public static final Setting PASSWORD_SETTING = - Setting.simpleString("secret.mock.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("secret.mock.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); @Override public String name() { diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java index 0a6a752908f..a59510b8873 100644 --- a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java +++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java @@ -30,29 +30,28 @@ public interface AzureComputeService { final class Management { public static final Setting SUBSCRIPTION_ID_SETTING = - Setting.simpleString("cloud.azure.management.subscription.id", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.azure.management.subscription.id", SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting SERVICE_NAME_SETTING = - Setting.simpleString("cloud.azure.management.cloud.service.name", false, SettingsProperty.ClusterScope); + Setting.simpleString("cloud.azure.management.cloud.service.name", SettingsProperty.ClusterScope); // Keystore settings public static final Setting KEYSTORE_PATH_SETTING = - Setting.simpleString("cloud.azure.management.keystore.path", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.azure.management.keystore.path", SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting KEYSTORE_PASSWORD_SETTING = - Setting.simpleString("cloud.azure.management.keystore.password", false, SettingsProperty.ClusterScope, + Setting.simpleString("cloud.azure.management.keystore.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting KEYSTORE_TYPE_SETTING = - new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, false, + new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, SettingsProperty.ClusterScope, SettingsProperty.Filtered); } final class Discovery { public static final Setting REFRESH_SETTING = - Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), false, - SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), SettingsProperty.ClusterScope); public static final Setting HOST_TYPE_SETTING = new Setting<>("discovery.azure.host.type", AzureUnicastHostsProvider.HostType.PRIVATE_IP.name(), - AzureUnicastHostsProvider.HostType::fromString, false, SettingsProperty.ClusterScope); + AzureUnicastHostsProvider.HostType::fromString, SettingsProperty.ClusterScope); public static final String ENDPOINT_NAME = "discovery.azure.endpoint.name"; public static final String DEPLOYMENT_NAME = "discovery.azure.deployment.name"; diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java index b88704e18db..2f2c423afb7 100644 --- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java +++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java @@ -33,8 +33,7 @@ import java.util.Locale; import java.util.function.Function; public interface AwsEc2Service { - Setting AUTO_ATTRIBUTE_SETTING = - Setting.boolSetting("cloud.node.auto_attributes", false, false, SettingsProperty.ClusterScope); + Setting AUTO_ATTRIBUTE_SETTING = Setting.boolSetting("cloud.node.auto_attributes", false, SettingsProperty.ClusterScope); // Global AWS settings (shared between discovery-ec2 and repository-s3) // Each setting starting with `cloud.aws` also exists in repository-s3 project. Don't forget to update @@ -43,43 +42,43 @@ public interface AwsEc2Service { * cloud.aws.access_key: AWS Access key. Shared with repository-s3 plugin */ Setting KEY_SETTING = - Setting.simpleString("cloud.aws.access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with repository-s3 plugin */ Setting SECRET_SETTING = - Setting.simpleString("cloud.aws.secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with repository-s3 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - false, SettingsProperty.ClusterScope); + SettingsProperty.ClusterScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with repository-s3 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, SettingsProperty.ClusterScope); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", SettingsProperty.ClusterScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with repository-s3 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, SettingsProperty.ClusterScope); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with repository-s3 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, SettingsProperty.ClusterScope); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", SettingsProperty.ClusterScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with repository-s3 plugin */ Setting PROXY_PASSWORD_SETTING = - Setting.simpleString("cloud.aws.proxy.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.proxy.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with repository-s3 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, SettingsProperty.ClusterScope); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", SettingsProperty.ClusterScope); /** * cloud.aws.region: Region. Shared with repository-s3 plugin */ Setting REGION_SETTING = - new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * Defines specific ec2 settings starting with cloud.aws.ec2. @@ -89,63 +88,63 @@ public interface AwsEc2Service { * cloud.aws.ec2.access_key: AWS Access key specific for EC2 API calls. Defaults to cloud.aws.access_key. * @see AwsEc2Service#KEY_SETTING */ - Setting KEY_SETTING = new Setting<>("cloud.aws.ec2.access_key", AwsEc2Service.KEY_SETTING, Function.identity(), false, + Setting KEY_SETTING = new Setting<>("cloud.aws.ec2.access_key", AwsEc2Service.KEY_SETTING, Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.secret_key: AWS Secret key specific for EC2 API calls. Defaults to cloud.aws.secret_key. * @see AwsEc2Service#SECRET_SETTING */ - Setting SECRET_SETTING = new Setting<>("cloud.aws.ec2.secret_key", AwsEc2Service.SECRET_SETTING, Function.identity(), false, + Setting SECRET_SETTING = new Setting<>("cloud.aws.ec2.secret_key", AwsEc2Service.SECRET_SETTING, Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.protocol: Protocol for AWS API specific for EC2 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsEc2Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.ec2.protocol", AwsEc2Service.PROTOCOL_SETTING, - s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); + s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.host: In case of proxy, define its hostname/IP specific for EC2 API calls. Defaults to cloud.aws.proxy.host. * @see AwsEc2Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = new Setting<>("cloud.aws.ec2.proxy.host", AwsEc2Service.PROXY_HOST_SETTING, - Function.identity(), false, SettingsProperty.ClusterScope); + Function.identity(), SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.port: In case of proxy, define its port specific for EC2 API calls. Defaults to cloud.aws.proxy.port. * @see AwsEc2Service#PROXY_PORT_SETTING */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.ec2.proxy.port", AwsEc2Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), false, SettingsProperty.ClusterScope); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.username: In case of proxy with auth, define the username specific for EC2 API calls. * Defaults to cloud.aws.proxy.username. * @see AwsEc2Service#PROXY_USERNAME_SETTING */ Setting PROXY_USERNAME_SETTING = new Setting<>("cloud.aws.ec2.proxy.username", AwsEc2Service.PROXY_USERNAME_SETTING, - Function.identity(), false, SettingsProperty.ClusterScope); + Function.identity(), SettingsProperty.ClusterScope); /** * cloud.aws.ec2.proxy.password: In case of proxy with auth, define the password specific for EC2 API calls. * Defaults to cloud.aws.proxy.password. * @see AwsEc2Service#PROXY_PASSWORD_SETTING */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.ec2.proxy.password", AwsEc2Service.PROXY_PASSWORD_SETTING, - Function.identity(), false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.ec2.signer: If you are using an old AWS API version, you can define a Signer. Specific for EC2 API calls. * Defaults to cloud.aws.signer. * @see AwsEc2Service#SIGNER_SETTING */ Setting SIGNER_SETTING = new Setting<>("cloud.aws.ec2.signer", AwsEc2Service.SIGNER_SETTING, Function.identity(), - false, SettingsProperty.ClusterScope); + SettingsProperty.ClusterScope); /** * cloud.aws.ec2.region: Region specific for EC2 API calls. Defaults to cloud.aws.region. * @see AwsEc2Service#REGION_SETTING */ Setting REGION_SETTING = new Setting<>("cloud.aws.ec2.region", AwsEc2Service.REGION_SETTING, - s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * cloud.aws.ec2.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ - Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", false, SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", SettingsProperty.ClusterScope); } /** @@ -164,32 +163,32 @@ public interface AwsEc2Service { * Can be one of private_ip, public_ip, private_dns, public_dns. Defaults to private_ip. */ Setting HOST_TYPE_SETTING = - new Setting<>("discovery.ec2.host_type", HostType.PRIVATE_IP.name(), s -> HostType.valueOf(s.toUpperCase(Locale.ROOT)), false, + new Setting<>("discovery.ec2.host_type", HostType.PRIVATE_IP.name(), s -> HostType.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); /** * discovery.ec2.any_group: If set to false, will require all security groups to be present for the instance to be used for the * discovery. Defaults to true. */ Setting ANY_GROUP_SETTING = - Setting.boolSetting("discovery.ec2.any_group", true, false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.ec2.any_group", true, SettingsProperty.ClusterScope); /** * discovery.ec2.groups: Either a comma separated list or array based list of (security) groups. Only instances with the provided * security groups will be used in the cluster discovery. (NOTE: You could provide either group NAME or group ID.) */ Setting> GROUPS_SETTING = - Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), false, SettingsProperty.ClusterScope); + Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), SettingsProperty.ClusterScope); /** * discovery.ec2.availability_zones: Either a comma separated list or array based list of availability zones. Only instances within * the provided availability zones will be used in the cluster discovery. */ Setting> AVAILABILITY_ZONES_SETTING = - Setting.listSetting("discovery.ec2.availability_zones", Collections.emptyList(), s -> s.toString(), false, + Setting.listSetting("discovery.ec2.availability_zones", Collections.emptyList(), s -> s.toString(), SettingsProperty.ClusterScope); /** * discovery.ec2.node_cache_time: How long the list of hosts is cached to prevent further requests to the AWS API. Defaults to 10s. */ Setting NODE_CACHE_TIME_SETTING = - Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), false, SettingsProperty.ClusterScope); + Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), SettingsProperty.ClusterScope); /** * discovery.ec2.tag.*: The ec2 discovery can filter machines to include in the cluster based on tags (and not just groups). @@ -197,7 +196,7 @@ public interface AwsEc2Service { * instances with a tag key set to stage, and a value of dev. Several tags set will require all of those tags to be set for the * instance to be included. */ - Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", false, SettingsProperty.ClusterScope); + Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", SettingsProperty.ClusterScope); } AmazonEC2 client(); diff --git a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java index 53e0c10d058..66d8365476b 100644 --- a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java +++ b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java @@ -73,11 +73,11 @@ public class AttachmentMapper extends FieldMapper { private static ESLogger logger = ESLoggerFactory.getLogger("mapper.attachment"); public static final Setting INDEX_ATTACHMENT_IGNORE_ERRORS_SETTING = - Setting.boolSetting("index.mapping.attachment.ignore_errors", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.attachment.ignore_errors", true, SettingsProperty.IndexScope); public static final Setting INDEX_ATTACHMENT_DETECT_LANGUAGE_SETTING = - Setting.boolSetting("index.mapping.attachment.detect_language", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.attachment.detect_language", false, SettingsProperty.IndexScope); public static final Setting INDEX_ATTACHMENT_INDEXED_CHARS_SETTING = - Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, false, SettingsProperty.IndexScope); + Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, SettingsProperty.IndexScope); public static final String CONTENT_TYPE = "attachment"; diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java index f16e9b6729c..197bde69a1c 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java @@ -42,19 +42,19 @@ public interface AzureStorageService { final class Storage { public static final String PREFIX = "cloud.azure.storage."; public static final Setting TIMEOUT_SETTING = - Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), false, SettingsProperty.ClusterScope); + Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(5), SettingsProperty.ClusterScope); public static final Setting ACCOUNT_SETTING = - Setting.simpleString("repositories.azure.account", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("repositories.azure.account", SettingsProperty.ClusterScope, SettingsProperty.Filtered); public static final Setting CONTAINER_SETTING = - Setting.simpleString("repositories.azure.container", false, SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.container", SettingsProperty.ClusterScope); public static final Setting BASE_PATH_SETTING = - Setting.simpleString("repositories.azure.base_path", false, SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.base_path", SettingsProperty.ClusterScope); public static final Setting LOCATION_MODE_SETTING = - Setting.simpleString("repositories.azure.location_mode", false, SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.location_mode", SettingsProperty.ClusterScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); public static final Setting COMPRESS_SETTING = - Setting.boolSetting("repositories.azure.compress", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.azure.compress", false, SettingsProperty.ClusterScope); } boolean doesContainerExist(String account, LocationMode mode, String container); diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index 013007a84a7..56b2d9fc253 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -68,17 +68,14 @@ public class AzureRepository extends BlobStoreRepository { public final static String TYPE = "azure"; public static final class Repository { - public static final Setting ACCOUNT_SETTING = - Setting.simpleString("account", false, SettingsProperty.ClusterScope); + public static final Setting ACCOUNT_SETTING = Setting.simpleString("account", SettingsProperty.ClusterScope); public static final Setting CONTAINER_SETTING = - new Setting<>("container", "elasticsearch-snapshots", Function.identity(), false, SettingsProperty.ClusterScope); - public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, SettingsProperty.ClusterScope); - public static final Setting LOCATION_MODE_SETTING = - Setting.simpleString("location_mode", false, SettingsProperty.ClusterScope); + new Setting<>("container", "elasticsearch-snapshots", Function.identity(), SettingsProperty.ClusterScope); + public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", SettingsProperty.ClusterScope); + public static final Setting LOCATION_MODE_SETTING = Setting.simpleString("location_mode", SettingsProperty.ClusterScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, false, SettingsProperty.ClusterScope); - public static final Setting COMPRESS_SETTING = - Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, SettingsProperty.ClusterScope); + public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); } private final AzureBlobStore blobStore; diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java index 22bc136523b..6f18bd3e6fd 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java @@ -40,43 +40,43 @@ public interface AwsS3Service extends LifecycleComponent { * cloud.aws.access_key: AWS Access key. Shared with discovery-ec2 plugin */ Setting KEY_SETTING = - Setting.simpleString("cloud.aws.access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with discovery-ec2 plugin */ Setting SECRET_SETTING = - Setting.simpleString("cloud.aws.secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with discovery-ec2 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - false, SettingsProperty.ClusterScope); + SettingsProperty.ClusterScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with discovery-ec2 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", false, SettingsProperty.ClusterScope); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", SettingsProperty.ClusterScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with discovery-ec2 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, false, SettingsProperty.ClusterScope); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, SettingsProperty.ClusterScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with discovery-ec2 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", false, SettingsProperty.ClusterScope); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", SettingsProperty.ClusterScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with discovery-ec2 plugin */ Setting PROXY_PASSWORD_SETTING = - Setting.simpleString("cloud.aws.proxy.password", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.proxy.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with discovery-ec2 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", false, SettingsProperty.ClusterScope); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", SettingsProperty.ClusterScope); /** * cloud.aws.region: Region. Shared with discovery-ec2 plugin */ Setting REGION_SETTING = - new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * Defines specific s3 settings starting with cloud.aws.s3. @@ -87,28 +87,28 @@ public interface AwsS3Service extends LifecycleComponent { * @see AwsS3Service#KEY_SETTING */ Setting KEY_SETTING = - new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), false, + new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.secret_key: AWS Secret key specific for S3 API calls. Defaults to cloud.aws.secret_key. * @see AwsS3Service#SECRET_SETTING */ Setting SECRET_SETTING = - new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), false, + new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.protocol: Protocol for AWS API specific for S3 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsS3Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = - new Setting<>("cloud.aws.s3.protocol", AwsS3Service.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, + new Setting<>("cloud.aws.s3.protocol", AwsS3Service.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.host: In case of proxy, define its hostname/IP specific for S3 API calls. Defaults to cloud.aws.proxy.host. * @see AwsS3Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = - new Setting<>("cloud.aws.s3.proxy.host", AwsS3Service.PROXY_HOST_SETTING, Function.identity(), false, + new Setting<>("cloud.aws.s3.proxy.host", AwsS3Service.PROXY_HOST_SETTING, Function.identity(), SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.port: In case of proxy, define its port specific for S3 API calls. Defaults to cloud.aws.proxy.port. @@ -116,14 +116,14 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.s3.proxy.port", AwsS3Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), false, SettingsProperty.ClusterScope); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.username: In case of proxy with auth, define the username specific for S3 API calls. * Defaults to cloud.aws.proxy.username. * @see AwsS3Service#PROXY_USERNAME_SETTING */ Setting PROXY_USERNAME_SETTING = - new Setting<>("cloud.aws.s3.proxy.username", AwsS3Service.PROXY_USERNAME_SETTING, Function.identity(), false, + new Setting<>("cloud.aws.s3.proxy.username", AwsS3Service.PROXY_USERNAME_SETTING, Function.identity(), SettingsProperty.ClusterScope); /** * cloud.aws.s3.proxy.password: In case of proxy with auth, define the password specific for S3 API calls. @@ -131,7 +131,7 @@ public interface AwsS3Service extends LifecycleComponent { * @see AwsS3Service#PROXY_PASSWORD_SETTING */ Setting PROXY_PASSWORD_SETTING = - new Setting<>("cloud.aws.s3.proxy.password", AwsS3Service.PROXY_PASSWORD_SETTING, Function.identity(), false, + new Setting<>("cloud.aws.s3.proxy.password", AwsS3Service.PROXY_PASSWORD_SETTING, Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * cloud.aws.s3.signer: If you are using an old AWS API version, you can define a Signer. Specific for S3 API calls. @@ -139,19 +139,18 @@ public interface AwsS3Service extends LifecycleComponent { * @see AwsS3Service#SIGNER_SETTING */ Setting SIGNER_SETTING = - new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), SettingsProperty.ClusterScope); /** * cloud.aws.s3.region: Region specific for S3 API calls. Defaults to cloud.aws.region. * @see AwsS3Service#REGION_SETTING */ Setting REGION_SETTING = - new Setting<>("cloud.aws.s3.region", AwsS3Service.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), false, + new Setting<>("cloud.aws.s3.region", AwsS3Service.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * cloud.aws.s3.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ - Setting ENDPOINT_SETTING = - Setting.simpleString("cloud.aws.s3.endpoint", false, SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.s3.endpoint", SettingsProperty.ClusterScope); } AmazonS3 client(String endpoint, Protocol protocol, String region, String account, String key, Integer maxRetries); diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index 3fdc8a487aa..dc0915cd276 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -67,41 +67,41 @@ public class S3Repository extends BlobStoreRepository { * @see CLOUD_S3#KEY_SETTING */ Setting KEY_SETTING = - new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), SettingsProperty.ClusterScope); /** * repositories.s3.secret_key: AWS Secret key specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.secret_key. * @see CLOUD_S3#SECRET_SETTING */ Setting SECRET_SETTING = - new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), SettingsProperty.ClusterScope); /** * repositories.s3.region: Region specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.region. * @see CLOUD_S3#REGION_SETTING */ Setting REGION_SETTING = - new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * repositories.s3.endpoint: Endpoint specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.endpoint. * @see CLOUD_S3#ENDPOINT_SETTING */ Setting ENDPOINT_SETTING = - new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * repositories.s3.protocol: Protocol specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.protocol. * @see CLOUD_S3#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = - new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); /** * repositories.s3.bucket: The name of the bucket to be used for snapshots. */ - Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", false, SettingsProperty.ClusterScope); + Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", SettingsProperty.ClusterScope); /** * repositories.s3.server_side_encryption: When set to true files are encrypted on server side using AES256 algorithm. * Defaults to false. */ Setting SERVER_SIDE_ENCRYPTION_SETTING = - Setting.boolSetting("repositories.s3.server_side_encryption", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.s3.server_side_encryption", false, SettingsProperty.ClusterScope); /** * repositories.s3.buffer_size: Minimum threshold below which the chunk is uploaded using a single request. Beyond this threshold, * the S3 repository will use the AWS Multipart Upload API to split the chunk into several parts, each of buffer_size length, and @@ -109,35 +109,35 @@ public class S3Repository extends BlobStoreRepository { * use of the Multipart API and may result in upload errors. Defaults to 5mb. */ Setting BUFFER_SIZE_SETTING = - Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, SettingsProperty.ClusterScope); /** * repositories.s3.max_retries: Number of retries in case of S3 errors. Defaults to 3. */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, false, SettingsProperty.ClusterScope); + Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, SettingsProperty.ClusterScope); /** * repositories.s3.chunk_size: Big files can be broken down into chunks during snapshotting if needed. Defaults to 100m. */ Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), SettingsProperty.ClusterScope); /** * repositories.s3.compress: When set to true metadata files are stored in compressed format. This setting doesn’t affect index * files that are already compressed by default. Defaults to false. */ - Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, false, SettingsProperty.ClusterScope); + Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, SettingsProperty.ClusterScope); /** * repositories.s3.storage_class: Sets the S3 storage class type for the backup files. Values may be standard, reduced_redundancy, * standard_ia. Defaults to standard. */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", false, SettingsProperty.ClusterScope); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", SettingsProperty.ClusterScope); /** * repositories.s3.canned_acl: The S3 repository supports all S3 canned ACLs : private, public-read, public-read-write, * authenticated-read, log-delivery-write, bucket-owner-read, bucket-owner-full-control. Defaults to private. */ - Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", false, SettingsProperty.ClusterScope); + Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", SettingsProperty.ClusterScope); /** * repositories.s3.base_path: Specifies the path within bucket to repository data. Defaults to root directory. */ - Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", false, SettingsProperty.ClusterScope); + Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", SettingsProperty.ClusterScope); } /** @@ -149,77 +149,75 @@ public class S3Repository extends BlobStoreRepository { * access_key * @see Repositories#KEY_SETTING */ - Setting KEY_SETTING = - Setting.simpleString("access_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting KEY_SETTING = Setting.simpleString("access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * secret_key * @see Repositories#SECRET_SETTING */ - Setting SECRET_SETTING = - Setting.simpleString("secret_key", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting SECRET_SETTING = Setting.simpleString("secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); /** * bucket * @see Repositories#BUCKET_SETTING */ - Setting BUCKET_SETTING = Setting.simpleString("bucket", false, SettingsProperty.ClusterScope); + Setting BUCKET_SETTING = Setting.simpleString("bucket", SettingsProperty.ClusterScope); /** * endpoint * @see Repositories#ENDPOINT_SETTING */ - Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", false, SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", SettingsProperty.ClusterScope); /** * protocol * @see Repositories#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = - new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), false, SettingsProperty.ClusterScope); + new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); /** * region * @see Repositories#REGION_SETTING */ - Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), false, SettingsProperty.ClusterScope); + Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); /** * server_side_encryption * @see Repositories#SERVER_SIDE_ENCRYPTION_SETTING */ Setting SERVER_SIDE_ENCRYPTION_SETTING = - Setting.boolSetting("server_side_encryption", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("server_side_encryption", false, SettingsProperty.ClusterScope); /** * buffer_size * @see Repositories#BUFFER_SIZE_SETTING */ Setting BUFFER_SIZE_SETTING = - Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, SettingsProperty.ClusterScope); /** * max_retries * @see Repositories#MAX_RETRIES_SETTING */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, false, SettingsProperty.ClusterScope); + Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, SettingsProperty.ClusterScope); /** * chunk_size * @see Repositories#CHUNK_SIZE_SETTING */ - Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", false, SettingsProperty.ClusterScope); + Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", SettingsProperty.ClusterScope); /** * compress * @see Repositories#COMPRESS_SETTING */ - Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, false, SettingsProperty.ClusterScope); + Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); /** * storage_class * @see Repositories#STORAGE_CLASS_SETTING */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", false, SettingsProperty.ClusterScope); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", SettingsProperty.ClusterScope); /** * canned_acl * @see Repositories#CANNED_ACL_SETTING */ - Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", false, SettingsProperty.ClusterScope); + Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", SettingsProperty.ClusterScope); /** * base_path * @see Repositories#BASE_PATH_SETTING */ - Setting BASE_PATH_SETTING = Setting.simpleString("base_path", false, SettingsProperty.ClusterScope); + Setting BASE_PATH_SETTING = Setting.simpleString("base_path", SettingsProperty.ClusterScope); } private final S3BlobStore blobStore; diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index 4273c202779..22a06957d38 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -270,7 +270,7 @@ public abstract class ESIntegTestCase extends ESTestCase { * It's set once per test via a generic index template. */ public static final Setting INDEX_TEST_SEED_SETTING = - Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, false, SettingsProperty.IndexScope); + Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, SettingsProperty.IndexScope); /** * A boolean value to enable or disable mock modules. This is useful to test the diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java index 4b4692be90c..f10039391db 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java @@ -36,11 +36,11 @@ public final class InternalSettingsPlugin extends Plugin { } public static final Setting VERSION_CREATED = - Setting.intSetting("index.version.created", 0, false, SettingsProperty.IndexScope); + Setting.intSetting("index.version.created", 0, SettingsProperty.IndexScope); public static final Setting MERGE_ENABLED = - Setting.boolSetting("index.merge.enabled", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.merge.enabled", true, SettingsProperty.IndexScope); public static final Setting INDEX_CREATION_DATE_SETTING = - Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, false, SettingsProperty.IndexScope); + Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, SettingsProperty.IndexScope); public void onModule(SettingsModule module) { module.registerSetting(VERSION_CREATED); diff --git a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java index b94e7c7e854..d7bc9a7e0db 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java +++ b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java @@ -64,7 +64,7 @@ public final class MockIndexEventListener { /** * For tests to pass in to fail on listener invocation */ - public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, false, SettingsProperty.IndexScope); + public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, SettingsProperty.IndexScope); public void onModule(SettingsModule module) { module.registerSetting(INDEX_FAIL); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java index cde26a5b55f..2fad1fc05e8 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java +++ b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java @@ -57,12 +57,12 @@ public final class MockEngineSupport { * slow if {@link org.apache.lucene.index.AssertingDirectoryReader} is used. */ public static final Setting WRAP_READER_RATIO = - Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, SettingsProperty.IndexScope); /** * Allows tests to prevent an engine from being flushed on close ie. to test translog recovery... */ public static final Setting DISABLE_FLUSH_ON_CLOSE = - Setting.boolSetting("index.mock.disable_flush_on_close", false, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mock.disable_flush_on_close", false, SettingsProperty.IndexScope); private final AtomicBoolean closing = new AtomicBoolean(false); diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java index 6f0e6d51d10..2cb5367e642 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java +++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java @@ -63,15 +63,15 @@ import java.util.Random; public class MockFSDirectoryService extends FsDirectoryService { public static final Setting RANDOM_IO_EXCEPTION_RATE_ON_OPEN_SETTING = - Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d, 0.0d, SettingsProperty.IndexScope); public static final Setting RANDOM_IO_EXCEPTION_RATE_SETTING = - Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d, 0.0d, false, SettingsProperty.IndexScope); + Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d, 0.0d, SettingsProperty.IndexScope); public static final Setting RANDOM_PREVENT_DOUBLE_WRITE_SETTING = - Setting.boolSetting("index.store.mock.random.prevent_double_write", true, false, SettingsProperty.IndexScope);// true is default in MDW + Setting.boolSetting("index.store.mock.random.prevent_double_write", true, SettingsProperty.IndexScope);// true is default in MDW public static final Setting RANDOM_NO_DELETE_OPEN_FILE_SETTING = - Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, false, SettingsProperty.IndexScope);// true is default in MDW + Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, SettingsProperty.IndexScope);// true is default in MDW public static final Setting CRASH_INDEX_SETTING = - Setting.boolSetting("index.store.mock.random.crash_index", true, false, SettingsProperty.IndexScope);// true is default in MDW + Setting.boolSetting("index.store.mock.random.crash_index", true, SettingsProperty.IndexScope);// true is default in MDW private final FsDirectoryService delegateService; private final Random random; diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java index 8d1a2beed89..3d535d67799 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java +++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java @@ -46,7 +46,7 @@ import java.util.Map; public class MockFSIndexStore extends IndexStore { public static final Setting INDEX_CHECK_INDEX_ON_CLOSE_SETTING = - Setting.boolSetting("index.store.mock.check_index_on_close", true, false, SettingsProperty.IndexScope); + Setting.boolSetting("index.store.mock.check_index_on_close", true, SettingsProperty.IndexScope); public static class TestPlugin extends Plugin { @Override diff --git a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java index bdafa98b6ac..6009929e38e 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java +++ b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java @@ -35,7 +35,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class MockTaskManager extends TaskManager { public static final Setting USE_MOCK_TASK_MANAGER_SETTING = - Setting.boolSetting("tests.mock.taskmanager.enabled", false, false, SettingsProperty.ClusterScope); + Setting.boolSetting("tests.mock.taskmanager.enabled", false, SettingsProperty.ClusterScope); private final Collection listeners = new CopyOnWriteArrayList<>(); diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java index 49a89977e95..88cdd325448 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java +++ b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java @@ -70,10 +70,10 @@ public class AssertingLocalTransport extends LocalTransport { public static final Setting ASSERTING_TRANSPORT_MIN_VERSION_KEY = new Setting<>("transport.asserting.version.min", Integer.toString(Version.CURRENT.minimumCompatibilityVersion().id), - (s) -> Version.fromId(Integer.parseInt(s)), false, SettingsProperty.ClusterScope); + (s) -> Version.fromId(Integer.parseInt(s)), SettingsProperty.ClusterScope); public static final Setting ASSERTING_TRANSPORT_MAX_VERSION_KEY = new Setting<>("transport.asserting.version.max", Integer.toString(Version.CURRENT.id), - (s) -> Version.fromId(Integer.parseInt(s)), false, SettingsProperty.ClusterScope); + (s) -> Version.fromId(Integer.parseInt(s)), SettingsProperty.ClusterScope); private final Random random; private final Version minVersion; private final Version maxVersion; From 7a7f112e890aa55a3b5e180a762ce47cfb7f14da Mon Sep 17 00:00:00 2001 From: David Pilato Date: Sun, 28 Feb 2016 11:21:20 +0100 Subject: [PATCH 05/49] Check mutually exclusive scopes We want to make sure that a developer does not put more than one scope on a given setting. --- .../common/settings/Setting.java | 12 +++++ .../common/settings/SettingTests.java | 52 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index ce20c521932..1469d4679cb 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -125,6 +125,18 @@ public class Setting extends ToXContentToBytes { } else { this.properties = EnumSet.copyOf(Arrays.asList(properties)); } + // We validate scope settings. They are mutually exclusive + int numScopes = 0; + for (SettingsProperty property : properties) { + if (property == SettingsProperty.ClusterScope || + property == SettingsProperty.IndexScope || + property == SettingsProperty.NodeScope) { + numScopes++; + } + } + if (numScopes > 1) { + throw new IllegalArgumentException("More than one scope has been added to the setting [" + key + "]"); + } } /** diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index b916783b316..f2c76931729 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; public class SettingTests extends ESTestCase { @@ -400,4 +401,55 @@ public class SettingTests extends ESTestCase { assertEquals(5, integerSetting.get(Settings.builder().put("foo.bar", 5).build()).intValue()); assertEquals(1, integerSetting.get(Settings.EMPTY).intValue()); } + + /** + * Only one single scope can be added to any setting + */ + public void testMutuallyExclusiveScopes() { + // Those should pass + Setting setting = Setting.simpleString("foo.bar", SettingsProperty.ClusterScope); + assertThat(setting.hasClusterScope(), is(true)); + assertThat(setting.hasNodeScope(), is(false)); + assertThat(setting.hasIndexScope(), is(false)); + setting = Setting.simpleString("foo.bar", SettingsProperty.NodeScope); + assertThat(setting.hasNodeScope(), is(true)); + assertThat(setting.hasIndexScope(), is(false)); + assertThat(setting.hasClusterScope(), is(false)); + setting = Setting.simpleString("foo.bar", SettingsProperty.IndexScope); + assertThat(setting.hasIndexScope(), is(true)); + assertThat(setting.hasNodeScope(), is(false)); + assertThat(setting.hasClusterScope(), is(false)); + + // We test the default scope + setting = Setting.simpleString("foo.bar"); + assertThat(setting.hasNodeScope(), is(true)); + assertThat(setting.hasIndexScope(), is(false)); + assertThat(setting.hasClusterScope(), is(false)); + + // Those should fail + try { + Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.ClusterScope); + fail("Multiple scopes should fail"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); + } + try { + Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.NodeScope); + fail("Multiple scopes should fail"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); + } + try { + Setting.simpleString("foo.bar", SettingsProperty.ClusterScope, SettingsProperty.NodeScope); + fail("Multiple scopes should fail"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); + } + try { + Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.ClusterScope, SettingsProperty.NodeScope); + fail("Multiple scopes should fail"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); + } + } } From cadd8664bbf98f8fd00df098d2f405040e61f269 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Mon, 29 Feb 2016 10:00:05 +0100 Subject: [PATCH 06/49] Fix regression in test --- .../java/org/elasticsearch/common/settings/SettingTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index f2c76931729..cd6496d8b2f 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -40,7 +40,7 @@ public class SettingTests extends ESTestCase { Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); assertFalse(booleanSetting.get(Settings.EMPTY)); assertFalse(booleanSetting.get(Settings.builder().put("foo.bar", false).build())); - assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", SettingsProperty.Dynamic).build())); + assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", true).build())); } public void testByteSize() { From 8cd919c6876f3b380137eb97bc7b37f0058e9c2f Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 29 Feb 2016 19:52:42 -0800 Subject: [PATCH 07/49] Added jopt simple option parser and switched plugin cli to use it --- core/build.gradle | 3 +- .../bootstrap/BootstrapCLIParser.java | 11 +- .../java/org/elasticsearch/cli/Command.java | 111 ++++++++++++++++++ .../java/org/elasticsearch/cli/ExitCodes.java | 42 +++++++ .../org/elasticsearch/cli/MultiCommand.java | 73 ++++++++++++ .../org/elasticsearch/cli/TestCommand.java | 41 +++++++ .../{common => }/cli/UserError.java | 10 +- .../org/elasticsearch/common/cli/CliTool.java | 6 +- .../elasticsearch/common/cli/Terminal.java | 21 +++- .../plugins/InstallPluginCommand.java | 73 +++++++----- .../plugins/ListPluginsCommand.java | 17 ++- .../org/elasticsearch/plugins/PluginCli.java | 103 ++-------------- .../plugins/RemovePluginCommand.java | 51 +++++--- .../elasticsearch/plugins/PluginCliTests.java | 2 + .../bootstrap/BootstrapCliParserTests.java | 3 +- .../common/cli/CliToolTests.java | 4 +- .../plugins/InstallPluginCommandTests.java | 7 +- .../plugins/ListPluginsCommandTests.java | 6 +- .../plugins/RemovePluginCommandTests.java | 6 +- .../common/cli/CliToolTestCase.java | 6 + 20 files changed, 426 insertions(+), 170 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/cli/Command.java create mode 100644 core/src/main/java/org/elasticsearch/cli/ExitCodes.java create mode 100644 core/src/main/java/org/elasticsearch/cli/MultiCommand.java create mode 100644 core/src/main/java/org/elasticsearch/cli/TestCommand.java rename core/src/main/java/org/elasticsearch/{common => }/cli/UserError.java (79%) diff --git a/core/build.gradle b/core/build.gradle index e1511a9cdd1..f79c2a7623b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -48,7 +48,8 @@ dependencies { compile 'org.elasticsearch:securesm:1.0' // utilities - compile 'commons-cli:commons-cli:1.3.1' + compile 'commons-cli:commons-cli:1.3.1' // nocommit: remove the old! + compile 'net.sf.jopt-simple:jopt-simple:4.9' compile 'com.carrotsearch:hppc:0.7.1' // time handling, remove with java 8 time diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java index ca67fc91132..ec11a773ccc 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java @@ -27,7 +27,7 @@ import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolConfig; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.cli.UserError; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.monitor.jvm.JvmInfo; @@ -37,7 +37,6 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; -import java.util.Set; import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd; import static org.elasticsearch.common.cli.CliToolConfig.Builder.optionBuilder; @@ -138,11 +137,11 @@ final class BootstrapCLIParser extends CliTool { String arg = iterator.next(); if (!arg.startsWith("--")) { if (arg.startsWith("-D") || arg.startsWith("-d") || arg.startsWith("-p")) { - throw new UserError(ExitStatus.USAGE, + throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "] starting with \"-D\", \"-d\" or \"-p\" must be before any parameters starting with --" ); } else { - throw new UserError(ExitStatus.USAGE, "Parameter [" + arg + "]does not start with --"); + throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "]does not start with --"); } } // if there is no = sign, we have to get the next argu @@ -156,11 +155,11 @@ final class BootstrapCLIParser extends CliTool { if (iterator.hasNext()) { String value = iterator.next(); if (value.startsWith("--")) { - throw new UserError(ExitStatus.USAGE, "Parameter [" + arg + "] needs value"); + throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "] needs value"); } properties.put("es." + arg, value); } else { - throw new UserError(ExitStatus.USAGE, "Parameter [" + arg + "] needs value"); + throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "] needs value"); } } } diff --git a/core/src/main/java/org/elasticsearch/cli/Command.java b/core/src/main/java/org/elasticsearch/cli/Command.java new file mode 100644 index 00000000000..bc44a8eb635 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/cli/Command.java @@ -0,0 +1,111 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.cli; + +import java.io.IOException; +import java.util.Arrays; + +import joptsimple.OptionException; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import org.elasticsearch.common.SuppressForbidden; +import org.elasticsearch.common.cli.Terminal; + +/** + * An action to execute within a cli. + */ +public abstract class Command { + + /** A description of the command, used in the help output. */ + protected final String description; + + /** The option parser for this command. */ + protected final OptionParser parser = new OptionParser(); + + private final OptionSpec helpOption = parser.acceptsAll(Arrays.asList("h", "help"), "show help").forHelp(); + private final OptionSpec silentOption = parser.acceptsAll(Arrays.asList("s", "silent"), "show minimal output"); + private final OptionSpec verboseOption = parser.acceptsAll(Arrays.asList("v", "verbose"), "show verbose output"); + + public Command(String description) { + this.description = description; + } + + /** Parses options for this command from args and executes it. */ + public final int main(String[] args, Terminal terminal) throws Exception { + + final OptionSet options; + try { + options = parser.parse(args); + } catch (OptionException e) { + printHelp(terminal); + terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage()); + return ExitCodes.USAGE; + } + + if (options.has(helpOption)) { + printHelp(terminal); + return ExitCodes.OK; + } + + if (options.has(silentOption)) { + if (options.has(verboseOption)) { + // mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it + printHelp(terminal); + terminal.println(Terminal.Verbosity.SILENT, "ERROR: Cannot specify -s and -v together"); + return ExitCodes.USAGE; + } + terminal.setVerbosity(Terminal.Verbosity.SILENT); + } else if (options.has(verboseOption)) { + terminal.setVerbosity(Terminal.Verbosity.VERBOSE); + } else { + terminal.setVerbosity(Terminal.Verbosity.NORMAL); + } + + try { + return execute(terminal, options); + } catch (UserError e) { + terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage()); + return e.exitCode; + } + } + + /** Prints a help message for the command to the terminal. */ + private void printHelp(Terminal terminal) throws IOException { + terminal.println(description); + terminal.println(""); + printAdditionalHelp(terminal); + parser.printHelpOn(terminal.getWriter()); + } + + /** Prints additional help information, specific to the command */ + protected void printAdditionalHelp(Terminal terminal) {} + + @SuppressForbidden(reason = "Allowed to exit explicitly from #main()") + protected static void exit(int status) { + System.exit(status); + } + + /** + * Executes this command. + * + * Any runtime user errors (like an input file that does not exist), should throw a {@link UserError}. */ + protected abstract int execute(Terminal terminal, OptionSet options) throws Exception; +} diff --git a/core/src/main/java/org/elasticsearch/cli/ExitCodes.java b/core/src/main/java/org/elasticsearch/cli/ExitCodes.java new file mode 100644 index 00000000000..d08deb8b1ad --- /dev/null +++ b/core/src/main/java/org/elasticsearch/cli/ExitCodes.java @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.cli; + +/** + * POSIX exit codes. + */ +public class ExitCodes { + public static final int OK = 0; + public static final int USAGE = 64; /* command line usage error */ + public static final int DATA_ERROR = 65; /* data format error */ + public static final int NO_INPUT = 66; /* cannot open input */ + public static final int NO_USER = 67; /* addressee unknown */ + public static final int NO_HOST = 68; /* host name unknown */ + public static final int UNAVAILABLE = 69; /* service unavailable */ + public static final int CODE_ERROR = 70; /* internal software error */ + public static final int CANT_CREATE = 73; /* can't create (user) output file */ + public static final int IO_ERROR = 74; /* input/output error */ + public static final int TEMP_FAILURE = 75; /* temp failure; user is invited to retry */ + public static final int PROTOCOL = 76; /* remote error in protocol */ + public static final int NOPERM = 77; /* permission denied */ + public static final int CONFIG = 78; /* configuration error */ + + private ExitCodes() { /* no instance, just constants */ } +} diff --git a/core/src/main/java/org/elasticsearch/cli/MultiCommand.java b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java new file mode 100644 index 00000000000..94c403d57d0 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.cli; + +import java.io.IOException; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +import joptsimple.NonOptionArgumentSpec; +import joptsimple.OptionSet; +import org.elasticsearch.common.cli.Terminal; + +/** + * A cli tool which is made up of multiple subcommands. + */ +public class MultiCommand extends Command { + + protected final Map subcommands = new LinkedHashMap<>(); + + private final NonOptionArgumentSpec arguments = parser.nonOptions("command"); + + public MultiCommand(String description) { + super(description); + parser.posixlyCorrect(true); + } + + @Override + protected void printAdditionalHelp(Terminal terminal) { + if (subcommands.isEmpty()) { + throw new IllegalStateException("No subcommands configured"); + } + terminal.println("Commands"); + terminal.println("--------"); + for (Map.Entry subcommand : subcommands.entrySet()) { + terminal.println(subcommand.getKey() + " - " + subcommand.getValue().description); + } + terminal.println(""); + } + + @Override + protected int execute(Terminal terminal, OptionSet options) throws Exception { + if (subcommands.isEmpty()) { + throw new IllegalStateException("No subcommands configured"); + } + String[] args = arguments.values(options).toArray(new String[0]); + if (args.length == 0) { + throw new UserError(ExitCodes.USAGE, "Missing command"); + } + Command subcommand = subcommands.get(args[0]); + if (subcommand == null) { + throw new UserError(ExitCodes.USAGE, "Unknown command [" + args[0] + "]"); + } + return subcommand.main(Arrays.copyOfRange(args, 1, args.length), terminal); + } +} diff --git a/core/src/main/java/org/elasticsearch/cli/TestCommand.java b/core/src/main/java/org/elasticsearch/cli/TestCommand.java new file mode 100644 index 00000000000..fe3fa5c6b8c --- /dev/null +++ b/core/src/main/java/org/elasticsearch/cli/TestCommand.java @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.cli; + +import joptsimple.OptionSet; +import org.elasticsearch.common.cli.Terminal; + +public class TestCommand extends Command { + + public static void main(String[] args) throws Exception { + exit(new TestCommand().main(args, Terminal.DEFAULT)); + } + + public TestCommand() { + super("some test cli"); + parser.accepts("foo", "some option"); + } + + @Override + protected int execute(Terminal terminal, OptionSet options) throws Exception { + terminal.println("running"); + return ExitCodes.OK; + } +} diff --git a/core/src/main/java/org/elasticsearch/common/cli/UserError.java b/core/src/main/java/org/elasticsearch/cli/UserError.java similarity index 79% rename from core/src/main/java/org/elasticsearch/common/cli/UserError.java rename to core/src/main/java/org/elasticsearch/cli/UserError.java index ad709830885..2a4f2bf1233 100644 --- a/core/src/main/java/org/elasticsearch/common/cli/UserError.java +++ b/core/src/main/java/org/elasticsearch/cli/UserError.java @@ -17,19 +17,19 @@ * under the License. */ -package org.elasticsearch.common.cli; +package org.elasticsearch.cli; /** - * An exception representing a user fixable problem in {@link CliTool} usage. + * An exception representing a user fixable problem in {@link Command} usage. */ public class UserError extends Exception { /** The exist status the cli should use when catching this user error. */ - public final CliTool.ExitStatus exitStatus; + public final int exitCode; /** Constructs a UserError with an exit status and message to show the user. */ - public UserError(CliTool.ExitStatus exitStatus, String msg) { + public UserError(int exitCode, String msg) { super(msg); - this.exitStatus = exitStatus; + this.exitCode = exitCode; } } diff --git a/core/src/main/java/org/elasticsearch/common/cli/CliTool.java b/core/src/main/java/org/elasticsearch/common/cli/CliTool.java index 2ea01f45068..ba2007813d5 100644 --- a/core/src/main/java/org/elasticsearch/common/cli/CliTool.java +++ b/core/src/main/java/org/elasticsearch/common/cli/CliTool.java @@ -26,6 +26,7 @@ import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.MissingArgumentException; import org.apache.commons.cli.MissingOptionException; import org.apache.commons.cli.UnrecognizedOptionException; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.node.internal.InternalSettingsPreparer; @@ -143,7 +144,8 @@ public abstract class CliTool { return parse(cmd, args).execute(settings, env); } catch (UserError error) { terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + error.getMessage()); - return error.exitStatus; + return ExitStatus.USAGE; + //return error.exitCode; } } @@ -163,7 +165,7 @@ public abstract class CliTool { } catch (AlreadySelectedException|MissingArgumentException|MissingOptionException|UnrecognizedOptionException e) { // intentionally drop the stack trace here as these are really user errors, // the stack trace into cli parsing lib is not important - throw new UserError(ExitStatus.USAGE, e.toString()); + throw new UserError(ExitStatus.USAGE.status(), e.toString()); } if (cli.hasOption("v")) { diff --git a/core/src/main/java/org/elasticsearch/common/cli/Terminal.java b/core/src/main/java/org/elasticsearch/common/cli/Terminal.java index 8d4a8036bdf..27dd2f7b87f 100644 --- a/core/src/main/java/org/elasticsearch/common/cli/Terminal.java +++ b/core/src/main/java/org/elasticsearch/common/cli/Terminal.java @@ -23,12 +23,14 @@ import java.io.BufferedReader; import java.io.Console; import java.io.IOException; import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Writer; import java.nio.charset.Charset; import org.elasticsearch.common.SuppressForbidden; /** - * A Terminal wraps access to reading input and writing output for a {@link CliTool}. + * A Terminal wraps access to reading input and writing output for a cli. * * The available methods are similar to those of {@link Console}, with the ability * to read either normal text or a password, and the ability to print a line @@ -53,7 +55,7 @@ public abstract class Terminal { private Verbosity verbosity = Verbosity.NORMAL; /** Sets the verbosity of the terminal. */ - void setVerbosity(Verbosity verbosity) { + public void setVerbosity(Verbosity verbosity) { this.verbosity = verbosity; } @@ -63,6 +65,9 @@ public abstract class Terminal { /** Reads password text from the terminal input. See {@link Console#readPassword()}}. */ public abstract char[] readSecret(String prompt); + /** Returns a Writer which can be used to write to the terminal directly. */ + public abstract PrintWriter getWriter(); + /** Print a message directly to the terminal. */ protected abstract void doPrint(String msg); @@ -86,6 +91,11 @@ public abstract class Terminal { return console != null; } + @Override + public PrintWriter getWriter() { + return console.writer(); + } + @Override public void doPrint(String msg) { console.printf("%s", msg); @@ -105,6 +115,8 @@ public abstract class Terminal { private static class SystemTerminal extends Terminal { + private static final PrintWriter writer = new PrintWriter(System.out); + @Override @SuppressForbidden(reason = "System#out") public void doPrint(String msg) { @@ -112,6 +124,11 @@ public abstract class Terminal { System.out.flush(); } + @Override + public PrintWriter getWriter() { + return writer; + } + @Override public String readText(String text) { doPrint(text); diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index 767f6d42179..977d89a3418 100644 --- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java @@ -19,16 +19,19 @@ package org.elasticsearch.plugins; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; import org.apache.lucene.util.IOUtils; import org.elasticsearch.Build; import org.elasticsearch.Version; import org.elasticsearch.bootstrap.JarHell; +import org.elasticsearch.cli.Command; +import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.cli.UserError; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.hash.MessageDigests; import org.elasticsearch.common.io.FileSystemUtils; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import java.io.BufferedReader; @@ -88,7 +91,7 @@ import static org.elasticsearch.common.util.set.Sets.newHashSet; * elasticsearch config directory, using the name of the plugin. If any files to be installed * already exist, they will be skipped. */ -class InstallPluginCommand extends CliTool.Command { +class InstallPluginCommand extends Command { private static final String PROPERTY_SUPPORT_STAGING_URLS = "es.plugins.staging"; @@ -119,17 +122,33 @@ class InstallPluginCommand extends CliTool.Command { "repository-s3", "store-smb")); - private final String pluginId; - private final boolean batch; + private final Environment env; + private final OptionSpec batchOption; + private final OptionSpec arguments; - InstallPluginCommand(Terminal terminal, String pluginId, boolean batch) { - super(terminal); - this.pluginId = pluginId; - this.batch = batch; + InstallPluginCommand(Environment env) { + super("Install a plugin"); + this.env = env; + this.batchOption = parser.acceptsAll(Arrays.asList("b", "batch"), + "Enable batch mode explicitly, automatic confirmation of security permission"); + this.arguments = parser.nonOptions("plugin id"); } @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { + protected int execute(Terminal terminal, OptionSet options) throws Exception { + // TODO: in jopt-simple 5.0 we can enforce a min/max number of positional args + List args = arguments.values(options); + if (args.size() != 1) { + throw new UserError(ExitCodes.USAGE, "Must supply a single plugin id argument"); + } + String pluginId = args.get(0); + boolean isBatch = options.has(batchOption) || System.console() == null; + execute(terminal, pluginId, isBatch); + return ExitCodes.OK; + } + + // pkg private for testing + void execute(Terminal terminal, String pluginId, boolean isBatch) throws Exception { // TODO: remove this leniency!! is it needed anymore? if (Files.exists(env.pluginsFile()) == false) { @@ -137,15 +156,13 @@ class InstallPluginCommand extends CliTool.Command { Files.createDirectory(env.pluginsFile()); } - Path pluginZip = download(pluginId, env.tmpFile()); + Path pluginZip = download(terminal, pluginId, env.tmpFile()); Path extractedZip = unzip(pluginZip, env.pluginsFile()); - install(extractedZip, env); - - return CliTool.ExitStatus.OK; + install(terminal, isBatch, extractedZip); } /** Downloads the plugin and returns the file it was downloaded to. */ - private Path download(String pluginId, Path tmpDir) throws Exception { + private Path download(Terminal terminal, String pluginId, Path tmpDir) throws Exception { if (OFFICIAL_PLUGINS.contains(pluginId)) { final String version = Version.CURRENT.toString(); final String url; @@ -195,14 +212,14 @@ class InstallPluginCommand extends CliTool.Command { BufferedReader checksumReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); expectedChecksum = checksumReader.readLine(); if (checksumReader.readLine() != null) { - throw new UserError(CliTool.ExitStatus.IO_ERROR, "Invalid checksum file at " + checksumUrl); + throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "Invalid checksum file at " + checksumUrl); } } byte[] zipbytes = Files.readAllBytes(zip); String gotChecksum = MessageDigests.toHexString(MessageDigests.sha1().digest(zipbytes)); if (expectedChecksum.equals(gotChecksum) == false) { - throw new UserError(CliTool.ExitStatus.IO_ERROR, "SHA1 mismatch, expected " + expectedChecksum + " but got " + gotChecksum); + throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "SHA1 mismatch, expected " + expectedChecksum + " but got " + gotChecksum); } return zip; @@ -244,13 +261,13 @@ class InstallPluginCommand extends CliTool.Command { Files.delete(zip); if (hasEsDir == false) { IOUtils.rm(target); - throw new UserError(CliTool.ExitStatus.DATA_ERROR, "`elasticsearch` directory is missing in the plugin zip"); + throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "`elasticsearch` directory is missing in the plugin zip"); } return target; } /** Load information about the plugin, and verify it can be installed with no errors. */ - private PluginInfo verify(Path pluginRoot, Environment env) throws Exception { + private PluginInfo verify(Terminal terminal, Path pluginRoot, boolean isBatch) throws Exception { // read and validate the plugin descriptor PluginInfo info = PluginInfo.readFromProperties(pluginRoot); terminal.println(VERBOSE, info.toString()); @@ -258,7 +275,7 @@ class InstallPluginCommand extends CliTool.Command { // don't let luser install plugin as a module... // they might be unavoidably in maven central and are packaged up the same way) if (MODULES.contains(info.getName())) { - throw new UserError(CliTool.ExitStatus.USAGE, "plugin '" + info.getName() + "' cannot be installed like this, it is a system module"); + throw new UserError(CliTool.ExitStatus.USAGE.status(), "plugin '" + info.getName() + "' cannot be installed like this, it is a system module"); } // check for jar hell before any copying @@ -268,7 +285,7 @@ class InstallPluginCommand extends CliTool.Command { // if it exists, confirm or warn the user Path policy = pluginRoot.resolve(PluginInfo.ES_PLUGIN_POLICY); if (Files.exists(policy)) { - PluginSecurity.readPolicy(policy, terminal, env, batch); + PluginSecurity.readPolicy(policy, terminal, env, isBatch); } return info; @@ -305,16 +322,16 @@ class InstallPluginCommand extends CliTool.Command { * Installs the plugin from {@code tmpRoot} into the plugins dir. * If the plugin has a bin dir and/or a config dir, those are copied. */ - private void install(Path tmpRoot, Environment env) throws Exception { + private void install(Terminal terminal, boolean isBatch, Path tmpRoot) throws Exception { List deleteOnFailure = new ArrayList<>(); deleteOnFailure.add(tmpRoot); try { - PluginInfo info = verify(tmpRoot, env); + PluginInfo info = verify(terminal, tmpRoot, isBatch); final Path destination = env.pluginsFile().resolve(info.getName()); if (Files.exists(destination)) { - throw new UserError(CliTool.ExitStatus.USAGE, "plugin directory " + destination.toAbsolutePath() + " already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command"); + throw new UserError(CliTool.ExitStatus.USAGE.status(), "plugin directory " + destination.toAbsolutePath() + " already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command"); } Path tmpBinDir = tmpRoot.resolve("bin"); @@ -347,7 +364,7 @@ class InstallPluginCommand extends CliTool.Command { /** Copies the files from {@code tmpBinDir} into {@code destBinDir}, along with permissions from dest dirs parent. */ private void installBin(PluginInfo info, Path tmpBinDir, Path destBinDir) throws Exception { if (Files.isDirectory(tmpBinDir) == false) { - throw new UserError(CliTool.ExitStatus.IO_ERROR, "bin in plugin " + info.getName() + " is not a directory"); + throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "bin in plugin " + info.getName() + " is not a directory"); } Files.createDirectory(destBinDir); @@ -365,7 +382,7 @@ class InstallPluginCommand extends CliTool.Command { try (DirectoryStream stream = Files.newDirectoryStream(tmpBinDir)) { for (Path srcFile : stream) { if (Files.isDirectory(srcFile)) { - throw new UserError(CliTool.ExitStatus.DATA_ERROR, "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName()); + throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName()); } Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile)); @@ -386,7 +403,7 @@ class InstallPluginCommand extends CliTool.Command { */ private void installConfig(PluginInfo info, Path tmpConfigDir, Path destConfigDir) throws Exception { if (Files.isDirectory(tmpConfigDir) == false) { - throw new UserError(CliTool.ExitStatus.IO_ERROR, "config in plugin " + info.getName() + " is not a directory"); + throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "config in plugin " + info.getName() + " is not a directory"); } // create the plugin's config dir "if necessary" @@ -395,7 +412,7 @@ class InstallPluginCommand extends CliTool.Command { try (DirectoryStream stream = Files.newDirectoryStream(tmpConfigDir)) { for (Path srcFile : stream) { if (Files.isDirectory(srcFile)) { - throw new UserError(CliTool.ExitStatus.DATA_ERROR, "Directories not allowed in config dir for plugin " + info.getName()); + throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "Directories not allowed in config dir for plugin " + info.getName()); } Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile)); diff --git a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java index 6abed4e6bc2..142a18cbde5 100644 --- a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java +++ b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java @@ -24,22 +24,27 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import joptsimple.OptionSet; +import org.elasticsearch.cli.Command; +import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; /** * A command for the plugin cli to list plugins installed in elasticsearch. */ -class ListPluginsCommand extends CliTool.Command { +class ListPluginsCommand extends Command { - ListPluginsCommand(Terminal terminal) { - super(terminal); + private final Environment env; + + ListPluginsCommand(Environment env) { + super("Lists installed elasticsearch plugins"); + this.env = env; } @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { + public int execute(Terminal terminal, OptionSet options) throws Exception { if (Files.exists(env.pluginsFile()) == false) { throw new IOException("Plugins directory missing: " + env.pluginsFile()); } @@ -51,6 +56,6 @@ class ListPluginsCommand extends CliTool.Command { } } - return CliTool.ExitStatus.OK; + return ExitCodes.OK; } } diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginCli.java b/core/src/main/java/org/elasticsearch/plugins/PluginCli.java index 30a36501a61..9f2e432a438 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginCli.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginCli.java @@ -19,106 +19,29 @@ package org.elasticsearch.plugins; -import org.apache.commons.cli.CommandLine; -import org.elasticsearch.common.SuppressForbidden; -import org.elasticsearch.common.cli.CliTool; -import org.elasticsearch.common.cli.CliToolConfig; +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.varia.NullAppender; +import org.elasticsearch.cli.MultiCommand; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.logging.log4j.LogConfigurator; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.node.internal.InternalSettingsPreparer; -import java.util.Locale; - -import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd; -import static org.elasticsearch.common.cli.CliToolConfig.Builder.option; - /** * A cli tool for adding, removing and listing plugins for elasticsearch. */ -public class PluginCli extends CliTool { +public class PluginCli extends MultiCommand { - // commands - private static final String LIST_CMD_NAME = "list"; - private static final String INSTALL_CMD_NAME = "install"; - private static final String REMOVE_CMD_NAME = "remove"; - - // usage config - private static final CliToolConfig.Cmd LIST_CMD = cmd(LIST_CMD_NAME, ListPluginsCommand.class).build(); - private static final CliToolConfig.Cmd INSTALL_CMD = cmd(INSTALL_CMD_NAME, InstallPluginCommand.class) - .options(option("b", "batch").required(false)) - .build(); - private static final CliToolConfig.Cmd REMOVE_CMD = cmd(REMOVE_CMD_NAME, RemovePluginCommand.class).build(); - - static final CliToolConfig CONFIG = CliToolConfig.config("plugin", PluginCli.class) - .cmds(LIST_CMD, INSTALL_CMD, REMOVE_CMD) - .build(); + public PluginCli(Environment env) { + super("A tool for managing installed elasticsearch plugins"); + subcommands.put("list", new ListPluginsCommand(env)); + subcommands.put("install", new InstallPluginCommand(env)); + subcommands.put("remove", new RemovePluginCommand(env)); + } public static void main(String[] args) throws Exception { - // initialize default for es.logger.level because we will not read the logging.yml - String loggerLevel = System.getProperty("es.logger.level", "INFO"); - // Set the appender for all potential log files to terminal so that other components that use the logger print out the - // same terminal. - // The reason for this is that the plugin cli cannot be configured with a file appender because when the plugin command is - // executed there is no way of knowing where the logfiles should be placed. For example, if elasticsearch - // is run as service then the logs should be at /var/log/elasticsearch but when started from the tar they should be at es.home/logs. - // Therefore we print to Terminal. - Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.builder() - .put("appender.terminal.type", "terminal") - .put("rootLogger", "${es.logger.level}, terminal") - .put("es.logger.level", loggerLevel) - .build(), Terminal.DEFAULT); - // configure but do not read the logging conf file - LogConfigurator.configure(env.settings(), false); - int status = new PluginCli(Terminal.DEFAULT).execute(args).status(); - exit(status); - } - - @SuppressForbidden(reason = "Allowed to exit explicitly from #main()") - private static void exit(int status) { - System.exit(status); - } - - PluginCli(Terminal terminal) { - super(CONFIG, terminal); - } - - @Override - protected Command parse(String cmdName, CommandLine cli) throws Exception { - switch (cmdName.toLowerCase(Locale.ROOT)) { - case LIST_CMD_NAME: - return new ListPluginsCommand(terminal); - case INSTALL_CMD_NAME: - return parseInstallPluginCommand(cli); - case REMOVE_CMD_NAME: - return parseRemovePluginCommand(cli); - default: - assert false : "can't get here as cmd name is validated before this method is called"; - return exitCmd(ExitStatus.USAGE); - } - } - - private Command parseInstallPluginCommand(CommandLine cli) { - String[] args = cli.getArgs(); - if (args.length != 1) { - return exitCmd(ExitStatus.USAGE, terminal, "Must supply a single plugin id argument"); - } - - boolean batch = System.console() == null; - if (cli.hasOption("b")) { - batch = true; - } - - return new InstallPluginCommand(terminal, args[0], batch); - } - - private Command parseRemovePluginCommand(CommandLine cli) { - String[] args = cli.getArgs(); - if (args.length != 1) { - return exitCmd(ExitStatus.USAGE, terminal, "Must supply a single plugin name argument"); - } - - return new RemovePluginCommand(terminal, args[0]); + BasicConfigurator.configure(new NullAppender()); + Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.EMPTY, Terminal.DEFAULT); + exit(new PluginCli(env).main(args, Terminal.DEFAULT)); } } diff --git a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java index 8ce1056bbfd..10a73a0fc9a 100644 --- a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java +++ b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java @@ -19,40 +19,57 @@ package org.elasticsearch.plugins; -import org.apache.lucene.util.IOUtils; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.cli.CliTool; -import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.cli.UserError; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; - import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.List; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import org.apache.lucene.util.IOUtils; +import org.elasticsearch.cli.Command; +import org.elasticsearch.cli.ExitCodes; +import org.elasticsearch.cli.UserError; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.cli.CliTool; +import org.elasticsearch.common.cli.Terminal; +import org.elasticsearch.env.Environment; + import static org.elasticsearch.common.cli.Terminal.Verbosity.VERBOSE; /** * A command for the plugin cli to remove a plugin from elasticsearch. */ -class RemovePluginCommand extends CliTool.Command { - private final String pluginName; +class RemovePluginCommand extends Command { - public RemovePluginCommand(Terminal terminal, String pluginName) { - super(terminal); - this.pluginName = pluginName; + private final Environment env; + private final OptionSpec arguments; + + RemovePluginCommand(Environment env) { + super("Removes a plugin from elasticsearch"); + this.env = env; + this.arguments = parser.nonOptions("plugin name"); } @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { + public int execute(Terminal terminal, OptionSet options) throws Exception { + // TODO: in jopt-simple 5.0 we can enforce a min/max number of positional args + List args = arguments.values(options); + if (args.size() != 1) { + throw new UserError(ExitCodes.USAGE, "Must supply a single plugin id argument"); + } + execute(terminal, args.get(0)); + return ExitCodes.OK; + } + + // pkg private for testing + void execute(Terminal terminal, String pluginName) throws Exception { terminal.println("-> Removing " + Strings.coalesceToEmpty(pluginName) + "..."); Path pluginDir = env.pluginsFile().resolve(pluginName); if (Files.exists(pluginDir) == false) { - throw new UserError(CliTool.ExitStatus.USAGE, "Plugin " + pluginName + " not found. Run 'plugin list' to get list of installed plugins."); + throw new UserError(CliTool.ExitStatus.USAGE.status(), "Plugin " + pluginName + " not found. Run 'plugin list' to get list of installed plugins."); } List pluginPaths = new ArrayList<>(); @@ -60,7 +77,7 @@ class RemovePluginCommand extends CliTool.Command { Path pluginBinDir = env.binFile().resolve(pluginName); if (Files.exists(pluginBinDir)) { if (Files.isDirectory(pluginBinDir) == false) { - throw new UserError(CliTool.ExitStatus.IO_ERROR, "Bin dir for " + pluginName + " is not a directory"); + throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "Bin dir for " + pluginName + " is not a directory"); } pluginPaths.add(pluginBinDir); terminal.println(VERBOSE, "Removing: " + pluginBinDir); @@ -72,7 +89,5 @@ class RemovePluginCommand extends CliTool.Command { pluginPaths.add(tmpPluginDir); IOUtils.rm(pluginPaths.toArray(new Path[pluginPaths.size()])); - - return CliTool.ExitStatus.OK; } } diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java index 3a121590083..8973a9be3e2 100644 --- a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java +++ b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java @@ -28,6 +28,7 @@ import static org.hamcrest.Matchers.is; public class PluginCliTests extends CliToolTestCase { public void testHelpWorks() throws Exception { + /* CliToolTestCase.CaptureOutputTerminal terminal = new CliToolTestCase.CaptureOutputTerminal(); assertThat(new PluginCli(terminal).execute(args("--help")), is(OK_AND_EXIT)); assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin.help"); @@ -46,5 +47,6 @@ public class PluginCliTests extends CliToolTestCase { terminal.getTerminalOutput().clear(); assertThat(new PluginCli(terminal).execute(args("list -h")), is(OK_AND_EXIT)); assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin-list.help"); + */ } } diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java index 012af99cef0..c1d894710a3 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java @@ -24,7 +24,7 @@ import org.elasticsearch.Version; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.cli.CliTool.ExitStatus; import org.elasticsearch.common.cli.CliToolTestCase; -import org.elasticsearch.common.cli.UserError; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.monitor.jvm.JvmInfo; import org.hamcrest.Matcher; @@ -37,7 +37,6 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Properties; import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK; import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK_AND_EXIT; diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java index 5033914632a..70d507853fa 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java @@ -20,7 +20,7 @@ package org.elasticsearch.common.cli; import org.apache.commons.cli.CommandLine; -import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.settings.Settings; @@ -70,7 +70,7 @@ public class CliToolTests extends CliToolTestCase { @Override public CliTool.ExitStatus execute(Settings settings, Environment env) throws UserError { executed.set(true); - throw new UserError(CliTool.ExitStatus.USAGE, "bad usage"); + throw new UserError(CliTool.ExitStatus.USAGE.status(), "bad usage"); } }; SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java index 66dfa67ccbd..e51b13e969e 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java @@ -36,6 +36,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.PosixFileAttributeView; import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,10 +45,11 @@ import java.util.zip.ZipOutputStream; import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.Version; +import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.cli.UserError; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.test.ESTestCase; @@ -118,8 +120,7 @@ public class InstallPluginCommandTests extends ESTestCase { static CliToolTestCase.CaptureOutputTerminal installPlugin(String pluginUrl, Environment env) throws Exception { CliToolTestCase.CaptureOutputTerminal terminal = new CliToolTestCase.CaptureOutputTerminal(Terminal.Verbosity.NORMAL); - CliTool.ExitStatus status = new InstallPluginCommand(terminal, pluginUrl, true).execute(env.settings(), env); - assertEquals(CliTool.ExitStatus.OK, status); + new InstallPluginCommand(env).execute(terminal, pluginUrl, true); return terminal; } diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java index c68e207c0c3..7ffdd8545df 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.List; import org.apache.lucene.util.LuceneTestCase; +import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.cli.Terminal; @@ -47,8 +48,9 @@ public class ListPluginsCommandTests extends ESTestCase { static CliToolTestCase.CaptureOutputTerminal listPlugins(Environment env) throws Exception { CliToolTestCase.CaptureOutputTerminal terminal = new CliToolTestCase.CaptureOutputTerminal(Terminal.Verbosity.NORMAL); - CliTool.ExitStatus status = new ListPluginsCommand(terminal).execute(env.settings(), env); - assertEquals(CliTool.ExitStatus.OK, status); + String[] args = {}; + int status = new ListPluginsCommand(env).main(args, terminal); + assertEquals(ExitCodes.OK, status); return terminal; } diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java index 10fbc3c2696..6ffe4168de1 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java @@ -25,10 +25,11 @@ import java.nio.file.Files; import java.nio.file.Path; import org.apache.lucene.util.LuceneTestCase; +import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.cli.UserError; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.test.ESTestCase; @@ -50,8 +51,7 @@ public class RemovePluginCommandTests extends ESTestCase { static CliToolTestCase.CaptureOutputTerminal removePlugin(String name, Environment env) throws Exception { CliToolTestCase.CaptureOutputTerminal terminal = new CliToolTestCase.CaptureOutputTerminal(Terminal.Verbosity.VERBOSE); - CliTool.ExitStatus status = new RemovePluginCommand(terminal, name).execute(env.settings(), env); - assertEquals(CliTool.ExitStatus.OK, status); + new RemovePluginCommand(env).execute(terminal, name); return terminal; } diff --git a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java index 6d6c176b27d..21a5e0228f6 100644 --- a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java @@ -28,6 +28,7 @@ import org.junit.After; import org.junit.Before; import java.io.IOException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -73,6 +74,11 @@ public abstract class CliToolTestCase extends ESTestCase { public char[] readSecret(String prompt) { return new char[0]; } + + @Override + public PrintWriter getWriter() { + return null; + } } /** From 354ede717b870f7413b538ed893ab1bb80128cc8 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 1 Mar 2016 11:48:52 -0800 Subject: [PATCH 08/49] Removed old help files and improved plugin cli tests --- .../plugins/InstallPluginCommand.java | 14 +- .../elasticsearch/plugins/plugin-install.help | 59 --- .../elasticsearch/plugins/plugin-list.help | 12 - .../elasticsearch/plugins/plugin-remove.help | 12 - .../org/elasticsearch/plugins/plugin.help | 24 -- .../common/cli/CliToolTests.java | 365 ------------------ .../plugins/RemovePluginCommandTests.java | 4 +- .../common/cli/CliToolTestCase.java | 11 +- 8 files changed, 18 insertions(+), 483 deletions(-) delete mode 100644 core/src/main/resources/org/elasticsearch/plugins/plugin-install.help delete mode 100644 core/src/main/resources/org/elasticsearch/plugins/plugin-list.help delete mode 100644 core/src/main/resources/org/elasticsearch/plugins/plugin-remove.help delete mode 100644 core/src/main/resources/org/elasticsearch/plugins/plugin.help delete mode 100644 qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index 977d89a3418..bbe00fddd8c 100644 --- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java @@ -51,6 +51,7 @@ import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Set; @@ -101,7 +102,7 @@ class InstallPluginCommand extends Command { "lang-groovy")); // TODO: make this a resource file generated by gradle - static final Set OFFICIAL_PLUGINS = unmodifiableSet(newHashSet( + static final Set OFFICIAL_PLUGINS = unmodifiableSet(new LinkedHashSet<>(Arrays.asList( "analysis-icu", "analysis-kuromoji", "analysis-phonetic", @@ -120,7 +121,7 @@ class InstallPluginCommand extends Command { "repository-azure", "repository-hdfs", "repository-s3", - "store-smb")); + "store-smb"))); private final Environment env; private final OptionSpec batchOption; @@ -134,6 +135,15 @@ class InstallPluginCommand extends Command { this.arguments = parser.nonOptions("plugin id"); } + @Override + protected void printAdditionalHelp(Terminal terminal) { + terminal.println("The following official plugins may be installed by name:"); + for (String plugin : OFFICIAL_PLUGINS) { + terminal.println(" " + plugin); + } + terminal.println(""); + } + @Override protected int execute(Terminal terminal, OptionSet options) throws Exception { // TODO: in jopt-simple 5.0 we can enforce a min/max number of positional args diff --git a/core/src/main/resources/org/elasticsearch/plugins/plugin-install.help b/core/src/main/resources/org/elasticsearch/plugins/plugin-install.help deleted file mode 100644 index 7037974ede3..00000000000 --- a/core/src/main/resources/org/elasticsearch/plugins/plugin-install.help +++ /dev/null @@ -1,59 +0,0 @@ -NAME - - install - Install a plugin - -SYNOPSIS - - plugin install - -DESCRIPTION - - This command installs an elasticsearch plugin. It can be used as follows: - - Officially supported or commercial plugins require just the plugin name: - - plugin install analysis-icu - plugin install x-pack - - Plugins from Maven Central require 'groupId:artifactId:version': - - plugin install org.elasticsearch:mapper-attachments:3.0.0 - - Plugins can be installed from a custom URL or file location as follows: - - plugin install http://some.domain.name//my-plugin-1.0.0.zip - plugin install file:/path/to/my-plugin-1.0.0.zip - -OFFICIAL PLUGINS - - The following plugins are officially supported and can be installed by just referring to their name - - - analysis-icu - - analysis-kuromoji - - analysis-phonetic - - analysis-smartcn - - analysis-stempel - - delete-by-query - - discovery-azure - - discovery-ec2 - - discovery-gce - - ingest-geoip - - lang-javascript - - lang-painless - - lang-python - - mapper-attachments - - mapper-murmur3 - - mapper-size - - repository-azure - - repository-hdfs - - repository-s3 - - store-smb - - -OPTIONS - - -v,--verbose Verbose output - - -h,--help Shows this message - - -b,--batch Enable batch mode explicitly, automatic confirmation of security permissions diff --git a/core/src/main/resources/org/elasticsearch/plugins/plugin-list.help b/core/src/main/resources/org/elasticsearch/plugins/plugin-list.help deleted file mode 100644 index c13949e8cb6..00000000000 --- a/core/src/main/resources/org/elasticsearch/plugins/plugin-list.help +++ /dev/null @@ -1,12 +0,0 @@ -NAME - - list - List all plugins - -SYNOPSIS - - plugin list - -DESCRIPTION - - This command lists all installed elasticsearch plugins - diff --git a/core/src/main/resources/org/elasticsearch/plugins/plugin-remove.help b/core/src/main/resources/org/elasticsearch/plugins/plugin-remove.help deleted file mode 100644 index b708adf1f69..00000000000 --- a/core/src/main/resources/org/elasticsearch/plugins/plugin-remove.help +++ /dev/null @@ -1,12 +0,0 @@ -NAME - - remove - Remove a plugin - -SYNOPSIS - - plugin remove - -DESCRIPTION - - This command removes an elasticsearch plugin - diff --git a/core/src/main/resources/org/elasticsearch/plugins/plugin.help b/core/src/main/resources/org/elasticsearch/plugins/plugin.help deleted file mode 100644 index 5cba544627a..00000000000 --- a/core/src/main/resources/org/elasticsearch/plugins/plugin.help +++ /dev/null @@ -1,24 +0,0 @@ -NAME - - plugin - Manages plugins - -SYNOPSIS - - plugin - -DESCRIPTION - - Manage plugins - -COMMANDS - - install Install a plugin - - remove Remove a plugin - - list List installed plugins - -NOTES - - [*] For usage help on specific commands please type "plugin -h" - diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java deleted file mode 100644 index 70d507853fa..00000000000 --- a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.common.cli; - -import org.apache.commons.cli.CommandLine; -import org.elasticsearch.cli.UserError; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.SuppressForbidden; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; -import org.elasticsearch.node.internal.InternalSettingsPreparer; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static java.util.Collections.unmodifiableMap; -import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK; -import static org.elasticsearch.common.cli.CliTool.ExitStatus.USAGE; -import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd; -import static org.hamcrest.Matchers.arrayContaining; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - -@SuppressForbidden(reason = "modifies system properties intentionally") -public class CliToolTests extends CliToolTestCase { - public void testOK() throws Exception { - Terminal terminal = new MockTerminal(); - final AtomicReference executed = new AtomicReference<>(false); - final NamedCommand cmd = new NamedCommand("cmd", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) { - executed.set(true); - return OK; - } - }; - SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); - CliTool.ExitStatus status = tool.execute(); - assertStatus(status, OK); - assertCommandHasBeenExecuted(executed); - } - - public void testUsageError() throws Exception { - Terminal terminal = new MockTerminal(); - final AtomicReference executed = new AtomicReference<>(false); - final NamedCommand cmd = new NamedCommand("cmd", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws UserError { - executed.set(true); - throw new UserError(CliTool.ExitStatus.USAGE.status(), "bad usage"); - } - }; - SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); - CliTool.ExitStatus status = tool.execute(); - assertStatus(status, CliTool.ExitStatus.USAGE); - assertCommandHasBeenExecuted(executed); - } - - public void testMultiCommand() throws Exception { - Terminal terminal = new MockTerminal(); - int count = randomIntBetween(2, 7); - List> executed = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - executed.add(new AtomicReference<>(false)); - } - NamedCommand[] cmds = new NamedCommand[count]; - for (int i = 0; i < count; i++) { - final int index = i; - cmds[i] = new NamedCommand("cmd" + index, terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - executed.get(index).set(true); - return OK; - } - }; - } - MultiCmdTool tool = new MultiCmdTool("tool", terminal, cmds); - int cmdIndex = randomIntBetween(0, count-1); - CliTool.ExitStatus status = tool.execute("cmd" + cmdIndex); - assertThat(status, is(OK)); - for (int i = 0; i < count; i++) { - assertThat(executed.get(i).get(), is(i == cmdIndex)); - } - } - - public void testMultiCommandUnknownCommand() throws Exception { - Terminal terminal = new MockTerminal(); - int count = randomIntBetween(2, 7); - List> executed = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - executed.add(new AtomicReference<>(false)); - } - NamedCommand[] cmds = new NamedCommand[count]; - for (int i = 0; i < count; i++) { - final int index = i; - cmds[i] = new NamedCommand("cmd" + index, terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - executed.get(index).set(true); - return OK; - } - }; - } - MultiCmdTool tool = new MultiCmdTool("tool", terminal, cmds); - CliTool.ExitStatus status = tool.execute("cmd" + count); // "cmd" + count doesn't exist - assertThat(status, is(CliTool.ExitStatus.USAGE)); - for (int i = 0; i < count; i++) { - assertThat(executed.get(i).get(), is(false)); - } - } - - public void testSingleCommandToolHelp() throws Exception { - CaptureOutputTerminal terminal = new CaptureOutputTerminal(); - final AtomicReference executed = new AtomicReference<>(false); - final NamedCommand cmd = new NamedCommand("cmd1", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - executed.set(true); - throw new IOException("io error"); - } - }; - SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); - CliTool.ExitStatus status = tool.execute(args("-h")); - assertStatus(status, CliTool.ExitStatus.OK_AND_EXIT); - assertThat(terminal.getTerminalOutput(), hasSize(3)); - assertThat(terminal.getTerminalOutput(), hasItem(containsString("cmd1 help"))); - } - - public void testMultiCommandToolHelp() throws Exception { - CaptureOutputTerminal terminal = new CaptureOutputTerminal(); - NamedCommand[] cmds = new NamedCommand[2]; - cmds[0] = new NamedCommand("cmd0", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - return OK; - } - }; - cmds[1] = new NamedCommand("cmd1", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - return OK; - } - }; - MultiCmdTool tool = new MultiCmdTool("tool", terminal, cmds); - CliTool.ExitStatus status = tool.execute(args("-h")); - assertStatus(status, CliTool.ExitStatus.OK_AND_EXIT); - assertThat(terminal.getTerminalOutput(), hasSize(3)); - assertThat(terminal.getTerminalOutput(), hasItem(containsString("tool help"))); - } - - public void testMultiCommandCmdHelp() throws Exception { - CaptureOutputTerminal terminal = new CaptureOutputTerminal(); - NamedCommand[] cmds = new NamedCommand[2]; - cmds[0] = new NamedCommand("cmd0", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - return OK; - } - }; - cmds[1] = new NamedCommand("cmd1", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - return OK; - } - }; - MultiCmdTool tool = new MultiCmdTool("tool", terminal, cmds); - CliTool.ExitStatus status = tool.execute(args("cmd1 -h")); - assertStatus(status, CliTool.ExitStatus.OK_AND_EXIT); - assertThat(terminal.getTerminalOutput(), hasSize(3)); - assertThat(terminal.getTerminalOutput(), hasItem(containsString("cmd1 help"))); - } - - public void testNonUserErrorPropagates() throws Exception { - CaptureOutputTerminal terminal = new CaptureOutputTerminal(); - NamedCommand cmd = new NamedCommand("cmd", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception { - throw new IOException("error message"); - } - }; - SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); - IOException e = expectThrows(IOException.class, () -> { - tool.execute(); - }); - assertEquals("error message", e.getMessage()); - } - - public void testMultipleLaunch() throws Exception { - Terminal terminal = new MockTerminal(); - final AtomicReference executed = new AtomicReference<>(false); - final NamedCommand cmd = new NamedCommand("cmd", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) { - executed.set(true); - return OK; - } - }; - SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd); - tool.parse("cmd", Strings.splitStringByCommaToArray("--verbose")); - tool.parse("cmd", Strings.splitStringByCommaToArray("--silent")); - tool.parse("cmd", Strings.splitStringByCommaToArray("--help")); - } - - public void testPromptForSetting() throws Exception { - final AtomicInteger counter = new AtomicInteger(); - final AtomicReference promptedSecretValue = new AtomicReference<>(null); - final AtomicReference promptedTextValue = new AtomicReference<>(null); - final Terminal terminal = new MockTerminal() { - @Override - public char[] readSecret(String text) { - counter.incrementAndGet(); - return "changeit".toCharArray(); - } - - @Override - public String readText(String text) { - counter.incrementAndGet(); - return "replaced"; - } - }; - final NamedCommand cmd = new NamedCommand("noop", terminal) { - @Override - public CliTool.ExitStatus execute(Settings settings, Environment env) { - promptedSecretValue.set(settings.get("foo.password")); - promptedTextValue.set(settings.get("replace")); - return OK; - } - }; - - System.setProperty("es.foo.password", InternalSettingsPreparer.SECRET_PROMPT_VALUE); - System.setProperty("es.replace", InternalSettingsPreparer.TEXT_PROMPT_VALUE); - try { - new SingleCmdTool("tool", terminal, cmd).execute(); - } finally { - System.clearProperty("es.foo.password"); - System.clearProperty("es.replace"); - } - - assertThat(counter.intValue(), is(2)); - assertThat(promptedSecretValue.get(), is("changeit")); - assertThat(promptedTextValue.get(), is("replaced")); - } - - public void testStopAtNonOptionParsing() throws Exception { - final CliToolConfig.Cmd lenientCommand = cmd("lenient", CliTool.Command.Exit.class).stopAtNonOption(true).build(); - final CliToolConfig.Cmd strictCommand = cmd("strict", CliTool.Command.Exit.class).stopAtNonOption(false).build(); - final CliToolConfig config = CliToolConfig.config("elasticsearch", CliTool.class).cmds(lenientCommand, strictCommand).build(); - - final CaptureOutputTerminal terminal = new CaptureOutputTerminal(); - final CliTool cliTool = new CliTool(config, terminal) { - @Override - protected Command parse(String cmdName, CommandLine cli) throws Exception { - return new NamedCommand(cmdName, terminal) { - @Override - public ExitStatus execute(Settings settings, Environment env) throws Exception { - return OK; - } - }; - } - }; - - // known parameters, no error - assertStatus(cliTool.execute(args("lenient --verbose")), OK); - assertStatus(cliTool.execute(args("lenient -v")), OK); - - // unknown parameters, no error - assertStatus(cliTool.execute(args("lenient --unknown")), OK); - assertStatus(cliTool.execute(args("lenient -u")), OK); - - // unknown parameters, error - assertStatus(cliTool.execute(args("strict --unknown")), USAGE); - assertThat(terminal.getTerminalOutput(), hasItem(containsString("Unrecognized option: --unknown"))); - - terminal.getTerminalOutput().clear(); - assertStatus(cliTool.execute(args("strict -u")), USAGE); - assertThat(terminal.getTerminalOutput(), hasItem(containsString("Unrecognized option: -u"))); - } - - private void assertStatus(CliTool.ExitStatus status, CliTool.ExitStatus expectedStatus) { - assertThat(status, is(expectedStatus)); - } - - private void assertCommandHasBeenExecuted(AtomicReference executed) { - assertThat("Expected command atomic reference counter to be set to true", executed.get(), is(Boolean.TRUE)); - } - - private static class SingleCmdTool extends CliTool { - - private final Command command; - - private SingleCmdTool(String name, Terminal terminal, NamedCommand command) { - super(CliToolConfig.config(name, SingleCmdTool.class) - .cmds(cmd(command.name, command.getClass())) - .build(), terminal); - this.command = command; - } - - @Override - protected Command parse(String cmdName, CommandLine cli) throws Exception { - return command; - } - } - - private static class MultiCmdTool extends CliTool { - - private final Map commands; - - private MultiCmdTool(String name, Terminal terminal, NamedCommand... commands) { - super(CliToolConfig.config(name, MultiCmdTool.class) - .cmds(cmds(commands)) - .build(), terminal); - Map commandByName = new HashMap<>(); - for (int i = 0; i < commands.length; i++) { - commandByName.put(commands[i].name, commands[i]); - } - this.commands = unmodifiableMap(commandByName); - } - - @Override - protected Command parse(String cmdName, CommandLine cli) throws Exception { - return commands.get(cmdName); - } - - private static CliToolConfig.Cmd[] cmds(NamedCommand... commands) { - CliToolConfig.Cmd[] cmds = new CliToolConfig.Cmd[commands.length]; - for (int i = 0; i < commands.length; i++) { - cmds[i] = cmd(commands[i].name, commands[i].getClass()).build(); - } - return cmds; - } - } - - private static abstract class NamedCommand extends CliTool.Command { - - private final String name; - - private NamedCommand(String name, Terminal terminal) { - super(terminal); - this.name = name; - } - } -} diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java index 6ffe4168de1..cedb4f5d878 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java @@ -25,11 +25,9 @@ import java.nio.file.Files; import java.nio.file.Path; import org.apache.lucene.util.LuceneTestCase; -import org.elasticsearch.cli.ExitCodes; -import org.elasticsearch.common.cli.CliTool; +import org.elasticsearch.cli.UserError; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.cli.UserError; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.test.ESTestCase; diff --git a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java index 21a5e0228f6..d96f6bd4e79 100644 --- a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java @@ -19,7 +19,11 @@ package org.elasticsearch.common.cli; -import org.elasticsearch.ExceptionsHelper; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + import org.elasticsearch.common.Strings; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.test.ESTestCase; @@ -27,11 +31,6 @@ import org.elasticsearch.test.StreamsUtils; import org.junit.After; import org.junit.Before; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; From e4d9e46508e46dba21268b5a22dc84cd50dfdb31 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Wed, 2 Mar 2016 09:49:52 +0100 Subject: [PATCH 09/49] Fix merge with master --- .../cluster/service/InternalClusterService.java | 2 +- .../common/settings/ScopedSettingsTests.java | 6 +++--- .../elasticsearch/cloud/gce/GceComputeService.java | 11 ++++++----- .../cloud/gce/GceComputeServiceImpl.java | 7 ++++--- .../discovery/gce/GceUnicastHostsProvider.java | 4 +++- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java index 29b7f6ad54e..af5c6a2f44b 100644 --- a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java +++ b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java @@ -106,7 +106,7 @@ public class InternalClusterService extends AbstractLifecycleComponent NODE_ID_SEED_SETTING = // don't use node.id.seed so it won't be seen as an attribute - Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, false, Setting.Scope.CLUSTER); + Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, SettingsProperty.ClusterScope); private final ThreadPool threadPool; private BiConsumer clusterStatePublisher; diff --git a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index d626fe961d5..84adee21b32 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -310,9 +310,9 @@ public class ScopedSettingsTests extends ESTestCase { public void testOverlappingComplexMatchSettings() { Set> settings = new LinkedHashSet<>(2); final boolean groupFirst = randomBoolean(); - final Setting groupSetting = Setting.groupSetting("foo.", false, Setting.Scope.CLUSTER); - final Setting listSetting = Setting.listSetting("foo.bar", Collections.emptyList(), Function.identity(), false, - Setting.Scope.CLUSTER); + final Setting groupSetting = Setting.groupSetting("foo.", SettingsProperty.ClusterScope); + final Setting listSetting = + Setting.listSetting("foo.bar", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); settings.add(groupFirst ? groupSetting : listSetting); settings.add(groupFirst ? listSetting : groupSetting); diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java index ce5154b3436..60af05ad6a1 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java @@ -22,6 +22,7 @@ package org.elasticsearch.cloud.gce; import com.google.api.services.compute.model.Instance; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.unit.TimeValue; import java.io.IOException; @@ -41,25 +42,25 @@ public interface GceComputeService extends LifecycleComponent /** * cloud.gce.project_id: Google project id */ - Setting PROJECT_SETTING = Setting.simpleString("cloud.gce.project_id", false, Setting.Scope.CLUSTER); + Setting PROJECT_SETTING = Setting.simpleString("cloud.gce.project_id", SettingsProperty.ClusterScope); /** * cloud.gce.zone: Google Compute Engine zones */ Setting> ZONE_SETTING = - Setting.listSetting("cloud.gce.zone", Collections.emptyList(), s -> s, false, Setting.Scope.CLUSTER); + Setting.listSetting("cloud.gce.zone", Collections.emptyList(), s -> s, SettingsProperty.ClusterScope); /** * cloud.gce.refresh_interval: How long the list of hosts is cached to prevent further requests to the AWS API. 0 disables caching. * A negative value will cause infinite caching. Defaults to 0s. */ Setting REFRESH_SETTING = - Setting.timeSetting("cloud.gce.refresh_interval", TimeValue.timeValueSeconds(0), false, Setting.Scope.CLUSTER); + Setting.timeSetting("cloud.gce.refresh_interval", TimeValue.timeValueSeconds(0), SettingsProperty.ClusterScope); /** * cloud.gce.retry: Should we retry calling GCE API in case of error? Defaults to true. */ - Setting RETRY_SETTING = Setting.boolSetting("cloud.gce.retry", true, false, Setting.Scope.CLUSTER); + Setting RETRY_SETTING = Setting.boolSetting("cloud.gce.retry", true, SettingsProperty.ClusterScope); /** * cloud.gce.max_wait: How long exponential backoff should retry before definitely failing. @@ -67,7 +68,7 @@ public interface GceComputeService extends LifecycleComponent * A negative value will retry indefinitely. Defaults to `-1s` (retry indefinitely). */ Setting MAX_WAIT_SETTING = - Setting.timeSetting("cloud.gce.max_wait", TimeValue.timeValueSeconds(-1), false, Setting.Scope.CLUSTER); + Setting.timeSetting("cloud.gce.max_wait", TimeValue.timeValueSeconds(-1), SettingsProperty.ClusterScope); /** * Return a collection of running instances within the same GCE project diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java index d9033b602d2..b0cfeb16c51 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java @@ -38,6 +38,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.gce.RetryHttpInitializerWrapper; @@ -61,11 +62,11 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent GCE_VALIDATE_CERTIFICATES = - Setting.boolSetting("cloud.gce.validate_certificates", true, false, Setting.Scope.CLUSTER); + Setting.boolSetting("cloud.gce.validate_certificates", true, SettingsProperty.ClusterScope); public static final Setting GCE_HOST = - new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), SettingsProperty.ClusterScope); public static final Setting GCE_ROOT_URL = - new Setting<>("cloud.gce.root_url", "https://www.googleapis.com", Function.identity(), false, Setting.Scope.CLUSTER); + new Setting<>("cloud.gce.root_url", "https://www.googleapis.com", Function.identity(), SettingsProperty.ClusterScope); private final String project; private final List zones; diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java index e840d3439d6..738befe9d16 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java @@ -31,6 +31,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -43,6 +44,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Function; /** * @@ -53,7 +55,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas * discovery.gce.tags: The gce discovery can filter machines to include in the cluster based on tags. */ public static final Setting> TAGS_SETTING = - Setting.listSetting("discovery.gce.tags", Collections.emptyList(), s -> s, false, Setting.Scope.CLUSTER); + Setting.listSetting("discovery.gce.tags", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); static final class Status { private static final String TERMINATED = "TERMINATED"; From c103e40e726c69fa093bb22e2574499dbce0282c Mon Sep 17 00:00:00 2001 From: David Pilato Date: Wed, 2 Mar 2016 10:06:53 +0100 Subject: [PATCH 10/49] Add support for deprecated settings This is a backport of #16845 in this branch. We now also support marking settings with `SettingsProperty.Deprecated`. If the setting is still used, it will print a `warn` to the user. --- .../common/settings/Setting.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index 1469d4679cb..af2d53743e4 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.logging.ESLogger; +import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.MemorySizeValue; @@ -81,6 +82,11 @@ public class Setting extends ToXContentToBytes { */ Dynamic, + /** + * mark this setting as deprecated + */ + Deprecated, + /** * Cluster scope. * @See IndexScope @@ -103,6 +109,7 @@ public class Setting extends ToXContentToBytes { IndexScope; } + private static final ESLogger logger = Loggers.getLogger(Setting.class); private final String key; protected final Function defaultValue; private final Function parser; @@ -215,6 +222,13 @@ public class Setting extends ToXContentToBytes { return properties.contains(SettingsProperty.NodeScope); } + /** + * Returns true if this setting is deprecated, otherwise false + */ + public boolean isDeprecated() { + return properties.contains(SettingsProperty.Deprecated); + } + /** * Returns true iff this setting is a group setting. Group settings represent a set of settings * rather than a single value. The key, see {@link #getKey()}, in contrast to non-group settings is a prefix like cluster.store. @@ -275,6 +289,12 @@ public class Setting extends ToXContentToBytes { * instead. This is useful if the value can't be parsed due to an invalid value to access the actual value. */ public String getRaw(Settings settings) { + // They're using the setting, so we need to tell them to stop + if (this.isDeprecated() && this.exists(settings)) { + // It would be convenient to show its replacement key, but replacement is often not so simple + logger.warn("[{}] setting was deprecated in Elasticsearch and it will be removed in a future release! " + + "See the breaking changes lists in the documentation for details", getKey()); + } return settings.get(key, defaultValue.apply(settings)); } @@ -678,7 +698,7 @@ public class Setting extends ToXContentToBytes { /** * This setting type allows to validate settings that have the same type and a common prefix. For instance feature.${type}=[true|false] - * can easily be added with this setting. Yet, dynamic key settings don't support updaters our of the box unless {@link #getConcreteSetting(String)} + * can easily be added with this setting. Yet, dynamic key settings don't support updaters out of the box unless {@link #getConcreteSetting(String)} * is used to pull the updater. */ public static Setting dynamicKeySetting(String key, String defaultValue, Function parser, From 3f71c1d6a5520be787fdf5cbdb2c6400346df319 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Wed, 2 Mar 2016 10:12:40 +0100 Subject: [PATCH 11/49] Replace `s -> s` by `Function.identity()` --- .../org/elasticsearch/common/network/NetworkService.java | 7 ++++--- .../org/elasticsearch/http/HttpTransportSettings.java | 7 ++++--- .../org/elasticsearch/transport/TransportSettings.java | 9 +++++---- .../org/elasticsearch/common/settings/SettingTests.java | 7 ++++--- .../org/elasticsearch/cloud/gce/GceComputeService.java | 3 ++- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java index fc192225222..83f4f5fc88c 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java @@ -35,6 +35,7 @@ import java.util.HashSet; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import java.util.function.Function; /** * @@ -45,11 +46,11 @@ public class NetworkService extends AbstractComponent { public static final String DEFAULT_NETWORK_HOST = "_local_"; public static final Setting> GLOBAL_NETWORK_HOST_SETTING = - Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), s -> s, SettingsProperty.ClusterScope); + Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), Function.identity(), SettingsProperty.ClusterScope); public static final Setting> GLOBAL_NETWORK_BINDHOST_SETTING = - Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, SettingsProperty.ClusterScope); + Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), SettingsProperty.ClusterScope); public static final Setting> GLOBAL_NETWORK_PUBLISHHOST_SETTING = - Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, s -> s, SettingsProperty.ClusterScope); + Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), SettingsProperty.ClusterScope); public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, SettingsProperty.ClusterScope); public static final class TcpSettings { diff --git a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java index 9fbf444e76e..b1b29eae60c 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java +++ b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java @@ -26,6 +26,7 @@ import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; import java.util.List; +import java.util.function.Function; import static java.util.Collections.emptyList; import static org.elasticsearch.common.settings.Setting.listSetting; @@ -53,11 +54,11 @@ public final class HttpTransportSettings { public static final Setting SETTING_HTTP_COMPRESSION_LEVEL = Setting.intSetting("http.compression_level", 6, SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_HOST = - listSetting("http.host", emptyList(), s -> s, SettingsProperty.ClusterScope); + listSetting("http.host", emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_PUBLISH_HOST = - listSetting("http.publish_host", SETTING_HTTP_HOST, s -> s, SettingsProperty.ClusterScope); + listSetting("http.publish_host", SETTING_HTTP_HOST, Function.identity(), SettingsProperty.ClusterScope); public static final Setting> SETTING_HTTP_BIND_HOST = - listSetting("http.bind_host", SETTING_HTTP_HOST, s -> s, SettingsProperty.ClusterScope); + listSetting("http.bind_host", SETTING_HTTP_HOST, Function.identity(), SettingsProperty.ClusterScope); public static final Setting SETTING_HTTP_PORT = new Setting("http.port", "9200-9300", PortsRange::new, SettingsProperty.ClusterScope); diff --git a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java index eaa3f004188..b52a54509bd 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.settings.Setting.SettingsProperty; import org.elasticsearch.common.settings.Settings; import java.util.List; +import java.util.function.Function; import static java.util.Collections.emptyList; import static org.elasticsearch.common.settings.Setting.groupSetting; @@ -36,13 +37,13 @@ import static org.elasticsearch.common.settings.Setting.listSetting; final public class TransportSettings { public static final Setting> HOST = - listSetting("transport.host", emptyList(), s -> s, SettingsProperty.ClusterScope); + listSetting("transport.host", emptyList(), Function.identity(), SettingsProperty.ClusterScope); public static final Setting> PUBLISH_HOST = - listSetting("transport.publish_host", HOST, s -> s, SettingsProperty.ClusterScope); + listSetting("transport.publish_host", HOST, Function.identity(), SettingsProperty.ClusterScope); public static final Setting> BIND_HOST = - listSetting("transport.bind_host", HOST, s -> s, SettingsProperty.ClusterScope); + listSetting("transport.bind_host", HOST, Function.identity(), SettingsProperty.ClusterScope); public static final Setting PORT = - new Setting<>("transport.tcp.port", "9300-9400", s -> s, SettingsProperty.ClusterScope); + new Setting<>("transport.tcp.port", "9300-9400", Function.identity(), SettingsProperty.ClusterScope); public static final Setting PUBLISH_PORT = intSetting("transport.publish_port", -1, -1, SettingsProperty.ClusterScope); public static final String DEFAULT_PROFILE = "default"; diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index cd6496d8b2f..9d1176dd0f4 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -29,6 +29,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -122,11 +123,11 @@ public class SettingTests extends ESTestCase { assertEquals(defautlValue, setting.getDefault(Settings.EMPTY)); Setting secondaryDefault = - new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), (s) -> s, SettingsProperty.ClusterScope); + new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), Function.identity(), SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefault.get(Settings.EMPTY)); assertEquals("42", secondaryDefault.get(Settings.builder().put("old.foo.bar", 42).build())); Setting secondaryDefaultViaSettings = - new Setting<>("foo.bar", secondaryDefault, (s) -> s, SettingsProperty.ClusterScope); + new Setting<>("foo.bar", secondaryDefault, Function.identity(), SettingsProperty.ClusterScope); assertEquals("some_default", secondaryDefaultViaSettings.get(Settings.EMPTY)); assertEquals("42", secondaryDefaultViaSettings.get(Settings.builder().put("old.foo.bar", 42).build())); } @@ -324,7 +325,7 @@ public class SettingTests extends ESTestCase { assertEquals(i, intValues.get(i).intValue()); } - Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, s -> s, + Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, Function.identity(), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); value = settingWithFallback.get(Settings.EMPTY); assertEquals(1, value.size()); diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java index 60af05ad6a1..7a46768e5a0 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Function; public interface GceComputeService extends LifecycleComponent { @@ -48,7 +49,7 @@ public interface GceComputeService extends LifecycleComponent * cloud.gce.zone: Google Compute Engine zones */ Setting> ZONE_SETTING = - Setting.listSetting("cloud.gce.zone", Collections.emptyList(), s -> s, SettingsProperty.ClusterScope); + Setting.listSetting("cloud.gce.zone", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); /** * cloud.gce.refresh_interval: How long the list of hosts is cached to prevent further requests to the AWS API. 0 disables caching. From e4031932edaea00b5ec06f6153aa7e02e8f0e74e Mon Sep 17 00:00:00 2001 From: David Pilato Date: Wed, 2 Mar 2016 15:10:32 +0100 Subject: [PATCH 12/49] Use deprecation Logger --- .../main/java/org/elasticsearch/common/settings/Setting.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index af2d53743e4..394180d27f5 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -24,6 +24,7 @@ import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.regex.Regex; @@ -110,6 +111,8 @@ public class Setting extends ToXContentToBytes { } private static final ESLogger logger = Loggers.getLogger(Setting.class); + private static final DeprecationLogger deprecationLogger = new DeprecationLogger(logger); + private final String key; protected final Function defaultValue; private final Function parser; @@ -292,7 +295,7 @@ public class Setting extends ToXContentToBytes { // They're using the setting, so we need to tell them to stop if (this.isDeprecated() && this.exists(settings)) { // It would be convenient to show its replacement key, but replacement is often not so simple - logger.warn("[{}] setting was deprecated in Elasticsearch and it will be removed in a future release! " + + deprecationLogger.deprecated("[{}] setting was deprecated in Elasticsearch and it will be removed in a future release! " + "See the breaking changes lists in the documentation for details", getKey()); } return settings.get(key, defaultValue.apply(settings)); From 209da28bb2d63b6e9e517cd996d40e9222224a8c Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 3 Mar 2016 09:37:33 -0800 Subject: [PATCH 13/49] Removed check file command tests, check file command is going away --- .../common/cli/CheckFileCommandTests.java | 329 ------------------ 1 file changed, 329 deletions(-) delete mode 100644 qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CheckFileCommandTests.java diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CheckFileCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CheckFileCommandTests.java deleted file mode 100644 index 45f3df22cd7..00000000000 --- a/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CheckFileCommandTests.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.common.cli; - -import com.google.common.jimfs.Configuration; -import com.google.common.jimfs.Jimfs; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.env.Environment; -import org.elasticsearch.test.ESTestCase; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.GroupPrincipal; -import java.nio.file.attribute.PosixFileAttributeView; -import java.nio.file.attribute.PosixFileAttributes; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.UserPrincipal; -import java.util.Set; - -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - -/** - * - */ -public class CheckFileCommandTests extends ESTestCase { - - private CliToolTestCase.CaptureOutputTerminal captureOutputTerminal = new CliToolTestCase.CaptureOutputTerminal(); - - private Configuration jimFsConfiguration = Configuration.unix().toBuilder().setAttributeViews("basic", "owner", "posix", "unix").build(); - private Configuration jimFsConfigurationWithoutPermissions = randomBoolean() ? Configuration.unix().toBuilder().setAttributeViews("basic").build() : Configuration.windows(); - - private enum Mode { - CHANGE, KEEP, DISABLED - } - - public void testThatCommandLogsErrorMessageOnFail() throws Exception { - executeCommand(jimFsConfiguration, new PermissionCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.CHANGE)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasItem(containsString("Please ensure that the user account running Elasticsearch has read access to this file"))); - } - - public void testThatCommandLogsNothingWhenPermissionRemains() throws Exception { - executeCommand(jimFsConfiguration, new PermissionCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.KEEP)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingWhenDisabled() throws Exception { - executeCommand(jimFsConfiguration, new PermissionCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingIfFilesystemDoesNotSupportPermissions() throws Exception { - executeCommand(jimFsConfigurationWithoutPermissions, new PermissionCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsOwnerChange() throws Exception { - executeCommand(jimFsConfiguration, new OwnerCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.CHANGE)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasItem(allOf(containsString("Owner of file ["), containsString("] used to be ["), containsString("], but now is [")))); - } - - public void testThatCommandLogsNothingIfOwnerRemainsSame() throws Exception { - executeCommand(jimFsConfiguration, new OwnerCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.KEEP)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingIfOwnerIsDisabled() throws Exception { - executeCommand(jimFsConfiguration, new OwnerCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingIfFileSystemDoesNotSupportOwners() throws Exception { - executeCommand(jimFsConfigurationWithoutPermissions, new OwnerCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsIfGroupChanges() throws Exception { - executeCommand(jimFsConfiguration, new GroupCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.CHANGE)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasItem(allOf(containsString("Group of file ["), containsString("] used to be ["), containsString("], but now is [")))); - } - - public void testThatCommandLogsNothingIfGroupRemainsSame() throws Exception { - executeCommand(jimFsConfiguration, new GroupCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.KEEP)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingIfGroupIsDisabled() throws Exception { - executeCommand(jimFsConfiguration, new GroupCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandLogsNothingIfFileSystemDoesNotSupportGroups() throws Exception { - executeCommand(jimFsConfigurationWithoutPermissions, new GroupCheckFileCommand(createTempDir(), captureOutputTerminal, Mode.DISABLED)); - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandDoesNotLogAnythingOnFileCreation() throws Exception { - Configuration configuration = randomBoolean() ? jimFsConfiguration : jimFsConfigurationWithoutPermissions; - - try (FileSystem fs = Jimfs.newFileSystem(configuration)) { - Path path = fs.getPath(randomAsciiOfLength(10)); - Settings settings = Settings.builder() - .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString()) - .build(); - new CreateFileCommand(captureOutputTerminal, path).execute(settings, new Environment(settings)); - assertThat(Files.exists(path), is(true)); - } - - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - public void testThatCommandWorksIfFileIsDeletedByCommand() throws Exception { - Configuration configuration = randomBoolean() ? jimFsConfiguration : jimFsConfigurationWithoutPermissions; - - try (FileSystem fs = Jimfs.newFileSystem(configuration)) { - Path path = fs.getPath(randomAsciiOfLength(10)); - Files.write(path, "anything".getBytes(StandardCharsets.UTF_8)); - - Settings settings = Settings.builder() - .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString()) - .build(); - new DeleteFileCommand(captureOutputTerminal, path).execute(settings, new Environment(settings)); - assertThat(Files.exists(path), is(false)); - } - - assertThat(captureOutputTerminal.getTerminalOutput(), hasSize(0)); - } - - private void executeCommand(Configuration configuration, AbstractTestCheckFileCommand command) throws Exception { - try (FileSystem fs = Jimfs.newFileSystem(configuration)) { - command.execute(fs); - } - } - - abstract class AbstractTestCheckFileCommand extends CheckFileCommand { - - protected final Mode mode; - protected FileSystem fs; - protected Path[] paths; - final Path baseDir; - - public AbstractTestCheckFileCommand(Path baseDir, Terminal terminal, Mode mode) throws IOException { - super(terminal); - this.mode = mode; - this.baseDir = baseDir; - } - - public CliTool.ExitStatus execute(FileSystem fs) throws Exception { - this.fs = fs; - this.paths = new Path[] { writePath(fs, "p1", "anything"), writePath(fs, "p2", "anything"), writePath(fs, "p3", "anything") }; - Settings settings = Settings.settingsBuilder() - .put(Environment.PATH_HOME_SETTING.getKey(), baseDir.toString()) - .build(); - return super.execute(Settings.EMPTY, new Environment(settings)); - } - - private Path writePath(FileSystem fs, String name, String content) throws IOException { - Path path = fs.getPath(name); - Files.write(path, content.getBytes(StandardCharsets.UTF_8)); - return path; - } - - @Override - protected Path[] pathsForPermissionsCheck(Settings settings, Environment env) { - return paths; - } - } - - /** - * command that changes permissions from a file if enabled - */ - class PermissionCheckFileCommand extends AbstractTestCheckFileCommand { - - public PermissionCheckFileCommand(Path baseDir, Terminal terminal, Mode mode) throws IOException { - super(baseDir, terminal, mode); - } - - @Override - public CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception { - int randomInt = randomInt(paths.length - 1); - Path randomPath = paths[randomInt]; - switch (mode) { - case CHANGE: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - Files.setPosixFilePermissions(randomPath, Sets.newHashSet(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OTHERS_EXECUTE, PosixFilePermission.GROUP_EXECUTE)); - break; - case KEEP: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - Set posixFilePermissions = Files.getPosixFilePermissions(randomPath); - Files.setPosixFilePermissions(randomPath, posixFilePermissions); - break; - } - return CliTool.ExitStatus.OK; - } - - } - - /** - * command that changes the owner of a file if enabled - */ - class OwnerCheckFileCommand extends AbstractTestCheckFileCommand { - - public OwnerCheckFileCommand(Path baseDir, Terminal terminal, Mode mode) throws IOException { - super(baseDir, terminal, mode); - } - - @Override - public CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception { - int randomInt = randomInt(paths.length - 1); - Path randomPath = paths[randomInt]; - switch (mode) { - case CHANGE: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - UserPrincipal randomOwner = fs.getUserPrincipalLookupService().lookupPrincipalByName(randomAsciiOfLength(10)); - Files.setOwner(randomPath, randomOwner); - break; - case KEEP: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - UserPrincipal originalOwner = Files.getOwner(randomPath); - Files.setOwner(randomPath, originalOwner); - break; - } - - return CliTool.ExitStatus.OK; - } - } - - /** - * command that changes the group of a file if enabled - */ - class GroupCheckFileCommand extends AbstractTestCheckFileCommand { - - public GroupCheckFileCommand(Path baseDir, Terminal terminal, Mode mode) throws IOException { - super(baseDir, terminal, mode); - } - - @Override - public CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception { - int randomInt = randomInt(paths.length - 1); - Path randomPath = paths[randomInt]; - switch (mode) { - case CHANGE: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - GroupPrincipal randomPrincipal = fs.getUserPrincipalLookupService().lookupPrincipalByGroupName(randomAsciiOfLength(10)); - Files.getFileAttributeView(randomPath, PosixFileAttributeView.class).setGroup(randomPrincipal); - break; - case KEEP: - Files.write(randomPath, randomAsciiOfLength(10).getBytes(StandardCharsets.UTF_8)); - GroupPrincipal groupPrincipal = Files.readAttributes(randomPath, PosixFileAttributes.class).group(); - Files.getFileAttributeView(randomPath, PosixFileAttributeView.class).setGroup(groupPrincipal); - break; - } - - return CliTool.ExitStatus.OK; - } - } - - /** - * A command that creates a non existing file - */ - class CreateFileCommand extends CheckFileCommand { - - private final Path pathToCreate; - - public CreateFileCommand(Terminal terminal, Path pathToCreate) { - super(terminal); - this.pathToCreate = pathToCreate; - } - - @Override - public CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception { - Files.write(pathToCreate, "anything".getBytes(StandardCharsets.UTF_8)); - return CliTool.ExitStatus.OK; - } - - @Override - protected Path[] pathsForPermissionsCheck(Settings settings, Environment env) throws Exception { - return new Path[] { pathToCreate }; - } - } - - /** - * A command that deletes an existing file - */ - class DeleteFileCommand extends CheckFileCommand { - - private final Path pathToDelete; - - public DeleteFileCommand(Terminal terminal, Path pathToDelete) { - super(terminal); - this.pathToDelete = pathToDelete; - } - - @Override - public CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception { - Files.delete(pathToDelete); - return CliTool.ExitStatus.OK; - } - - @Override - protected Path[] pathsForPermissionsCheck(Settings settings, Environment env) throws Exception { - return new Path[] {pathToDelete}; - } - } -} From 76719341dc8f5fb27433020bb3e4663e6e161a62 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Fri, 4 Mar 2016 13:24:39 +0100 Subject: [PATCH 14/49] Fix after merge --- .../common/settings/Setting.java | 22 ++++++++++--------- .../common/settings/SettingTests.java | 3 ++- .../azure/storage/AzureStorageSettings.java | 14 +++++++----- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index 12adef7b4bb..c6753d243c0 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -165,11 +165,10 @@ public class Setting extends ToXContentToBytes { * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. - * @param dynamic true iff this setting can be dynamically updateable - * @param scope the scope of this setting + * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Function defaultValue, Function parser, boolean dynamic, Scope scope) { - this(new SimpleKey(key), defaultValue, parser, dynamic, scope); + public Setting(String key, Function defaultValue, Function parser, SettingsProperty... properties) { + this(new SimpleKey(key), defaultValue, parser, properties); } /** @@ -722,8 +721,9 @@ public class Setting extends ToXContentToBytes { * can easily be added with this setting. Yet, prefix key settings don't support updaters out of the box unless * {@link #getConcreteSetting(String)} is used to pull the updater. */ - public static Setting prefixKeySetting(String prefix, String defaultValue, Function parser, boolean dynamic, Scope scope) { - return affixKeySetting(AffixKey.withPrefix(prefix), (s) -> defaultValue, parser, dynamic, scope); + public static Setting prefixKeySetting(String prefix, String defaultValue, Function parser, + SettingsProperty... properties) { + return affixKeySetting(AffixKey.withPrefix(prefix), (s) -> defaultValue, parser, properties); } /** @@ -731,12 +731,14 @@ public class Setting extends ToXContentToBytes { * storage.${backend}.enable=[true|false] can easily be added with this setting. Yet, adfix key settings don't support updaters * out of the box unless {@link #getConcreteSetting(String)} is used to pull the updater. */ - public static Setting adfixKeySetting(String prefix, String suffix, Function defaultValue, Function parser, boolean dynamic, Scope scope) { - return affixKeySetting(AffixKey.withAdfix(prefix, suffix), defaultValue, parser, dynamic, scope); + public static Setting adfixKeySetting(String prefix, String suffix, Function defaultValue, + Function parser, SettingsProperty... properties) { + return affixKeySetting(AffixKey.withAdfix(prefix, suffix), defaultValue, parser, properties); } - public static Setting adfixKeySetting(String prefix, String suffix, String defaultValue, Function parser, boolean dynamic, Scope scope) { - return adfixKeySetting(prefix, suffix, (s) -> defaultValue, parser, dynamic, scope); + public static Setting adfixKeySetting(String prefix, String suffix, String defaultValue, Function parser, + SettingsProperty... properties) { + return adfixKeySetting(prefix, suffix, (s) -> defaultValue, parser, properties); } public static Setting affixKeySetting(AffixKey key, Function defaultValue, Function parser, diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index 98bb385c122..841126d1415 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -384,7 +384,8 @@ public class SettingTests extends ESTestCase { } public void testAdfixKeySetting() { - Setting setting = Setting.adfixKeySetting("foo", "enable", "false", Boolean::parseBoolean, false, Setting.Scope.CLUSTER); + Setting setting = + Setting.adfixKeySetting("foo", "enable", "false", Boolean::parseBoolean, Setting.SettingsProperty.ClusterScope); assertTrue(setting.hasComplexMatcher()); assertTrue(setting.match("foo.bar.enable")); assertTrue(setting.match("foo.baz.enable")); diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java index da9151e9504..06185845ffb 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java @@ -46,11 +46,13 @@ public final class AzureStorageSettings { TIMEOUT_KEY, (s) -> Storage.TIMEOUT_SETTING.get(s).toString(), (s) -> Setting.parseTimeValue(s, TimeValue.timeValueSeconds(-1), TIMEOUT_KEY.toString()), - false, - Setting.Scope.CLUSTER); - private static final Setting ACCOUNT_SETTING = Setting.adfixKeySetting(Storage.PREFIX, ACCOUNT_SUFFIX, "", Function.identity(), false, Setting.Scope.CLUSTER); - private static final Setting KEY_SETTING = Setting.adfixKeySetting(Storage.PREFIX, KEY_SUFFIX, "", Function.identity(), false, Setting.Scope.CLUSTER); - private static final Setting DEFAULT_SETTING = Setting.adfixKeySetting(Storage.PREFIX, DEFAULT_SUFFIX, "false", Boolean::valueOf, false, Setting.Scope.CLUSTER); + Setting.SettingsProperty.ClusterScope); + private static final Setting ACCOUNT_SETTING = + Setting.adfixKeySetting(Storage.PREFIX, ACCOUNT_SUFFIX, "", Function.identity(), Setting.SettingsProperty.ClusterScope); + private static final Setting KEY_SETTING = + Setting.adfixKeySetting(Storage.PREFIX, KEY_SUFFIX, "", Function.identity(), Setting.SettingsProperty.ClusterScope); + private static final Setting DEFAULT_SETTING = + Setting.adfixKeySetting(Storage.PREFIX, DEFAULT_SUFFIX, "false", Boolean::valueOf, Setting.SettingsProperty.ClusterScope); private final String name; @@ -110,7 +112,7 @@ public final class AzureStorageSettings { } private static List createStorageSettings(Settings settings) { - Setting storageGroupSetting = Setting.groupSetting(Storage.PREFIX, false, Setting.Scope.CLUSTER); + Setting storageGroupSetting = Setting.groupSetting(Storage.PREFIX, Setting.SettingsProperty.ClusterScope); // ignore global timeout which has the same prefix but does not belong to any group Settings groups = storageGroupSetting.get(settings.filter((k) -> k.equals(Storage.TIMEOUT_SETTING.getKey()) == false)); List storageSettings = new ArrayList<>(); From 2bb3846d1fd6b120e963762ee9efe8c3120ff412 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Fri, 4 Mar 2016 16:53:22 +0100 Subject: [PATCH 15/49] Update after review: * remove `ClusterScope` * rename `ClusterSettings` to `NodeSettings` * rename `SettingsProperty` to `Property` --- .../close/TransportCloseIndexAction.java | 4 +- .../action/support/AutoCreateIndex.java | 4 +- .../action/support/DestructiveOperations.java | 4 +- .../master/TransportMasterNodeReadAction.java | 4 +- .../bootstrap/BootstrapSettings.java | 10 +- .../cache/recycler/PageCacheRecycler.java | 15 +-- .../java/org/elasticsearch/client/Client.java | 8 +- .../TransportClientNodesService.java | 10 +- .../elasticsearch/cluster/ClusterModule.java | 4 +- .../elasticsearch/cluster/ClusterName.java | 4 +- .../cluster/InternalClusterInfoService.java | 6 +- .../action/index/MappingUpdatedAction.java | 4 +- .../cluster/metadata/AutoExpandReplicas.java | 4 +- .../cluster/metadata/IndexMetaData.java | 30 ++--- .../cluster/metadata/MetaData.java | 4 +- .../cluster/routing/UnassignedInfo.java | 6 +- .../allocator/BalancedShardsAllocator.java | 8 +- .../decider/AwarenessAllocationDecider.java | 8 +- .../ClusterRebalanceAllocationDecider.java | 4 +- .../ConcurrentRebalanceAllocationDecider.java | 4 +- .../decider/DiskThresholdDecider.java | 12 +- .../decider/EnableAllocationDecider.java | 10 +- .../decider/FilterAllocationDecider.java | 8 +- .../decider/ShardsLimitAllocationDecider.java | 6 +- .../SnapshotInProgressAllocationDecider.java | 4 +- .../decider/ThrottlingAllocationDecider.java | 10 +- .../service/InternalClusterService.java | 8 +- .../common/logging/ESLoggerFactory.java | 7 +- .../common/network/NetworkModule.java | 10 +- .../common/network/NetworkService.java | 28 ++-- .../settings/AbstractScopedSettings.java | 6 +- .../common/settings/ClusterSettings.java | 4 +- .../common/settings/IndexScopedSettings.java | 10 +- .../common/settings/Setting.java | 123 ++++++++---------- .../common/settings/SettingsModule.java | 19 +-- .../common/util/concurrent/EsExecutors.java | 4 +- .../common/util/concurrent/ThreadContext.java | 5 +- .../discovery/DiscoveryModule.java | 6 +- .../discovery/DiscoverySettings.java | 12 +- .../discovery/zen/ZenDiscovery.java | 20 +-- .../zen/elect/ElectMasterService.java | 4 +- .../discovery/zen/fd/FaultDetection.java | 12 +- .../zen/ping/unicast/UnicastZenPing.java | 6 +- .../org/elasticsearch/env/Environment.java | 20 +-- .../elasticsearch/env/NodeEnvironment.java | 11 +- .../elasticsearch/gateway/GatewayService.java | 16 +-- .../gateway/PrimaryShardAllocator.java | 6 +- .../http/HttpTransportSettings.java | 44 +++---- .../http/netty/NettyHttpServerTransport.java | 26 ++-- .../org/elasticsearch/index/IndexModule.java | 8 +- .../elasticsearch/index/IndexSettings.java | 34 ++--- .../org/elasticsearch/index/IndexWarmer.java | 4 +- .../elasticsearch/index/IndexingSlowLog.java | 18 +-- .../index/MergePolicyConfig.java | 18 +-- .../index/MergeSchedulerConfig.java | 10 +- .../elasticsearch/index/SearchSlowLog.java | 24 ++-- .../index/cache/bitset/BitsetFilterCache.java | 4 +- .../index/engine/EngineConfig.java | 6 +- .../fielddata/IndexFieldDataService.java | 4 +- .../index/mapper/FieldMapper.java | 6 +- .../index/mapper/MapperService.java | 6 +- .../index/mapper/core/NumberFieldMapper.java | 4 +- .../percolator/PercolatorQueriesRegistry.java | 6 +- .../index/store/FsDirectoryService.java | 5 +- .../elasticsearch/index/store/IndexStore.java | 6 +- .../index/store/IndexStoreConfig.java | 6 +- .../org/elasticsearch/index/store/Store.java | 6 +- .../indices/IndicesQueryCache.java | 6 +- .../indices/IndicesRequestCache.java | 8 +- .../elasticsearch/indices/IndicesService.java | 4 +- .../indices/analysis/HunspellService.java | 8 +- .../HierarchyCircuitBreakerService.java | 16 +-- .../cache/IndicesFieldDataCache.java | 4 +- .../indices/recovery/RecoverySettings.java | 14 +- .../indices/store/IndicesStore.java | 5 +- .../indices/ttl/IndicesTTLService.java | 4 +- .../elasticsearch/monitor/fs/FsService.java | 4 +- .../monitor/jvm/JvmGcMonitorService.java | 8 +- .../elasticsearch/monitor/jvm/JvmService.java | 4 +- .../elasticsearch/monitor/os/OsService.java | 4 +- .../monitor/process/ProcessService.java | 4 +- .../java/org/elasticsearch/node/Node.java | 20 +-- .../internal/InternalSettingsPreparer.java | 4 +- .../elasticsearch/plugins/PluginsService.java | 4 +- .../repositories/fs/FsRepository.java | 14 +- .../repositories/uri/URLRepository.java | 14 +- .../elasticsearch/rest/BaseRestHandler.java | 4 +- .../elasticsearch/script/ScriptService.java | 9 +- .../elasticsearch/script/ScriptSettings.java | 10 +- .../elasticsearch/search/SearchService.java | 9 +- .../elasticsearch/threadpool/ThreadPool.java | 4 +- .../elasticsearch/transport/Transport.java | 4 +- .../transport/TransportService.java | 6 +- .../transport/TransportSettings.java | 14 +- .../transport/netty/NettyTransport.java | 44 +++---- .../org/elasticsearch/tribe/TribeService.java | 16 +-- .../repositories/RepositoryBlocksIT.java | 2 +- .../cluster/snapshots/SnapshotBlocksIT.java | 2 +- .../cluster/ClusterModuleTests.java | 6 +- .../cluster/settings/SettingsFilteringIT.java | 8 +- .../common/settings/ScopedSettingsTests.java | 30 ++--- .../common/settings/SettingTests.java | 81 ++++-------- .../common/settings/SettingsModuleTests.java | 12 +- .../elasticsearch/index/IndexModuleTests.java | 6 +- .../index/IndexSettingsTests.java | 10 +- .../index/SettingsListenerIT.java | 6 +- .../indices/IndicesOptionsIntegrationIT.java | 8 +- .../RandomExceptionCircuitBreakerIT.java | 6 +- .../basic/SearchWithRandomExceptionsIT.java | 6 +- .../snapshots/mockstore/MockRepository.java | 6 +- .../azure/management/AzureComputeService.java | 18 +-- .../cloud/aws/AwsEc2Service.java | 54 ++++---- .../cloud/gce/GceComputeService.java | 12 +- .../cloud/gce/GceComputeServiceImpl.java | 9 +- .../gce/GceUnicastHostsProvider.java | 4 +- .../mapper/attachments/AttachmentMapper.java | 8 +- .../azure/storage/AzureStorageService.java | 16 +-- .../azure/storage/AzureStorageSettings.java | 10 +- .../repositories/azure/AzureRepository.java | 14 +- .../elasticsearch/cloud/aws/AwsS3Service.java | 40 +++--- .../repositories/s3/S3Repository.java | 58 ++++----- .../elasticsearch/test/ESIntegTestCase.java | 8 +- .../test/InternalSettingsPlugin.java | 8 +- .../test/MockIndexEventListener.java | 4 +- .../test/engine/MockEngineSupport.java | 6 +- .../test/store/MockFSDirectoryService.java | 14 +- .../test/store/MockFSIndexStore.java | 4 +- .../test/tasks/MockTaskManager.java | 4 +- .../transport/AssertingLocalTransport.java | 6 +- 129 files changed, 733 insertions(+), 799 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java index 6065a2ec66e..5c88a8be3d3 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/close/TransportCloseIndexAction.java @@ -33,7 +33,7 @@ import org.elasticsearch.cluster.metadata.MetaDataIndexStateService; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; @@ -48,7 +48,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeAction CLUSTER_INDICES_CLOSE_ENABLE_SETTING = - Setting.boolSetting("cluster.indices.close.enable", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.indices.close.enable", true, Property.Dynamic, Property.NodeScope); @Inject public TransportCloseIndexAction(Settings settings, TransportService transportService, ClusterService clusterService, diff --git a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java index 2169d3a1521..339abcb22bc 100644 --- a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java +++ b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java @@ -27,7 +27,7 @@ import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.mapper.MapperService; @@ -41,7 +41,7 @@ import java.util.List; public final class AutoCreateIndex { public static final Setting AUTO_CREATE_INDEX_SETTING = - new Setting<>("action.auto_create_index", "true", AutoCreate::new, SettingsProperty.ClusterScope); + new Setting<>("action.auto_create_index", "true", AutoCreate::new, Property.NodeScope); private final boolean dynamicMappingDisabled; private final IndexNameExpressionResolver resolver; diff --git a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java index 6591384271b..31fc1d06175 100644 --- a/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java +++ b/core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java @@ -23,7 +23,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -35,7 +35,7 @@ public final class DestructiveOperations extends AbstractComponent { * Setting which controls whether wildcard usage (*, prefix*, _all) is allowed. */ public static final Setting REQUIRES_NAME_SETTING = - Setting.boolSetting("action.destructive_requires_name", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.boolSetting("action.destructive_requires_name", false, Property.Dynamic, Property.NodeScope); private volatile boolean destructiveRequiresName; @Inject diff --git a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java index 08ba0defd73..f53355f24e3 100644 --- a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java +++ b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java @@ -24,7 +24,7 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; @@ -39,7 +39,7 @@ public abstract class TransportMasterNodeReadAction { public static final Setting FORCE_LOCAL_SETTING = - Setting.boolSetting("action.master.force_local", false, SettingsProperty.ClusterScope); + Setting.boolSetting("action.master.force_local", false, Property.NodeScope); private final boolean forceLocal; diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java index dd9263330e6..4e9dffc995b 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java @@ -20,7 +20,7 @@ package org.elasticsearch.bootstrap; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; public final class BootstrapSettings { @@ -29,13 +29,13 @@ public final class BootstrapSettings { // TODO: remove this hack when insecure defaults are removed from java public static final Setting SECURITY_FILTER_BAD_DEFAULTS_SETTING = - Setting.boolSetting("security.manager.filter_bad_defaults", true, SettingsProperty.ClusterScope); + Setting.boolSetting("security.manager.filter_bad_defaults", true, Property.NodeScope); public static final Setting MLOCKALL_SETTING = - Setting.boolSetting("bootstrap.mlockall", false, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.mlockall", false, Property.NodeScope); public static final Setting SECCOMP_SETTING = - Setting.boolSetting("bootstrap.seccomp", true, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.seccomp", true, Property.NodeScope); public static final Setting CTRLHANDLER_SETTING = - Setting.boolSetting("bootstrap.ctrlhandler", true, SettingsProperty.ClusterScope); + Setting.boolSetting("bootstrap.ctrlhandler", true, Property.NodeScope); } diff --git a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java index f58947409e9..2fad8678649 100644 --- a/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java +++ b/core/src/main/java/org/elasticsearch/cache/recycler/PageCacheRecycler.java @@ -19,14 +19,13 @@ package org.elasticsearch.cache.recycler; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.recycler.AbstractRecyclerC; import org.elasticsearch.common.recycler.Recycler; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.util.BigArrays; @@ -45,18 +44,18 @@ import static org.elasticsearch.common.recycler.Recyclers.none; public class PageCacheRecycler extends AbstractComponent implements Releasable { public static final Setting TYPE_SETTING = - new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, SettingsProperty.ClusterScope); + new Setting<>("cache.recycler.page.type", Type.CONCURRENT.name(), Type::parse, Property.NodeScope); public static final Setting LIMIT_HEAP_SETTING = - Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", SettingsProperty.ClusterScope); + Setting.byteSizeSetting("cache.recycler.page.limit.heap", "10%", Property.NodeScope); public static final Setting WEIGHT_BYTES_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.bytes", 1d, 0d, Property.NodeScope); public static final Setting WEIGHT_LONG_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.longs", 1d, 0d, Property.NodeScope); public static final Setting WEIGHT_INT_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.ints", 1d, 0d, Property.NodeScope); // object pages are less useful to us so we give them a lower weight by default public static final Setting WEIGHT_OBJECTS_SETTING = - Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, SettingsProperty.ClusterScope); + Setting.doubleSetting("cache.recycler.page.weight.objects", 0.1d, 0d, Property.NodeScope); private final Recycler bytePage; private final Recycler intPage; diff --git a/core/src/main/java/org/elasticsearch/client/Client.java b/core/src/main/java/org/elasticsearch/client/Client.java index 1ced0f2b019..e5d8d4f55b7 100644 --- a/core/src/main/java/org/elasticsearch/client/Client.java +++ b/core/src/main/java/org/elasticsearch/client/Client.java @@ -19,12 +19,8 @@ package org.elasticsearch.client; -import org.elasticsearch.action.Action; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.ActionRequest; -import org.elasticsearch.action.ActionRequestBuilder; -import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; @@ -87,7 +83,7 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.Map; @@ -115,7 +111,7 @@ public interface Client extends ElasticsearchClient, Releasable { default: throw new IllegalArgumentException("Can't parse [client.type] must be one of [node, transport]"); } - }, SettingsProperty.ClusterScope); + }, Property.NodeScope); /** * The admin client that can be used to perform administrative operations. diff --git a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java index 28c921333ca..2dfd8f9fa03 100644 --- a/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java +++ b/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java @@ -34,7 +34,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -102,13 +102,13 @@ public class TransportClientNodesService extends AbstractComponent { public static final Setting CLIENT_TRANSPORT_NODES_SAMPLER_INTERVAL = - Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("client.transport.nodes_sampler_interval", timeValueSeconds(5), Property.NodeScope); public static final Setting CLIENT_TRANSPORT_PING_TIMEOUT = - Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("client.transport.ping_timeout", timeValueSeconds(5), Property.NodeScope); public static final Setting CLIENT_TRANSPORT_IGNORE_CLUSTER_NAME = - Setting.boolSetting("client.transport.ignore_cluster_name", false, SettingsProperty.ClusterScope); + Setting.boolSetting("client.transport.ignore_cluster_name", false, Property.NodeScope); public static final Setting CLIENT_TRANSPORT_SNIFF = - Setting.boolSetting("client.transport.sniff", false, SettingsProperty.ClusterScope); + Setting.boolSetting("client.transport.sniff", false, Property.NodeScope); @Inject public TransportClientNodesService(Settings settings, ClusterName clusterName, TransportService transportService, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java index c57549236e8..c54cf1b070f 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java @@ -58,7 +58,7 @@ import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.gateway.GatewayAllocator; @@ -76,7 +76,7 @@ public class ClusterModule extends AbstractModule { public static final String EVEN_SHARD_COUNT_ALLOCATOR = "even_shard"; public static final String BALANCED_ALLOCATOR = "balanced"; // default public static final Setting SHARDS_ALLOCATOR_TYPE_SETTING = - new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.type", BALANCED_ALLOCATOR, Function.identity(), Property.NodeScope); public static final List> DEFAULT_ALLOCATION_DECIDERS = Collections.unmodifiableList(Arrays.asList( SameShardAllocationDecider.class, diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java index 185c68e075c..09c64065dbd 100644 --- a/core/src/main/java/org/elasticsearch/cluster/ClusterName.java +++ b/core/src/main/java/org/elasticsearch/cluster/ClusterName.java @@ -23,7 +23,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.io.IOException; @@ -38,7 +38,7 @@ public class ClusterName implements Streamable { throw new IllegalArgumentException("[cluster.name] must not be empty"); } return s; - }, SettingsProperty.ClusterScope); + }, Property.NodeScope); public static final ClusterName DEFAULT = new ClusterName(CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY).intern()); diff --git a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java index 32f521a6782..896793f1bf3 100644 --- a/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java +++ b/core/src/main/java/org/elasticsearch/cluster/InternalClusterInfoService.java @@ -39,7 +39,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; @@ -67,10 +67,10 @@ public class InternalClusterInfoService extends AbstractComponent implements Clu public static final Setting INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL_SETTING = Setting.timeSetting("cluster.info.update.interval", TimeValue.timeValueSeconds(30), TimeValue.timeValueSeconds(10), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting INTERNAL_CLUSTER_INFO_TIMEOUT_SETTING = Setting.positiveTimeSetting("cluster.info.update.timeout", TimeValue.timeValueSeconds(15), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile TimeValue updateFrequency; diff --git a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java index 4005631d5af..d483d56d84c 100644 --- a/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java +++ b/core/src/main/java/org/elasticsearch/cluster/action/index/MappingUpdatedAction.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.mapper.MapperService; @@ -44,7 +44,7 @@ public class MappingUpdatedAction extends AbstractComponent { public static final Setting INDICES_MAPPING_DYNAMIC_TIMEOUT_SETTING = Setting.positiveTimeSetting("indices.mapping.dynamic_timeout", TimeValue.timeValueSeconds(30), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private IndicesAdminClient client; private volatile TimeValue dynamicMappingUpdateTimeout; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java index 9a8499832ea..4b4a8e54d7c 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AutoExpandReplicas.java @@ -20,7 +20,7 @@ package org.elasticsearch.cluster.metadata; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; /** * This class acts as a functional wrapper around the index.auto_expand_replicas setting. @@ -57,7 +57,7 @@ final class AutoExpandReplicas { } } return new AutoExpandReplicas(min, max, true); - }, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + }, Property.Dynamic, Property.IndexScope); private final int minReplicas; private final int maxReplicas; diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index 3031273815d..8c093a72ff3 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -38,7 +38,7 @@ import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.common.xcontent.FromXContentBuilder; @@ -154,35 +154,35 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String INDEX_SETTING_PREFIX = "index."; public static final String SETTING_NUMBER_OF_SHARDS = "index.number_of_shards"; public static final Setting INDEX_NUMBER_OF_SHARDS_SETTING = - Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, SettingsProperty.IndexScope); + Setting.intSetting(SETTING_NUMBER_OF_SHARDS, 5, 1, Property.IndexScope); public static final String SETTING_NUMBER_OF_REPLICAS = "index.number_of_replicas"; public static final Setting INDEX_NUMBER_OF_REPLICAS_SETTING = - Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.intSetting(SETTING_NUMBER_OF_REPLICAS, 1, 0, Property.Dynamic, Property.IndexScope); public static final String SETTING_SHADOW_REPLICAS = "index.shadow_replicas"; public static final Setting INDEX_SHADOW_REPLICAS_SETTING = - Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHADOW_REPLICAS, false, Property.IndexScope); public static final String SETTING_SHARED_FILESYSTEM = "index.shared_filesystem"; public static final Setting INDEX_SHARED_FILESYSTEM_SETTING = - Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHARED_FILESYSTEM, false, Property.IndexScope); public static final String SETTING_AUTO_EXPAND_REPLICAS = "index.auto_expand_replicas"; public static final Setting INDEX_AUTO_EXPAND_REPLICAS_SETTING = AutoExpandReplicas.SETTING; public static final String SETTING_READ_ONLY = "index.blocks.read_only"; public static final Setting INDEX_READ_ONLY_SETTING = - Setting.boolSetting(SETTING_READ_ONLY, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_READ_ONLY, false, Property.Dynamic, Property.IndexScope); public static final String SETTING_BLOCKS_READ = "index.blocks.read"; public static final Setting INDEX_BLOCKS_READ_SETTING = - Setting.boolSetting(SETTING_BLOCKS_READ, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_READ, false, Property.Dynamic, Property.IndexScope); public static final String SETTING_BLOCKS_WRITE = "index.blocks.write"; public static final Setting INDEX_BLOCKS_WRITE_SETTING = - Setting.boolSetting(SETTING_BLOCKS_WRITE, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_WRITE, false, Property.Dynamic, Property.IndexScope); public static final String SETTING_BLOCKS_METADATA = "index.blocks.metadata"; public static final Setting INDEX_BLOCKS_METADATA_SETTING = - Setting.boolSetting(SETTING_BLOCKS_METADATA, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_BLOCKS_METADATA, false, Property.Dynamic, Property.IndexScope); public static final String SETTING_VERSION_CREATED = "index.version.created"; public static final String SETTING_VERSION_CREATED_STRING = "index.version.created_string"; @@ -192,23 +192,23 @@ public class IndexMetaData implements Diffable, FromXContentBuild public static final String SETTING_CREATION_DATE = "index.creation_date"; public static final String SETTING_PRIORITY = "index.priority"; public static final Setting INDEX_PRIORITY_SETTING = - Setting.intSetting("index.priority", 1, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.intSetting("index.priority", 1, 0, Property.Dynamic, Property.IndexScope); public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string"; public static final String SETTING_INDEX_UUID = "index.uuid"; public static final String SETTING_DATA_PATH = "index.data_path"; public static final Setting INDEX_DATA_PATH_SETTING = - new Setting<>(SETTING_DATA_PATH, "", Function.identity(), SettingsProperty.IndexScope); + new Setting<>(SETTING_DATA_PATH, "", Function.identity(), Property.IndexScope); public static final String SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE = "index.shared_filesystem.recover_on_any_node"; public static final Setting INDEX_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE_SETTING = - Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(SETTING_SHARED_FS_ALLOW_RECOVERY_ON_ANY_NODE, false, Property.Dynamic, Property.IndexScope); public static final String INDEX_UUID_NA_VALUE = "_na_"; public static final Setting INDEX_ROUTING_REQUIRE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.require.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.require.", Property.Dynamic, Property.IndexScope); public static final Setting INDEX_ROUTING_INCLUDE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.include.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.include.", Property.Dynamic, Property.IndexScope); public static final Setting INDEX_ROUTING_EXCLUDE_GROUP_SETTING = - Setting.groupSetting("index.routing.allocation.exclude.", SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.groupSetting("index.routing.allocation.exclude.", Property.Dynamic, Property.IndexScope); public static final IndexMetaData PROTO = IndexMetaData.builder("") .settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index 996046015b1..4c83f64581e 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -41,7 +41,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.common.xcontent.FromXContentBuilder; @@ -141,7 +141,7 @@ public class MetaData implements Iterable, Diffable, Fr public static final Setting SETTING_READ_ONLY_SETTING = - Setting.boolSetting("cluster.blocks.read_only", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.blocks.read_only", false, Property.Dynamic, Property.NodeScope); public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE)); diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java index 1b7fcf96779..be7d90a1fef 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java @@ -29,7 +29,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; @@ -46,8 +46,8 @@ public class UnassignedInfo implements ToXContent, Writeable { private static final TimeValue DEFAULT_DELAYED_NODE_LEFT_TIMEOUT = TimeValue.timeValueMinutes(1); public static final Setting INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING = - Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + Setting.timeSetting("index.unassigned.node_left.delayed_timeout", DEFAULT_DELAYED_NODE_LEFT_TIMEOUT, Property.Dynamic, + Property.IndexScope); /** * Reason why the shard is in unassigned state. diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java index 22cb17ab8cb..40e0d6c9732 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java @@ -39,7 +39,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.gateway.PriorityComparator; @@ -74,12 +74,12 @@ import static org.elasticsearch.cluster.routing.ShardRoutingState.RELOCATING; public class BalancedShardsAllocator extends AbstractComponent implements ShardsAllocator { public static final Setting INDEX_BALANCE_FACTOR_SETTING = - Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.floatSetting("cluster.routing.allocation.balance.index", 0.55f, Property.Dynamic, Property.NodeScope); public static final Setting SHARD_BALANCE_FACTOR_SETTING = - Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.floatSetting("cluster.routing.allocation.balance.shard", 0.45f, Property.Dynamic, Property.NodeScope); public static final Setting THRESHOLD_SETTING = Setting.floatSetting("cluster.routing.allocation.balance.threshold", 1.0f, 0.0f, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile WeightFunction weightFunction; private volatile float threshold; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java index 235cfd84186..77613f39084 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AwarenessAllocationDecider.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.HashMap; @@ -79,10 +79,10 @@ public class AwarenessAllocationDecider extends AllocationDecider { public static final String NAME = "awareness"; public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING = - new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , SettingsProperty.Dynamic, - SettingsProperty.ClusterScope); + new Setting<>("cluster.routing.allocation.awareness.attributes", "", Strings::splitStringByCommaToArray , Property.Dynamic, + Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.awareness.force.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.awareness.force.", Property.Dynamic, Property.NodeScope); private String[] awarenessAttributes; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java index 58966dd62a6..84e974aceb0 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ClusterRebalanceAllocationDecider.java @@ -24,7 +24,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.Locale; @@ -51,7 +51,7 @@ public class ClusterRebalanceAllocationDecider extends AllocationDecider { public static final String NAME = "cluster_rebalance"; public static final Setting CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING = new Setting<>("cluster.routing.allocation.allow_rebalance", ClusterRebalanceType.INDICES_ALL_ACTIVE.name().toLowerCase(Locale.ROOT), - ClusterRebalanceType::parseString, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + ClusterRebalanceType::parseString, Property.Dynamic, Property.NodeScope); /** * An enum representation for the configured re-balance type. diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java index cab73958b75..fe6bf918dc2 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ConcurrentRebalanceAllocationDecider.java @@ -24,7 +24,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -45,7 +45,7 @@ public class ConcurrentRebalanceAllocationDecider extends AllocationDecider { public static final Setting CLUSTER_ROUTING_ALLOCATION_CLUSTER_CONCURRENT_REBALANCE_SETTING = Setting.intSetting("cluster.routing.allocation.cluster_concurrent_rebalance", 2, -1, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile int clusterConcurrentRebalance; @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java index e8b5a3dba04..dcb6080bd1e 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/DiskThresholdDecider.java @@ -38,7 +38,7 @@ import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.RatioValue; @@ -83,21 +83,21 @@ public class DiskThresholdDecider extends AllocationDecider { private volatile TimeValue rerouteInterval; public static final Setting CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING = - Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.boolSetting("cluster.routing.allocation.disk.threshold_enabled", true, Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING = new Setting<>("cluster.routing.allocation.disk.watermark.low", "85%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.low"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING = new Setting<>("cluster.routing.allocation.disk.watermark.high", "90%", (s) -> validWatermarkSetting(s, "cluster.routing.allocation.disk.watermark.high"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING = Setting.boolSetting("cluster.routing.allocation.disk.include_relocations", true, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope);; + Property.Dynamic, Property.NodeScope);; public static final Setting CLUSTER_ROUTING_ALLOCATION_REROUTE_INTERVAL_SETTING = Setting.positiveTimeSetting("cluster.routing.allocation.disk.reroute_interval", TimeValue.timeValueSeconds(60), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** * Listens for a node to go over the high watermark and kicks off an empty diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java index 0cca4cac480..80dada86022 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/EnableAllocationDecider.java @@ -26,7 +26,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.Locale; @@ -63,17 +63,17 @@ public class EnableAllocationDecider extends AllocationDecider { public static final Setting CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING = new Setting<>("cluster.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting INDEX_ROUTING_ALLOCATION_ENABLE_SETTING = new Setting<>("index.routing.allocation.enable", Allocation.ALL.name(), Allocation::parse, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting CLUSTER_ROUTING_REBALANCE_ENABLE_SETTING = new Setting<>("cluster.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting INDEX_ROUTING_REBALANCE_ENABLE_SETTING = new Setting<>("index.routing.rebalance.enable", Rebalance.ALL.name(), Rebalance::parse, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); private volatile Rebalance enableRebalance; private volatile Allocation enableAllocation; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java index b4c50d1849b..c3ff0bb355e 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java @@ -27,7 +27,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.AND; @@ -62,11 +62,11 @@ public class FilterAllocationDecider extends AllocationDecider { public static final String NAME = "filter"; public static final Setting CLUSTER_ROUTING_REQUIRE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.require.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.require.", Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_INCLUDE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.include.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.include.", Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING = - Setting.groupSetting("cluster.routing.allocation.exclude.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.groupSetting("cluster.routing.allocation.exclude.", Property.Dynamic, Property.NodeScope); private volatile DiscoveryNodeFilters clusterRequireFilters; private volatile DiscoveryNodeFilters clusterIncludeFilters; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java index 03a383830ce..ab8be4dc8da 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ShardsLimitAllocationDecider.java @@ -27,7 +27,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -62,7 +62,7 @@ public class ShardsLimitAllocationDecider extends AllocationDecider { */ public static final Setting INDEX_TOTAL_SHARDS_PER_NODE_SETTING = Setting.intSetting("index.routing.allocation.total_shards_per_node", -1, -1, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); /** * Controls the maximum number of shards per node on a global level. @@ -70,7 +70,7 @@ public class ShardsLimitAllocationDecider extends AllocationDecider { */ public static final Setting CLUSTER_TOTAL_SHARDS_PER_NODE_SETTING = Setting.intSetting("cluster.routing.allocation.total_shards_per_node", -1, -1, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); @Inject diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java index a9d269d3b3a..d656afc8036 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDecider.java @@ -26,7 +26,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -42,7 +42,7 @@ public class SnapshotInProgressAllocationDecider extends AllocationDecider { */ public static final Setting CLUSTER_ROUTING_ALLOCATION_SNAPSHOT_RELOCATION_ENABLED_SETTING = Setting.boolSetting("cluster.routing.allocation.snapshot.relocation_enabled", false, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile boolean enableRelocation = false; diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java index 64900236291..ca6b312da4c 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/ThrottlingAllocationDecider.java @@ -25,7 +25,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -55,21 +55,21 @@ public class ThrottlingAllocationDecider extends AllocationDecider { new Setting<>("cluster.routing.allocation.node_concurrent_recoveries", Integer.toString(DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_recoveries"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES_SETTING = Setting.intSetting("cluster.routing.allocation.node_initial_primaries_recoveries", DEFAULT_CLUSTER_ROUTING_ALLOCATION_NODE_INITIAL_PRIMARIES_RECOVERIES, 0, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_INCOMING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_incoming_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_incoming_recoveries"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_OUTGOING_RECOVERIES_SETTING = new Setting<>("cluster.routing.allocation.node_concurrent_outgoing_recoveries", (s) -> CLUSTER_ROUTING_ALLOCATION_NODE_CONCURRENT_RECOVERIES_SETTING.getRaw(s), (s) -> Setting.parseInt(s, 0, "cluster.routing.allocation.node_concurrent_outgoing_recoveries"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile int primariesInitialRecoveries; diff --git a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java index 84a7130e334..47b65d6864f 100644 --- a/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java +++ b/core/src/main/java/org/elasticsearch/cluster/service/InternalClusterService.java @@ -52,7 +52,7 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.transport.TransportAddress; @@ -99,14 +99,14 @@ public class InternalClusterService extends AbstractLifecycleComponent CLUSTER_SERVICE_SLOW_TASK_LOGGING_THRESHOLD_SETTING = Setting.positiveTimeSetting("cluster.service.slow_task_logging_threshold", TimeValue.timeValueSeconds(30), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting CLUSTER_SERVICE_RECONNECT_INTERVAL_SETTING = - Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("cluster.service.reconnect_interval", TimeValue.timeValueSeconds(10), Property.NodeScope); public static final String UPDATE_THREAD_NAME = "clusterService#updateTask"; public static final Setting NODE_ID_SEED_SETTING = // don't use node.id.seed so it won't be seen as an attribute - Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, SettingsProperty.ClusterScope); + Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, Property.NodeScope); private final ThreadPool threadPool; private BiConsumer clusterStatePublisher; diff --git a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java index dbf1644cbfe..c0951c47df1 100644 --- a/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java +++ b/core/src/main/java/org/elasticsearch/common/logging/ESLoggerFactory.java @@ -21,8 +21,7 @@ package org.elasticsearch.common.logging; import org.apache.log4j.Logger; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; -import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.Setting.Property; import java.util.Locale; @@ -32,10 +31,10 @@ import java.util.Locale; public abstract class ESLoggerFactory { public static final Setting LOG_DEFAULT_LEVEL_SETTING = - new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, SettingsProperty.ClusterScope); + new Setting<>("logger.level", LogLevel.INFO.name(), LogLevel::parse, Property.NodeScope); public static final Setting LOG_LEVEL_SETTING = Setting.prefixKeySetting("logger.", LogLevel.INFO.name(), LogLevel::parse, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static ESLogger getLogger(String prefix, String name) { prefix = prefix == null ? null : prefix.intern(); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java index c79e8dd3af5..1a54ad2753a 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkModule.java @@ -28,7 +28,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.http.HttpServer; @@ -155,11 +155,11 @@ public class NetworkModule extends AbstractModule { public static final String LOCAL_TRANSPORT = "local"; public static final String NETTY_TRANSPORT = "netty"; - public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", SettingsProperty.ClusterScope); - public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, SettingsProperty.ClusterScope); + public static final Setting HTTP_TYPE_SETTING = Setting.simpleString("http.type", Property.NodeScope); + public static final Setting HTTP_ENABLED = Setting.boolSetting("http.enabled", true, Property.NodeScope); public static final Setting TRANSPORT_SERVICE_TYPE_SETTING = - Setting.simpleString("transport.service.type", SettingsProperty.ClusterScope); - public static final Setting TRANSPORT_TYPE_SETTING = Setting.simpleString("transport.type", SettingsProperty.ClusterScope); + Setting.simpleString("transport.service.type", Property.NodeScope); + public static final Setting TRANSPORT_TYPE_SETTING = Setting.simpleString("transport.type", Property.NodeScope); diff --git a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java index 83f4f5fc88c..ff1f3912cc5 100644 --- a/core/src/main/java/org/elasticsearch/common/network/NetworkService.java +++ b/core/src/main/java/org/elasticsearch/common/network/NetworkService.java @@ -22,7 +22,7 @@ package org.elasticsearch.common.network; import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -46,32 +46,32 @@ public class NetworkService extends AbstractComponent { public static final String DEFAULT_NETWORK_HOST = "_local_"; public static final Setting> GLOBAL_NETWORK_HOST_SETTING = - Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("network.host", Arrays.asList(DEFAULT_NETWORK_HOST), Function.identity(), Property.NodeScope); public static final Setting> GLOBAL_NETWORK_BINDHOST_SETTING = - Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("network.bind_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), Property.NodeScope); public static final Setting> GLOBAL_NETWORK_PUBLISHHOST_SETTING = - Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), SettingsProperty.ClusterScope); - public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, SettingsProperty.ClusterScope); + Setting.listSetting("network.publish_host", GLOBAL_NETWORK_HOST_SETTING, Function.identity(), Property.NodeScope); + public static final Setting NETWORK_SERVER = Setting.boolSetting("network.server", true, Property.NodeScope); public static final class TcpSettings { public static final Setting TCP_NO_DELAY = - Setting.boolSetting("network.tcp.no_delay", true, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.no_delay", true, Property.NodeScope); public static final Setting TCP_KEEP_ALIVE = - Setting.boolSetting("network.tcp.keep_alive", true, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.keep_alive", true, Property.NodeScope); public static final Setting TCP_REUSE_ADDRESS = - Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.reuse_address", NetworkUtils.defaultReuseAddress(), Property.NodeScope); public static final Setting TCP_SEND_BUFFER_SIZE = - Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("network.tcp.send_buffer_size", new ByteSizeValue(-1), Property.NodeScope); public static final Setting TCP_RECEIVE_BUFFER_SIZE = - Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("network.tcp.receive_buffer_size", new ByteSizeValue(-1), Property.NodeScope); public static final Setting TCP_BLOCKING = - Setting.boolSetting("network.tcp.blocking", false, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking", false, Property.NodeScope); public static final Setting TCP_BLOCKING_SERVER = - Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking_server", TCP_BLOCKING, Property.NodeScope); public static final Setting TCP_BLOCKING_CLIENT = - Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, SettingsProperty.ClusterScope); + Setting.boolSetting("network.tcp.blocking_client", TCP_BLOCKING, Property.NodeScope); public static final Setting TCP_CONNECT_TIMEOUT = - Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), SettingsProperty.ClusterScope); + Setting.timeSetting("network.tcp.connect_timeout", new TimeValue(30, TimeUnit.SECONDS), Property.NodeScope); } /** diff --git a/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java index 63ee81c30b7..baed9c0849f 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java @@ -44,11 +44,11 @@ public abstract class AbstractScopedSettings extends AbstractComponent { private final List> settingUpdaters = new CopyOnWriteArrayList<>(); private final Map> complexMatchers; private final Map> keySettings; - private final Setting.SettingsProperty scope; + private final Setting.Property scope; private static final Pattern KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])*[-\\w]+$"); private static final Pattern GROUP_KEY_PATTERN = Pattern.compile("^(?:[-\\w]+[.])+$"); - protected AbstractScopedSettings(Settings settings, Set> settingsSet, Setting.SettingsProperty scope) { + protected AbstractScopedSettings(Settings settings, Set> settingsSet, Setting.Property scope) { super(settings); this.lastSettingsApplied = Settings.EMPTY; this.scope = scope; @@ -96,7 +96,7 @@ public abstract class AbstractScopedSettings extends AbstractComponent { return GROUP_KEY_PATTERN.matcher(key).matches(); } - public Setting.SettingsProperty getScope() { + public Setting.Property getScope() { return this.scope; } diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index 888902fff68..45f58390b58 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -45,7 +45,7 @@ import org.elasticsearch.cluster.service.InternalClusterService; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.network.NetworkService; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.discovery.DiscoveryModule; @@ -102,7 +102,7 @@ import java.util.function.Predicate; */ public final class ClusterSettings extends AbstractScopedSettings { public ClusterSettings(Settings nodeSettings, Set> settingsSet) { - super(nodeSettings, settingsSet, SettingsProperty.ClusterScope); + super(nodeSettings, settingsSet, Property.NodeScope); addSettingsUpdater(new LoggingSettingUpdater(nodeSettings)); } diff --git a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index ae056460cd8..ae88f513c65 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -22,7 +22,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.routing.UnassignedInfo; import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.gateway.PrimaryShardAllocator; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; @@ -50,7 +50,7 @@ import java.util.function.Predicate; /** * Encapsulates all valid index level settings. - * @see org.elasticsearch.common.settings.Setting.SettingsProperty#IndexScope + * @see Property#IndexScope */ public final class IndexScopedSettings extends AbstractScopedSettings { @@ -135,15 +135,15 @@ public final class IndexScopedSettings extends AbstractScopedSettings { EngineConfig.INDEX_CODEC_SETTING, IndexWarmer.INDEX_NORMS_LOADING_SETTING, // this sucks but we can't really validate all the analyzers/similarity in here - Setting.groupSetting("index.similarity.", SettingsProperty.IndexScope), // this allows similarity settings to be passed - Setting.groupSetting("index.analysis.", SettingsProperty.IndexScope) // this allows analysis settings to be passed + Setting.groupSetting("index.similarity.", Property.IndexScope), // this allows similarity settings to be passed + Setting.groupSetting("index.analysis.", Property.IndexScope) // this allows analysis settings to be passed ))); public static final IndexScopedSettings DEFAULT_SCOPED_SETTINGS = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS); public IndexScopedSettings(Settings settings, Set> settingsSet) { - super(settings, settingsSet, SettingsProperty.IndexScope); + super(settings, settingsSet, Property.IndexScope); } private IndexScopedSettings(Settings settings, IndexScopedSettings other, IndexMetaData metaData) { diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java index c6753d243c0..7464e06c179 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java @@ -54,7 +54,7 @@ import java.util.stream.Collectors; * together with {@link AbstractScopedSettings}. This class contains several utility methods that makes it straight forward * to add settings for the majority of the cases. For instance a simple boolean settings can be defined like this: *
{@code
- * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, SettingsProperty.ClusterScope);}
+ * public static final Setting; MY_BOOLEAN = Setting.boolSetting("my.bool.setting", true, SettingsProperty.NodeScope);}
  * 
* To retrieve the value of the setting a {@link Settings} object can be passed directly to the {@link Setting#get(Settings)} method. *
@@ -66,13 +66,13 @@ import java.util.stream.Collectors;
  *     RED, GREEN, BLUE;
  * }
  * public static final Setting MY_BOOLEAN =
- *     new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, SettingsProperty.ClusterScope);
+ *     new Setting<>("my.color.setting", Color.RED.toString(), Color::valueOf, SettingsProperty.NodeScope);
  * }
  * 
*/ public class Setting extends ToXContentToBytes { - public enum SettingsProperty { + public enum Property { /** * should be filtered in some api (mask password/credentials) */ @@ -89,25 +89,14 @@ public class Setting extends ToXContentToBytes { Deprecated, /** - * Cluster scope. - * @See IndexScope - * @See NodeScope - */ - ClusterScope, - - /** - * Node scope. - * @See ClusterScope - * @See IndexScope + * Node scope */ NodeScope, /** - * Index scope. - * @See ClusterScope - * @See NodeScope + * Index scope */ - IndexScope; + IndexScope } private static final ESLogger logger = Loggers.getLogger(Setting.class); @@ -116,31 +105,30 @@ public class Setting extends ToXContentToBytes { private final Key key; protected final Function defaultValue; private final Function parser; - private final EnumSet properties; + private final EnumSet properties; /** - * Creates a new Setting instance + * Creates a new Setting instance. When no scope is provided, we default to {@link Property#NodeScope}. * @param key the settings key for this setting. * @param defaultValue a default value function that returns the default values string representation. * @param parser a parser that parses the string rep into a complex datatype. * @param properties properties for this setting like scope, filtering... */ - public Setting(Key key, Function defaultValue, Function parser, SettingsProperty... properties) { + public Setting(Key key, Function defaultValue, Function parser, Property... properties) { assert parser.apply(defaultValue.apply(Settings.EMPTY)) != null || this.isGroupSetting(): "parser returned null"; this.key = key; this.defaultValue = defaultValue; this.parser = parser; if (properties.length == 0) { - this.properties = EnumSet.of(SettingsProperty.NodeScope); + this.properties = EnumSet.of(Property.NodeScope); } else { this.properties = EnumSet.copyOf(Arrays.asList(properties)); } // We validate scope settings. They are mutually exclusive int numScopes = 0; - for (SettingsProperty property : properties) { - if (property == SettingsProperty.ClusterScope || - property == SettingsProperty.IndexScope || - property == SettingsProperty.NodeScope) { + for (Property property : properties) { + if (property == Property.NodeScope || + property == Property.IndexScope) { numScopes++; } } @@ -156,7 +144,7 @@ public class Setting extends ToXContentToBytes { * @param parser a parser that parses the string rep into a complex datatype. * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, String defaultValue, Function parser, SettingsProperty... properties) { + public Setting(String key, String defaultValue, Function parser, Property... properties) { this(key, s -> defaultValue, parser, properties); } @@ -167,7 +155,7 @@ public class Setting extends ToXContentToBytes { * @param parser a parser that parses the string rep into a complex datatype. * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Function defaultValue, Function parser, SettingsProperty... properties) { + public Setting(String key, Function defaultValue, Function parser, Property... properties) { this(new SimpleKey(key), defaultValue, parser, properties); } @@ -178,7 +166,7 @@ public class Setting extends ToXContentToBytes { * @param parser a parser that parses the string rep into a complex datatype. * @param properties properties for this setting like scope, filtering... */ - public Setting(String key, Setting fallBackSetting, Function parser, SettingsProperty... properties) { + public Setting(String key, Setting fallBackSetting, Function parser, Property... properties) { this(key, fallBackSetting::getRaw, parser, properties); } @@ -204,14 +192,14 @@ public class Setting extends ToXContentToBytes { * Returns true if this setting is dynamically updateable, otherwise false */ public final boolean isDynamic() { - return properties.contains(SettingsProperty.Dynamic); + return properties.contains(Property.Dynamic); } /** * Returns the setting properties - * @see SettingsProperty + * @see Property */ - public EnumSet getProperties() { + public EnumSet getProperties() { return properties; } @@ -219,35 +207,28 @@ public class Setting extends ToXContentToBytes { * Returns true if this setting must be filtered, otherwise false */ public boolean isFiltered() { - return properties.contains(SettingsProperty.Filtered); + return properties.contains(Property.Filtered); } /** - * Returns true if this setting has a cluster scope, otherwise false + * Returns true if this setting has a node scope, otherwise false */ - public boolean hasClusterScope() { - return properties.contains(SettingsProperty.ClusterScope); + public boolean hasNodeScope() { + return properties.contains(Property.NodeScope); } /** * Returns true if this setting has an index scope, otherwise false */ public boolean hasIndexScope() { - return properties.contains(SettingsProperty.IndexScope); - } - - /** - * Returns true if this setting has an index scope, otherwise false - */ - public boolean hasNodeScope() { - return properties.contains(SettingsProperty.NodeScope); + return properties.contains(Property.IndexScope); } /** * Returns true if this setting is deprecated, otherwise false */ public boolean isDeprecated() { - return properties.contains(SettingsProperty.Deprecated); + return properties.contains(Property.Deprecated); } /** @@ -451,11 +432,11 @@ public class Setting extends ToXContentToBytes { } - public static Setting floatSetting(String key, float defaultValue, SettingsProperty... properties) { + public static Setting floatSetting(String key, float defaultValue, Property... properties) { return new Setting<>(key, (s) -> Float.toString(defaultValue), Float::parseFloat, properties); } - public static Setting floatSetting(String key, float defaultValue, float minValue, SettingsProperty... properties) { + public static Setting floatSetting(String key, float defaultValue, float minValue, Property... properties) { return new Setting<>(key, (s) -> Float.toString(defaultValue), (s) -> { float value = Float.parseFloat(s); if (value < minValue) { @@ -465,19 +446,19 @@ public class Setting extends ToXContentToBytes { }, properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, SettingsProperty... properties) { + public static Setting intSetting(String key, int defaultValue, int minValue, int maxValue, Property... properties) { return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, maxValue, key), properties); } - public static Setting intSetting(String key, int defaultValue, int minValue, SettingsProperty... properties) { + public static Setting intSetting(String key, int defaultValue, int minValue, Property... properties) { return new Setting<>(key, (s) -> Integer.toString(defaultValue), (s) -> parseInt(s, minValue, key), properties); } - public static Setting longSetting(String key, long defaultValue, long minValue, SettingsProperty... properties) { + public static Setting longSetting(String key, long defaultValue, long minValue, Property... properties) { return new Setting<>(key, (s) -> Long.toString(defaultValue), (s) -> parseLong(s, minValue, key), properties); } - public static Setting simpleString(String key, SettingsProperty... properties) { + public static Setting simpleString(String key, Property... properties) { return new Setting<>(key, s -> "", Function.identity(), properties); } @@ -512,52 +493,52 @@ public class Setting extends ToXContentToBytes { return timeValue; } - public static Setting intSetting(String key, int defaultValue, SettingsProperty... properties) { + public static Setting intSetting(String key, int defaultValue, Property... properties) { return intSetting(key, defaultValue, Integer.MIN_VALUE, properties); } - public static Setting boolSetting(String key, boolean defaultValue, SettingsProperty... properties) { + public static Setting boolSetting(String key, boolean defaultValue, Property... properties) { return new Setting<>(key, (s) -> Boolean.toString(defaultValue), Booleans::parseBooleanExact, properties); } - public static Setting boolSetting(String key, Setting fallbackSetting, SettingsProperty... properties) { + public static Setting boolSetting(String key, Setting fallbackSetting, Property... properties) { return new Setting<>(key, fallbackSetting, Booleans::parseBooleanExact, properties); } - public static Setting byteSizeSetting(String key, String percentage, SettingsProperty... properties) { + public static Setting byteSizeSetting(String key, String percentage, Property... properties) { return new Setting<>(key, (s) -> percentage, (s) -> MemorySizeValue.parseBytesSizeValueOrHeapRatio(s, key), properties); } - public static Setting byteSizeSetting(String key, ByteSizeValue value, SettingsProperty... properties) { + public static Setting byteSizeSetting(String key, ByteSizeValue value, Property... properties) { return byteSizeSetting(key, (s) -> value.toString(), properties); } public static Setting byteSizeSetting(String key, Setting fallbackSettings, - SettingsProperty... properties) { + Property... properties) { return byteSizeSetting(key, fallbackSettings::getRaw, properties); } public static Setting byteSizeSetting(String key, Function defaultValue, - SettingsProperty... properties) { + Property... properties) { return new Setting<>(key, defaultValue, (s) -> ByteSizeValue.parseBytesSizeValue(s, key), properties); } - public static Setting positiveTimeSetting(String key, TimeValue defaultValue, SettingsProperty... properties) { + public static Setting positiveTimeSetting(String key, TimeValue defaultValue, Property... properties) { return timeSetting(key, defaultValue, TimeValue.timeValueMillis(0), properties); } public static Setting> listSetting(String key, List defaultStringValue, Function singleValueParser, - SettingsProperty... properties) { + Property... properties) { return listSetting(key, (s) -> defaultStringValue, singleValueParser, properties); } public static Setting> listSetting(String key, Setting> fallbackSetting, Function singleValueParser, - SettingsProperty... properties) { + Property... properties) { return listSetting(key, (s) -> parseableStringToList(fallbackSetting.getRaw(s)), singleValueParser, properties); } public static Setting> listSetting(String key, Function> defaultStringValue, - Function singleValueParser, SettingsProperty... properties) { + Function singleValueParser, Property... properties) { Function> parser = (s) -> parseableStringToList(s).stream().map(singleValueParser).collect(Collectors.toList()); @@ -611,7 +592,7 @@ public class Setting extends ToXContentToBytes { } } - public static Setting groupSetting(String key, SettingsProperty... properties) { + public static Setting groupSetting(String key, Property... properties) { // TODO CHECK IF WE REMOVE if (key.endsWith(".") == false) { throw new IllegalArgumentException("key must end with a '.'"); @@ -671,7 +652,7 @@ public class Setting extends ToXContentToBytes { } public static Setting timeSetting(String key, Function defaultValue, TimeValue minValue, - SettingsProperty... properties) { + Property... properties) { return new Setting<>(key, defaultValue, (s) -> { TimeValue timeValue = TimeValue.parseTimeValue(s, null, key); if (timeValue.millis() < minValue.millis()) { @@ -681,19 +662,19 @@ public class Setting extends ToXContentToBytes { }, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, SettingsProperty... properties) { + public static Setting timeSetting(String key, TimeValue defaultValue, TimeValue minValue, Property... properties) { return timeSetting(key, (s) -> defaultValue.getStringRep(), minValue, properties); } - public static Setting timeSetting(String key, TimeValue defaultValue, SettingsProperty... properties) { + public static Setting timeSetting(String key, TimeValue defaultValue, Property... properties) { return new Setting<>(key, (s) -> defaultValue.toString(), (s) -> TimeValue.parseTimeValue(s, key), properties); } - public static Setting timeSetting(String key, Setting fallbackSetting, SettingsProperty... properties) { + public static Setting timeSetting(String key, Setting fallbackSetting, Property... properties) { return new Setting<>(key, fallbackSetting::getRaw, (s) -> TimeValue.parseTimeValue(s, key), properties); } - public static Setting doubleSetting(String key, double defaultValue, double minValue, SettingsProperty... properties) { + public static Setting doubleSetting(String key, double defaultValue, double minValue, Property... properties) { return new Setting<>(key, (s) -> Double.toString(defaultValue), (s) -> { final double d = Double.parseDouble(s); if (d < minValue) { @@ -722,7 +703,7 @@ public class Setting extends ToXContentToBytes { * {@link #getConcreteSetting(String)} is used to pull the updater. */ public static Setting prefixKeySetting(String prefix, String defaultValue, Function parser, - SettingsProperty... properties) { + Property... properties) { return affixKeySetting(AffixKey.withPrefix(prefix), (s) -> defaultValue, parser, properties); } @@ -732,17 +713,17 @@ public class Setting extends ToXContentToBytes { * out of the box unless {@link #getConcreteSetting(String)} is used to pull the updater. */ public static Setting adfixKeySetting(String prefix, String suffix, Function defaultValue, - Function parser, SettingsProperty... properties) { + Function parser, Property... properties) { return affixKeySetting(AffixKey.withAdfix(prefix, suffix), defaultValue, parser, properties); } public static Setting adfixKeySetting(String prefix, String suffix, String defaultValue, Function parser, - SettingsProperty... properties) { + Property... properties) { return adfixKeySetting(prefix, suffix, (s) -> defaultValue, parser, properties); } public static Setting affixKeySetting(AffixKey key, Function defaultValue, Function parser, - SettingsProperty... properties) { + Property... properties) { return new Setting(key, defaultValue, parser, properties) { @Override diff --git a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java index 8786ac5f447..ee770f74756 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java +++ b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java @@ -35,7 +35,7 @@ public class SettingsModule extends AbstractModule { private final Settings settings; private final Set settingsFilterPattern = new HashSet<>(); - private final Map> clusterSettings = new HashMap<>(); + private final Map> nodeSettings = new HashMap<>(); private final Map> indexSettings = new HashMap<>(); private static final Predicate TRIBE_CLIENT_NODE_SETTINGS_PREDICATE = (s) -> s.startsWith("tribe.") && TribeService.TRIBE_SETTING_KEYS.contains(s) == false; @@ -52,7 +52,7 @@ public class SettingsModule extends AbstractModule { @Override protected void configure() { final IndexScopedSettings indexScopedSettings = new IndexScopedSettings(settings, new HashSet<>(this.indexSettings.values())); - final ClusterSettings clusterSettings = new ClusterSettings(settings, new HashSet<>(this.clusterSettings.values())); + final ClusterSettings clusterSettings = new ClusterSettings(settings, new HashSet<>(this.nodeSettings.values())); // by now we are fully configured, lets check node level settings for unregistered index settings indexScopedSettings.validate(settings.filter(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE)); final Predicate acceptOnlyClusterSettings = TRIBE_CLIENT_NODE_SETTINGS_PREDICATE.or(IndexScopedSettings.INDEX_SETTINGS_KEY_PREDICATE).negate(); @@ -76,17 +76,18 @@ public class SettingsModule extends AbstractModule { registerSettingsFilter(setting.getKey()); } } - if (setting.hasClusterScope()) { - if (clusterSettings.containsKey(setting.getKey())) { + if (setting.hasNodeScope()) { + if (nodeSettings.containsKey(setting.getKey())) { throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); } - clusterSettings.put(setting.getKey(), setting); - } - if (setting.hasIndexScope()) { + nodeSettings.put(setting.getKey(), setting); + } else if (setting.hasIndexScope()) { if (indexSettings.containsKey(setting.getKey())) { throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice"); } indexSettings.put(setting.getKey(), setting); + } else { + throw new IllegalArgumentException("No scope found for setting [" + setting.getKey() + "]"); } } @@ -108,8 +109,8 @@ public class SettingsModule extends AbstractModule { * Check if a setting has already been registered */ public boolean exists(Setting setting) { - if (setting.hasClusterScope()) { - return clusterSettings.containsKey(setting.getKey()); + if (setting.hasNodeScope()) { + return nodeSettings.containsKey(setting.getKey()); } if (setting.hasIndexScope()) { return indexSettings.containsKey(setting.getKey()); diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java index 7f4e9c8b6d1..df1288d4fd2 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java @@ -20,7 +20,7 @@ package org.elasticsearch.common.util.concurrent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.Arrays; @@ -43,7 +43,7 @@ public class EsExecutors { * This is used to adjust thread pools sizes etc. per node. */ public static final Setting PROCESSORS_SETTING = - Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, SettingsProperty.ClusterScope); + Setting.intSetting("processors", Math.min(32, Runtime.getRuntime().availableProcessors()), 1, Property.NodeScope); /** * Returns the number of processors available but at most 32. diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java index 47c115a47e0..2ac6082e85d 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java @@ -19,12 +19,11 @@ package org.elasticsearch.common.util.concurrent; import org.apache.lucene.util.CloseableThreadLocal; -import org.elasticsearch.common.collect.Iterators; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.io.Closeable; @@ -64,7 +63,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class ThreadContext implements Closeable, Writeable{ public static final String PREFIX = "request.headers"; - public static final Setting DEFAULT_HEADERS_SETTING = Setting.groupSetting(PREFIX + ".", SettingsProperty.ClusterScope); + public static final Setting DEFAULT_HEADERS_SETTING = Setting.groupSetting(PREFIX + ".", Property.NodeScope); private final Map defaultHeader; private static final ThreadContextStruct DEFAULT_CONTEXT = new ThreadContextStruct(Collections.emptyMap()); private final ContextThreadLocal threadLocal; diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java index fa5c0e950ed..4076b880d6f 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoveryModule.java @@ -23,7 +23,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.multibindings.Multibinder; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ExtensionPoint; import org.elasticsearch.discovery.local.LocalDiscovery; @@ -48,9 +48,9 @@ public class DiscoveryModule extends AbstractModule { public static final Setting DISCOVERY_TYPE_SETTING = new Setting<>("discovery.type", settings -> DiscoveryNode.localNode(settings) ? "local" : "zen", Function.identity(), - SettingsProperty.ClusterScope); + Property.NodeScope); public static final Setting ZEN_MASTER_SERVICE_TYPE_SETTING = - new Setting<>("discovery.zen.masterservice.type", "zen", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("discovery.zen.masterservice.type", "zen", Function.identity(), Property.NodeScope); private final Settings settings; private final Map>> unicastHostProviders = new HashMap<>(); diff --git a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java index 9cf78cf93e5..ca7ab342cd5 100644 --- a/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java +++ b/core/src/main/java/org/elasticsearch/discovery/DiscoverySettings.java @@ -24,7 +24,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.rest.RestStatus; @@ -45,7 +45,7 @@ public class DiscoverySettings extends AbstractComponent { **/ public static final Setting PUBLISH_TIMEOUT_SETTING = Setting.positiveTimeSetting("discovery.zen.publish_timeout", TimeValue.timeValueSeconds(30), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** * sets the timeout for receiving enough acks for a specific cluster state and committing it. failing @@ -54,14 +54,14 @@ public class DiscoverySettings extends AbstractComponent { public static final Setting COMMIT_TIMEOUT_SETTING = new Setting<>("discovery.zen.commit_timeout", (s) -> PUBLISH_TIMEOUT_SETTING.getRaw(s), (s) -> TimeValue.parseTimeValue(s, TimeValue.timeValueSeconds(30), "discovery.zen.commit_timeout"), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting NO_MASTER_BLOCK_SETTING = new Setting<>("discovery.zen.no_master_block", "write", DiscoverySettings::parseNoMasterBlock, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final Setting PUBLISH_DIFF_ENABLE_SETTING = - Setting.boolSetting("discovery.zen.publish_diff.enable", true, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.publish_diff.enable", true, Property.Dynamic, Property.NodeScope); public static final Setting INITIAL_STATE_TIMEOUT_SETTING = - Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.initial_state_timeout", TimeValue.timeValueSeconds(30), Property.NodeScope); private volatile ClusterBlock noMasterBlock; private volatile TimeValue publishTimeout; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java index f0a491f2821..63a0cfbe39d 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ZenDiscovery.java @@ -46,7 +46,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.Discovery; @@ -89,27 +89,27 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; public class ZenDiscovery extends AbstractLifecycleComponent implements Discovery, PingContextProvider { public final static Setting PING_TIMEOUT_SETTING = - Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.ping_timeout", timeValueSeconds(3), Property.NodeScope); public final static Setting JOIN_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.join_timeout", settings -> TimeValue.timeValueMillis(PING_TIMEOUT_SETTING.get(settings).millis() * 20).toString(), - TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); + TimeValue.timeValueMillis(0), Property.NodeScope); public final static Setting JOIN_RETRY_ATTEMPTS_SETTING = - Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.join_retry_attempts", 3, 1, Property.NodeScope); public final static Setting JOIN_RETRY_DELAY_SETTING = - Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.join_retry_delay", TimeValue.timeValueMillis(100), Property.NodeScope); public final static Setting MAX_PINGS_FROM_ANOTHER_MASTER_SETTING = - Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.max_pings_from_another_master", 3, 1, Property.NodeScope); public final static Setting SEND_LEAVE_REQUEST_SETTING = - Setting.boolSetting("discovery.zen.send_leave_request", true, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.send_leave_request", true, Property.NodeScope); public final static Setting MASTER_ELECTION_FILTER_CLIENT_SETTING = - Setting.boolSetting("discovery.zen.master_election.filter_client", true, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.master_election.filter_client", true, Property.NodeScope); public final static Setting MASTER_ELECTION_WAIT_FOR_JOINS_TIMEOUT_SETTING = Setting.timeSetting("discovery.zen.master_election.wait_for_joins_timeout", settings -> TimeValue.timeValueMillis(JOIN_TIMEOUT_SETTING.get(settings).millis() / 2).toString(), TimeValue.timeValueMillis(0), - SettingsProperty.ClusterScope); + Property.NodeScope); public final static Setting MASTER_ELECTION_FILTER_DATA_SETTING = - Setting.boolSetting("discovery.zen.master_election.filter_data", false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.master_election.filter_data", false, Property.NodeScope); public static final String DISCOVERY_REJOIN_ACTION_NAME = "internal:discovery/zen/rejoin"; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java index 8a35c6615e7..a3da8be5a94 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/elect/ElectMasterService.java @@ -26,7 +26,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; @@ -42,7 +42,7 @@ import java.util.List; public class ElectMasterService extends AbstractComponent { public static final Setting DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING = - Setting.intSetting("discovery.zen.minimum_master_nodes", -1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.minimum_master_nodes", -1, Property.Dynamic, Property.NodeScope); // This is the minimum version a master needs to be on, otherwise it gets ignored // This is based on the minimum compatible version of the current version this node is on diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java index 6fc575d51cd..1cfd46634a5 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/fd/FaultDetection.java @@ -22,7 +22,7 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.threadpool.ThreadPool; @@ -38,15 +38,15 @@ import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; public abstract class FaultDetection extends AbstractComponent { public static final Setting CONNECT_ON_NETWORK_DISCONNECT_SETTING = - Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.fd.connect_on_network_disconnect", false, Property.NodeScope); public static final Setting PING_INTERVAL_SETTING = - Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.zen.fd.ping_interval", timeValueSeconds(1), Property.NodeScope); public static final Setting PING_TIMEOUT_SETTING = - Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), SettingsProperty.ClusterScope); + Setting.timeSetting("discovery.zen.fd.ping_timeout", timeValueSeconds(30), Property.NodeScope); public static final Setting PING_RETRIES_SETTING = - Setting.intSetting("discovery.zen.fd.ping_retries", 3, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.fd.ping_retries", 3, Property.NodeScope); public static final Setting REGISTER_CONNECTION_LISTENER_SETTING = - Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.zen.fd.register_connection_listener", true, Property.NodeScope); protected final ThreadPool threadPool; protected final ClusterName clusterName; diff --git a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java index 35e5688f2aa..0e9b81ad1fc 100644 --- a/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java +++ b/core/src/main/java/org/elasticsearch/discovery/zen/ping/unicast/UnicastZenPing.java @@ -32,7 +32,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -89,9 +89,9 @@ public class UnicastZenPing extends AbstractLifecycleComponent implemen public static final String ACTION_NAME = "internal:discovery/zen/unicast"; public static final Setting> DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING = Setting.listSetting("discovery.zen.ping.unicast.hosts", Collections.emptyList(), Function.identity(), - SettingsProperty.ClusterScope); + Property.NodeScope); public static final Setting DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING = - Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, SettingsProperty.ClusterScope); + Setting.intSetting("discovery.zen.ping.unicast.concurrent_connects", 10, 0, Property.NodeScope); // these limits are per-address public static final int LIMIT_FOREIGN_PORTS_COUNT = 1; diff --git a/core/src/main/java/org/elasticsearch/env/Environment.java b/core/src/main/java/org/elasticsearch/env/Environment.java index 0e0ab1ace20..e022ce6ad2f 100644 --- a/core/src/main/java/org/elasticsearch/env/Environment.java +++ b/core/src/main/java/org/elasticsearch/env/Environment.java @@ -23,7 +23,7 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.io.IOException; @@ -47,17 +47,17 @@ import static org.elasticsearch.common.Strings.cleanPath; // TODO: move PathUtils to be package-private here instead of // public+forbidden api! public class Environment { - public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", SettingsProperty.ClusterScope); - public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", SettingsProperty.ClusterScope); - public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", SettingsProperty.ClusterScope); + public static final Setting PATH_HOME_SETTING = Setting.simpleString("path.home", Property.NodeScope); + public static final Setting PATH_CONF_SETTING = Setting.simpleString("path.conf", Property.NodeScope); + public static final Setting PATH_SCRIPTS_SETTING = Setting.simpleString("path.scripts", Property.NodeScope); public static final Setting> PATH_DATA_SETTING = - Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); - public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", SettingsProperty.ClusterScope); - public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", SettingsProperty.ClusterScope); + Setting.listSetting("path.data", Collections.emptyList(), Function.identity(), Property.NodeScope); + public static final Setting PATH_LOGS_SETTING = Setting.simpleString("path.logs", Property.NodeScope); + public static final Setting PATH_PLUGINS_SETTING = Setting.simpleString("path.plugins", Property.NodeScope); public static final Setting> PATH_REPO_SETTING = - Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); - public static final Setting PATH_SHARED_DATA_SETTING = Setting.simpleString("path.shared_data", SettingsProperty.ClusterScope); - public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", SettingsProperty.ClusterScope); + Setting.listSetting("path.repo", Collections.emptyList(), Function.identity(), Property.NodeScope); + public static final Setting PATH_SHARED_DATA_SETTING = Setting.simpleString("path.shared_data", Property.NodeScope); + public static final Setting PIDFILE_SETTING = Setting.simpleString("pidfile", Property.NodeScope); private final Settings settings; diff --git a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java index e93a835db36..b4b69e6ca1b 100644 --- a/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java +++ b/core/src/main/java/org/elasticsearch/env/NodeEnvironment.java @@ -36,7 +36,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -49,7 +49,6 @@ import org.elasticsearch.index.store.FsDirectoryService; import org.elasticsearch.monitor.fs.FsInfo; import org.elasticsearch.monitor.fs.FsProbe; import org.elasticsearch.monitor.jvm.JvmInfo; -import org.elasticsearch.monitor.process.ProcessProbe; import java.io.Closeable; import java.io.IOException; @@ -138,19 +137,19 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl * Maximum number of data nodes that should run in an environment. */ public static final Setting MAX_LOCAL_STORAGE_NODES_SETTING = Setting.intSetting("node.max_local_storage_nodes", 50, 1, - SettingsProperty.ClusterScope); + Property.NodeScope); /** * If true automatically append node id to custom data paths. */ public static final Setting ADD_NODE_ID_TO_CUSTOM_PATH = - Setting.boolSetting("node.add_id_to_custom_path", true, SettingsProperty.ClusterScope); + Setting.boolSetting("node.add_id_to_custom_path", true, Property.NodeScope); /** * If true the [verbose] SegmentInfos.infoStream logging is sent to System.out. */ public static final Setting ENABLE_LUCENE_SEGMENT_INFOS_TRACE_SETTING = - Setting.boolSetting("node.enable_lucene_segment_infos_trace", false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.enable_lucene_segment_infos_trace", false, Property.NodeScope); public static final String NODES_FOLDER = "nodes"; public static final String INDICES_FOLDER = "indices"; @@ -225,7 +224,7 @@ public final class NodeEnvironment extends AbstractComponent implements Closeabl maybeLogPathDetails(); maybeLogHeapDetails(); - + applySegmentInfosTrace(settings); assertCanWrite(); success = true; diff --git a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java index 2f7eeac6b0b..1a5424d0f07 100644 --- a/core/src/main/java/org/elasticsearch/gateway/GatewayService.java +++ b/core/src/main/java/org/elasticsearch/gateway/GatewayService.java @@ -37,7 +37,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.Discovery; @@ -53,19 +53,19 @@ import java.util.concurrent.atomic.AtomicBoolean; public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener { public static final Setting EXPECTED_NODES_SETTING = - Setting.intSetting("gateway.expected_nodes", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_nodes", -1, -1, Property.NodeScope); public static final Setting EXPECTED_DATA_NODES_SETTING = - Setting.intSetting("gateway.expected_data_nodes", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_data_nodes", -1, -1, Property.NodeScope); public static final Setting EXPECTED_MASTER_NODES_SETTING = - Setting.intSetting("gateway.expected_master_nodes", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.expected_master_nodes", -1, -1, Property.NodeScope); public static final Setting RECOVER_AFTER_TIME_SETTING = - Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("gateway.recover_after_time", TimeValue.timeValueMillis(0), Property.NodeScope); public static final Setting RECOVER_AFTER_NODES_SETTING = - Setting.intSetting("gateway.recover_after_nodes", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_nodes", -1, -1, Property.NodeScope); public static final Setting RECOVER_AFTER_DATA_NODES_SETTING = - Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_data_nodes", -1, -1, Property.NodeScope); public static final Setting RECOVER_AFTER_MASTER_NODES_SETTING = - Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, SettingsProperty.ClusterScope); + Setting.intSetting("gateway.recover_after_master_nodes", 0, 0, Property.NodeScope); public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); diff --git a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java index 6a37a0a7d25..5f6e50d6fc9 100644 --- a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java @@ -31,7 +31,7 @@ import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.gateway.TransportNodesListGatewayStartedShards.NodeGatewayStartedShards; import org.elasticsearch.index.shard.ShardStateMetaData; @@ -70,11 +70,11 @@ public abstract class PrimaryShardAllocator extends AbstractComponent { public static final Setting NODE_INITIAL_SHARDS_SETTING = new Setting<>("gateway.initial_shards", (settings) -> settings.get("gateway.local.initial_shards", "quorum"), INITIAL_SHARDS_PARSER, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); @Deprecated public static final Setting INDEX_RECOVERY_INITIAL_SHARDS_SETTING = new Setting<>("index.recovery.initial_shards", (settings) -> NODE_INITIAL_SHARDS_SETTING.get(settings) , INITIAL_SHARDS_PARSER, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public PrimaryShardAllocator(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java index b1b29eae60c..48af1c83965 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java +++ b/core/src/main/java/org/elasticsearch/http/HttpTransportSettings.java @@ -20,7 +20,7 @@ package org.elasticsearch.http; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.transport.PortsRange; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -34,50 +34,50 @@ import static org.elasticsearch.common.settings.Setting.listSetting; public final class HttpTransportSettings { public static final Setting SETTING_CORS_ENABLED = - Setting.boolSetting("http.cors.enabled", false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.cors.enabled", false, Property.NodeScope); public static final Setting SETTING_CORS_ALLOW_ORIGIN = - new Setting("http.cors.allow-origin", "", (value) -> value, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-origin", "", (value) -> value, Property.NodeScope); public static final Setting SETTING_CORS_MAX_AGE = - Setting.intSetting("http.cors.max-age", 1728000, SettingsProperty.ClusterScope); + Setting.intSetting("http.cors.max-age", 1728000, Property.NodeScope); public static final Setting SETTING_CORS_ALLOW_METHODS = - new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE", (value) -> value, Property.NodeScope); public static final Setting SETTING_CORS_ALLOW_HEADERS = - new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, SettingsProperty.ClusterScope); + new Setting("http.cors.allow-headers", "X-Requested-With, Content-Type, Content-Length", (value) -> value, Property.NodeScope); public static final Setting SETTING_CORS_ALLOW_CREDENTIALS = - Setting.boolSetting("http.cors.allow-credentials", false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.cors.allow-credentials", false, Property.NodeScope); public static final Setting SETTING_PIPELINING = - Setting.boolSetting("http.pipelining", true, SettingsProperty.ClusterScope); + Setting.boolSetting("http.pipelining", true, Property.NodeScope); public static final Setting SETTING_PIPELINING_MAX_EVENTS = - Setting.intSetting("http.pipelining.max_events", 10000, SettingsProperty.ClusterScope); + Setting.intSetting("http.pipelining.max_events", 10000, Property.NodeScope); public static final Setting SETTING_HTTP_COMPRESSION = - Setting.boolSetting("http.compression", false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.compression", false, Property.NodeScope); public static final Setting SETTING_HTTP_COMPRESSION_LEVEL = - Setting.intSetting("http.compression_level", 6, SettingsProperty.ClusterScope); + Setting.intSetting("http.compression_level", 6, Property.NodeScope); public static final Setting> SETTING_HTTP_HOST = - listSetting("http.host", emptyList(), Function.identity(), SettingsProperty.ClusterScope); + listSetting("http.host", emptyList(), Function.identity(), Property.NodeScope); public static final Setting> SETTING_HTTP_PUBLISH_HOST = - listSetting("http.publish_host", SETTING_HTTP_HOST, Function.identity(), SettingsProperty.ClusterScope); + listSetting("http.publish_host", SETTING_HTTP_HOST, Function.identity(), Property.NodeScope); public static final Setting> SETTING_HTTP_BIND_HOST = - listSetting("http.bind_host", SETTING_HTTP_HOST, Function.identity(), SettingsProperty.ClusterScope); + listSetting("http.bind_host", SETTING_HTTP_HOST, Function.identity(), Property.NodeScope); public static final Setting SETTING_HTTP_PORT = - new Setting("http.port", "9200-9300", PortsRange::new, SettingsProperty.ClusterScope); + new Setting("http.port", "9200-9300", PortsRange::new, Property.NodeScope); public static final Setting SETTING_HTTP_PUBLISH_PORT = - Setting.intSetting("http.publish_port", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("http.publish_port", -1, -1, Property.NodeScope); public static final Setting SETTING_HTTP_DETAILED_ERRORS_ENABLED = - Setting.boolSetting("http.detailed_errors.enabled", true, SettingsProperty.ClusterScope); + Setting.boolSetting("http.detailed_errors.enabled", true, Property.NodeScope); public static final Setting SETTING_HTTP_MAX_CONTENT_LENGTH = - Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_content_length", new ByteSizeValue(100, ByteSizeUnit.MB), Property.NodeScope); public static final Setting SETTING_HTTP_MAX_CHUNK_SIZE = - Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_chunk_size", new ByteSizeValue(8, ByteSizeUnit.KB), Property.NodeScope); public static final Setting SETTING_HTTP_MAX_HEADER_SIZE = - Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_header_size", new ByteSizeValue(8, ByteSizeUnit.KB), Property.NodeScope); public static final Setting SETTING_HTTP_MAX_INITIAL_LINE_LENGTH = - Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("http.max_initial_line_length", new ByteSizeValue(4, ByteSizeUnit.KB), Property.NodeScope); // don't reset cookies by default, since I don't think we really need to // note, parsing cookies was fixed in netty 3.5.1 regarding stack allocation, but still, currently, we don't need cookies public static final Setting SETTING_HTTP_RESET_COOKIES = - Setting.boolSetting("http.reset_cookies", false, SettingsProperty.ClusterScope); + Setting.boolSetting("http.reset_cookies", false, Property.NodeScope); private HttpTransportSettings() { } diff --git a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java index b072afc486d..525fe96e07f 100644 --- a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java +++ b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java @@ -29,7 +29,7 @@ import org.elasticsearch.common.netty.OpenChannelsHandler; import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -120,29 +120,29 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_MAX_CUMULATION_BUFFER_CAPACITY = Setting.byteSizeSetting("http.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), - SettingsProperty.ClusterScope); + Property.NodeScope); public static Setting SETTING_HTTP_NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = - Setting.intSetting("http.netty.max_composite_buffer_components", -1, SettingsProperty.ClusterScope); + Setting.intSetting("http.netty.max_composite_buffer_components", -1, Property.NodeScope); public static final Setting SETTING_HTTP_WORKER_COUNT = new Setting<>("http.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 1, "http.netty.worker_count"), Property.NodeScope); public static final Setting SETTING_HTTP_TCP_NO_DELAY = - boolSetting("http.tcp_no_delay", NetworkService.TcpSettings.TCP_NO_DELAY, SettingsProperty.ClusterScope); + boolSetting("http.tcp_no_delay", NetworkService.TcpSettings.TCP_NO_DELAY, Property.NodeScope); public static final Setting SETTING_HTTP_TCP_KEEP_ALIVE = - boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings.TCP_KEEP_ALIVE, SettingsProperty.ClusterScope); + boolSetting("http.tcp.keep_alive", NetworkService.TcpSettings.TCP_KEEP_ALIVE, Property.NodeScope); public static final Setting SETTING_HTTP_TCP_BLOCKING_SERVER = - boolSetting("http.tcp.blocking_server", NetworkService.TcpSettings.TCP_BLOCKING_SERVER, SettingsProperty.ClusterScope); + boolSetting("http.tcp.blocking_server", NetworkService.TcpSettings.TCP_BLOCKING_SERVER, Property.NodeScope); public static final Setting SETTING_HTTP_TCP_REUSE_ADDRESS = - boolSetting("http.tcp.reuse_address", NetworkService.TcpSettings.TCP_REUSE_ADDRESS, SettingsProperty.ClusterScope); + boolSetting("http.tcp.reuse_address", NetworkService.TcpSettings.TCP_REUSE_ADDRESS, Property.NodeScope); public static final Setting SETTING_HTTP_TCP_SEND_BUFFER_SIZE = Setting.byteSizeSetting("http.tcp.send_buffer_size", NetworkService.TcpSettings.TCP_SEND_BUFFER_SIZE, - SettingsProperty.ClusterScope); + Property.NodeScope); public static final Setting SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE = Setting.byteSizeSetting("http.tcp.receive_buffer_size", NetworkService.TcpSettings.TCP_RECEIVE_BUFFER_SIZE, - SettingsProperty.ClusterScope); + Property.NodeScope); public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting("transport.netty.receive_predictor_size", settings -> { @@ -154,11 +154,11 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MIN = - byteSizeSetting("http.netty.receive_predictor_min", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); + byteSizeSetting("http.netty.receive_predictor_min", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, Property.NodeScope); public static final Setting SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_MAX = - byteSizeSetting("http.netty.receive_predictor_max", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); + byteSizeSetting("http.netty.receive_predictor_max", SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE, Property.NodeScope); protected final NetworkService networkService; diff --git a/core/src/main/java/org/elasticsearch/index/IndexModule.java b/core/src/main/java/org/elasticsearch/index/IndexModule.java index 5c1217a863e..b6120bd9d78 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexModule.java +++ b/core/src/main/java/org/elasticsearch/index/IndexModule.java @@ -22,7 +22,7 @@ package org.elasticsearch.index; import org.apache.lucene.util.SetOnce; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.index.analysis.AnalysisRegistry; @@ -67,15 +67,15 @@ import java.util.function.Function; public final class IndexModule { public static final Setting INDEX_STORE_TYPE_SETTING = - new Setting<>("index.store.type", "", Function.identity(), SettingsProperty.IndexScope); + new Setting<>("index.store.type", "", Function.identity(), Property.IndexScope); public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity"; public static final String INDEX_QUERY_CACHE = "index"; public static final String NONE_QUERY_CACHE = "none"; public static final Setting INDEX_QUERY_CACHE_TYPE_SETTING = - new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), SettingsProperty.IndexScope); + new Setting<>("index.queries.cache.type", INDEX_QUERY_CACHE, Function.identity(), Property.IndexScope); // for test purposes only public static final Setting INDEX_QUERY_CACHE_EVERYTHING_SETTING = - Setting.boolSetting("index.queries.cache.everything", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.queries.cache.everything", false, Property.IndexScope); private final IndexSettings indexSettings; private final IndexStoreConfig indexStoreConfig; private final AnalysisRegistry analysisRegistry; diff --git a/core/src/main/java/org/elasticsearch/index/IndexSettings.java b/core/src/main/java/org/elasticsearch/index/IndexSettings.java index bb859f04652..b996e70b1e5 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/core/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -27,7 +27,7 @@ import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -51,25 +51,25 @@ import java.util.function.Predicate; public final class IndexSettings { public static final Setting DEFAULT_FIELD_SETTING = - new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), SettingsProperty.IndexScope); + new Setting<>("index.query.default_field", AllFieldMapper.NAME, Function.identity(), Property.IndexScope); public static final Setting QUERY_STRING_LENIENT_SETTING = - Setting.boolSetting("index.query_string.lenient", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.query_string.lenient", false, Property.IndexScope); public static final Setting QUERY_STRING_ANALYZE_WILDCARD = - Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.query.query_string.analyze_wildcard", false, Property.NodeScope); public static final Setting QUERY_STRING_ALLOW_LEADING_WILDCARD = - Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.query.query_string.allowLeadingWildcard", true, Property.NodeScope); public static final Setting ALLOW_UNMAPPED = - Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, SettingsProperty.IndexScope); + Setting.boolSetting("index.query.parse.allow_unmapped_fields", true, Property.IndexScope); public static final Setting INDEX_TRANSLOG_SYNC_INTERVAL_SETTING = Setting.timeSetting("index.translog.sync_interval", TimeValue.timeValueSeconds(5), TimeValue.timeValueMillis(100), - SettingsProperty.IndexScope); + Property.IndexScope); public static final Setting INDEX_TRANSLOG_DURABILITY_SETTING = new Setting<>("index.translog.durability", Translog.Durability.REQUEST.name(), - (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + (value) -> Translog.Durability.valueOf(value.toUpperCase(Locale.ROOT)), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_WARMER_ENABLED_SETTING = - Setting.boolSetting("index.warmer.enabled", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting("index.warmer.enabled", true, Property.Dynamic, Property.IndexScope); public static final Setting INDEX_TTL_DISABLE_PURGE_SETTING = - Setting.boolSetting("index.ttl.disable_purge", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting("index.ttl.disable_purge", false, Property.Dynamic, Property.IndexScope); public static final Setting INDEX_CHECK_ON_STARTUP = new Setting<>("index.shard.check_on_startup", "false", (s) -> { switch(s) { case "false": @@ -80,7 +80,7 @@ public final class IndexSettings { default: throw new IllegalArgumentException("unknown value for [index.shard.check_on_startup] must be one of [true, false, fix, checksum] but was: " + s); } - }, SettingsProperty.IndexScope); + }, Property.IndexScope); /** * Index setting describing the maximum value of from + size on a query. @@ -91,14 +91,14 @@ public final class IndexSettings { * safely. */ public static final Setting MAX_RESULT_WINDOW_SETTING = - Setting.intSetting("index.max_result_window", 10000, 1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.intSetting("index.max_result_window", 10000, 1, Property.Dynamic, Property.IndexScope); public static final TimeValue DEFAULT_REFRESH_INTERVAL = new TimeValue(1, TimeUnit.SECONDS); public static final Setting INDEX_REFRESH_INTERVAL_SETTING = Setting.timeSetting("index.refresh_interval", DEFAULT_REFRESH_INTERVAL, new TimeValue(-1, TimeUnit.MILLISECONDS), - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_TRANSLOG_FLUSH_THRESHOLD_SIZE_SETTING = - Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + Setting.byteSizeSetting("index.translog.flush_threshold_size", new ByteSizeValue(512, ByteSizeUnit.MB), Property.Dynamic, + Property.IndexScope); /** @@ -107,8 +107,8 @@ public final class IndexSettings { */ public static final TimeValue DEFAULT_GC_DELETES = TimeValue.timeValueSeconds(60); public static final Setting INDEX_GC_DELETES_SETTING = - Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + Setting.timeSetting("index.gc_deletes", DEFAULT_GC_DELETES, new TimeValue(-1, TimeUnit.MILLISECONDS), Property.Dynamic, + Property.IndexScope); private final Index index; private final Version version; diff --git a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java index b0b06e7ec67..ed1814681ac 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java +++ b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java @@ -27,7 +27,7 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.NumericDocValues; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.engine.Engine; @@ -57,7 +57,7 @@ public final class IndexWarmer extends AbstractComponent { public static final Setting INDEX_NORMS_LOADING_SETTING = new Setting<>("index.norms.loading", MappedFieldType.Loading.LAZY.toString(), (s) -> MappedFieldType.Loading.parse(s, MappedFieldType.Loading.LAZY), - SettingsProperty.IndexScope); + Property.IndexScope); private final List listeners; IndexWarmer(Settings settings, ThreadPool threadPool, Listener... listeners) { diff --git a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java index eff27e6e04d..21596b3eb00 100644 --- a/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/IndexingSlowLog.java @@ -24,7 +24,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.index.engine.Engine; @@ -57,21 +57,21 @@ public final class IndexingSlowLog implements IndexingOperationListener { private static final String INDEX_INDEXING_SLOWLOG_PREFIX = "index.indexing.slowlog"; public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING = Setting.timeSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".threshold.index.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_REFORMAT_SETTING = - Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(INDEX_INDEXING_SLOWLOG_PREFIX +".reformat", true, Property.Dynamic, Property.IndexScope); public static final Setting INDEX_INDEXING_SLOWLOG_LEVEL_SETTING = - new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + new Setting<>(INDEX_INDEXING_SLOWLOG_PREFIX +".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, Property.Dynamic, + Property.IndexScope); /** * Reads how much of the source to log. The user can specify any value they * like and numbers are interpreted the maximum number of characters to log @@ -84,7 +84,7 @@ public final class IndexingSlowLog implements IndexingOperationListener { } catch (NumberFormatException e) { return Booleans.parseBoolean(value, true) ? Integer.MAX_VALUE : 0; } - }, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + }, Property.Dynamic, Property.IndexScope); IndexingSlowLog(IndexSettings indexSettings) { this(indexSettings, Loggers.getLogger(INDEX_INDEXING_SLOWLOG_PREFIX + ".index"), diff --git a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java index 35ead01981c..c8d82eae888 100644 --- a/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergePolicyConfig.java @@ -25,7 +25,7 @@ import org.apache.lucene.index.TieredMergePolicy; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -129,29 +129,29 @@ public final class MergePolicyConfig { public static final double DEFAULT_RECLAIM_DELETES_WEIGHT = 2.0d; public static final Setting INDEX_COMPOUND_FORMAT_SETTING = new Setting<>("index.compound_format", Double.toString(TieredMergePolicy.DEFAULT_NO_CFS_RATIO), MergePolicyConfig::parseNoCFSRatio, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_EXPUNGE_DELETES_ALLOWED_SETTING = Setting.doubleSetting("index.merge.policy.expunge_deletes_allowed", DEFAULT_EXPUNGE_DELETES_ALLOWED, 0.0d, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING = Setting.byteSizeSetting("index.merge.policy.floor_segment", DEFAULT_FLOOR_SEGMENT, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_SETTING = Setting.intSetting("index.merge.policy.max_merge_at_once", DEFAULT_MAX_MERGE_AT_ONCE, 2, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGE_AT_ONCE_EXPLICIT_SETTING = Setting.intSetting("index.merge.policy.max_merge_at_once_explicit", DEFAULT_MAX_MERGE_AT_ONCE_EXPLICIT, 2, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_MAX_MERGED_SEGMENT_SETTING = Setting.byteSizeSetting("index.merge.policy.max_merged_segment", DEFAULT_MAX_MERGED_SEGMENT, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_SEGMENTS_PER_TIER_SETTING = Setting.doubleSetting("index.merge.policy.segments_per_tier", DEFAULT_SEGMENTS_PER_TIER, 2.0d, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_MERGE_POLICY_RECLAIM_DELETES_WEIGHT_SETTING = Setting.doubleSetting("index.merge.policy.reclaim_deletes_weight", DEFAULT_RECLAIM_DELETES_WEIGHT, 0.0d, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final String INDEX_MERGE_ENABLED = "index.merge.enabled"; // don't convert to Setting<> and register... we only set this in tests and register via a plugin diff --git a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java index 1cfc5c82a70..2eb43a50ee4 100644 --- a/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java +++ b/core/src/main/java/org/elasticsearch/index/MergeSchedulerConfig.java @@ -21,7 +21,7 @@ package org.elasticsearch.index; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.util.concurrent.EsExecutors; /** @@ -55,14 +55,14 @@ public final class MergeSchedulerConfig { public static final Setting MAX_THREAD_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_thread_count", (s) -> Integer.toString(Math.max(1, Math.min(4, EsExecutors.boundedNumberOfProcessors(s) / 2))), - (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_thread_count"), Property.Dynamic, + Property.IndexScope); public static final Setting MAX_MERGE_COUNT_SETTING = new Setting<>("index.merge.scheduler.max_merge_count", (s) -> Integer.toString(MAX_THREAD_COUNT_SETTING.get(s) + 5), - (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + (s) -> Setting.parseInt(s, 1, "index.merge.scheduler.max_merge_count"), Property.Dynamic, Property.IndexScope); public static final Setting AUTO_THROTTLE_SETTING = - Setting.boolSetting("index.merge.scheduler.auto_throttle", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting("index.merge.scheduler.auto_throttle", true, Property.Dynamic, Property.IndexScope); private volatile boolean autoThrottle; private volatile int maxThreadCount; diff --git a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java index 2770f7e6e08..cfa779d64aa 100644 --- a/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java +++ b/core/src/main/java/org/elasticsearch/index/SearchSlowLog.java @@ -23,7 +23,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.search.internal.SearchContext; @@ -53,33 +53,33 @@ public final class SearchSlowLog { private static final String INDEX_SEARCH_SLOWLOG_PREFIX = "index.search.slowlog"; public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.query.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.warn", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.info", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.debug", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING = Setting.timeSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".threshold.fetch.trace", TimeValue.timeValueNanos(-1), - TimeValue.timeValueMillis(-1), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + TimeValue.timeValueMillis(-1), Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_REFORMAT = - Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting(INDEX_SEARCH_SLOWLOG_PREFIX + ".reformat", true, Property.Dynamic, Property.IndexScope); public static final Setting INDEX_SEARCH_SLOWLOG_LEVEL = - new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, SettingsProperty.Dynamic, - SettingsProperty.IndexScope); + new Setting<>(INDEX_SEARCH_SLOWLOG_PREFIX + ".level", SlowLogLevel.TRACE.name(), SlowLogLevel::parse, Property.Dynamic, + Property.IndexScope); public SearchSlowLog(IndexSettings indexSettings) { diff --git a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java index 756d79c2440..19ec3c8402e 100644 --- a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java +++ b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java @@ -38,7 +38,7 @@ import org.elasticsearch.common.cache.RemovalListener; import org.elasticsearch.common.cache.RemovalNotification; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; @@ -72,7 +72,7 @@ import java.util.concurrent.Executor; public final class BitsetFilterCache extends AbstractIndexComponent implements LeafReader.CoreClosedListener, RemovalListener>, Closeable { public static final Setting INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING = - Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, SettingsProperty.IndexScope); + Setting.boolSetting("index.load_fixed_bitset_filters_eagerly", true, Property.IndexScope); private final boolean loadRandomAccessFiltersEagerly; private final Cache> loadedFilters; diff --git a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java index e1bcd5bb698..14a8f043234 100644 --- a/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java +++ b/core/src/main/java/org/elasticsearch/index/engine/EngineConfig.java @@ -26,7 +26,7 @@ import org.apache.lucene.search.QueryCache; import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.search.similarities.Similarity; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -40,8 +40,6 @@ import org.elasticsearch.index.translog.TranslogConfig; import org.elasticsearch.indices.IndexingMemoryController; import org.elasticsearch.threadpool.ThreadPool; -import java.util.Set; - /* * Holds all the configuration that is used to create an {@link Engine}. * Once {@link Engine} has been created with this object, changes to this @@ -84,7 +82,7 @@ public final class EngineConfig { } return s; } - }, SettingsProperty.IndexScope); + }, Property.IndexScope); /** if set to true the engine will start even if the translog id in the commit point can not be found */ public static final String INDEX_FORCE_NEW_TRANSLOG = "index.engine.force_new_translog"; diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index 394f965f97c..a7a76e5e7aa 100644 --- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -24,7 +24,7 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.fielddata.plain.AbstractGeoPointDVIndexFieldData; @@ -68,7 +68,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo default: throw new IllegalArgumentException("failed to parse [" + s + "] must be one of [node,node]"); } - }, SettingsProperty.IndexScope); + }, Property.IndexScope); private static final IndexFieldData.Builder MISSING_DOC_VALUES_BUILDER = (indexProperties, fieldType, cache, breakerService, mapperService1) -> { throw new IllegalStateException("Can't load fielddata on [" + fieldType.name() diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 4a1da492130..528c8a8ee03 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -29,7 +29,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.analysis.NamedAnalyzer; @@ -51,9 +51,9 @@ import java.util.stream.StreamSupport; public abstract class FieldMapper extends Mapper implements Cloneable { public static final Setting IGNORE_MALFORMED_SETTING = - Setting.boolSetting("index.mapping.ignore_malformed", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.ignore_malformed", false, Property.IndexScope); public static final Setting COERCE_SETTING = - Setting.boolSetting("index.mapping.coerce", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.coerce", false, Property.IndexScope); public abstract static class Builder extends Mapper.Builder { protected final MappedFieldType fieldType; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 0acf52b8728..414ea0f7e9c 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -27,7 +27,7 @@ import org.elasticsearch.ElasticsearchGenerationException; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.AnalysisService; @@ -83,10 +83,10 @@ public class MapperService extends AbstractIndexComponent implements Closeable { public static final String DEFAULT_MAPPING = "_default_"; public static final Setting INDEX_MAPPING_NESTED_FIELDS_LIMIT_SETTING = - Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.longSetting("index.mapping.nested_fields.limit", 50L, 0, Property.Dynamic, Property.IndexScope); public static final boolean INDEX_MAPPER_DYNAMIC_DEFAULT = true; public static final Setting INDEX_MAPPER_DYNAMIC_SETTING = - Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapper.dynamic", INDEX_MAPPER_DYNAMIC_DEFAULT, Property.IndexScope); private static ObjectHashSet META_FIELDS = ObjectHashSet.from( "_uid", "_id", "_type", "_all", "_parent", "_routing", "_index", "_size", "_timestamp", "_ttl" diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java index 02974157aed..8a0e4140193 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java @@ -33,7 +33,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Explicit; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -55,7 +55,7 @@ import java.util.List; public abstract class NumberFieldMapper extends FieldMapper implements AllFieldMapper.IncludeInAll { // this is private since it has a different default private static final Setting COERCE_SETTING = - Setting.boolSetting("index.mapping.coerce", true, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.coerce", true, Property.IndexScope); public static class Defaults { diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java index 17e54ced15f..0a0cb9e96d9 100644 --- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java +++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorQueriesRegistry.java @@ -31,14 +31,12 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.metrics.MeanMetric; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.engine.Engine; -import org.elasticsearch.index.fielddata.IndexFieldDataService; -import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.mapper.internal.TypeFieldMapper; import org.elasticsearch.index.mapper.internal.UidFieldMapper; @@ -63,7 +61,7 @@ import java.util.concurrent.TimeUnit; public final class PercolatorQueriesRegistry extends AbstractIndexShardComponent implements Closeable { public final static Setting INDEX_MAP_UNMAPPED_FIELDS_AS_STRING_SETTING = - Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.percolator.map_unmapped_fields_as_string", false, Property.IndexScope); private final ConcurrentMap percolateQueries = ConcurrentCollections.newConcurrentMapWithAggressiveConcurrency(); private final QueryShardContext queryShardContext; diff --git a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java index ac84fd76179..933fd784588 100644 --- a/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java +++ b/core/src/main/java/org/elasticsearch/index/store/FsDirectoryService.java @@ -36,8 +36,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; -import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; @@ -63,7 +62,7 @@ public class FsDirectoryService extends DirectoryService implements StoreRateLim default: throw new IllegalArgumentException("unrecognized [index.store.fs.fs_lock] \"" + s + "\": must be native or simple"); } - }, SettingsProperty.IndexScope); + }, Property.IndexScope); private final CounterMetric rateLimitingTimeInNanos = new CounterMetric(); private final ShardPath path; diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java index be4e6966226..9e01d871765 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStore.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStore.java @@ -21,7 +21,7 @@ package org.elasticsearch.index.store; import org.apache.lucene.store.StoreRateLimiting; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.IndexSettings; @@ -32,10 +32,10 @@ import org.elasticsearch.index.shard.ShardPath; public class IndexStore extends AbstractIndexComponent { public static final Setting INDEX_STORE_THROTTLE_TYPE_SETTING = new Setting<>("index.store.throttle.type", "none", IndexRateLimitingType::fromString, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public static final Setting INDEX_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("index.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); protected final IndexStoreConfig indexStoreConfig; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java index 28a4c32ab75..12558bb9554 100644 --- a/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java +++ b/core/src/main/java/org/elasticsearch/index/store/IndexStoreConfig.java @@ -22,7 +22,7 @@ import org.apache.lucene.store.StoreRateLimiting; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; @@ -39,13 +39,13 @@ public class IndexStoreConfig { */ public static final Setting INDICES_STORE_THROTTLE_TYPE_SETTING = new Setting<>("indices.store.throttle.type", StoreRateLimiting.Type.NONE.name(),StoreRateLimiting.Type::fromString, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** * Configures the node / cluster level throttle intensity. The default is 10240 MB */ public static final Setting INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("indices.store.throttle.max_bytes_per_sec", new ByteSizeValue(0), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private volatile StoreRateLimiting.Type rateLimitingType; private volatile ByteSizeValue rateLimitingThrottle; private final StoreRateLimiting rateLimiting = new StoreRateLimiting(); diff --git a/core/src/main/java/org/elasticsearch/index/store/Store.java b/core/src/main/java/org/elasticsearch/index/store/Store.java index f467d25c594..772edb1d1b2 100644 --- a/core/src/main/java/org/elasticsearch/index/store/Store.java +++ b/core/src/main/java/org/elasticsearch/index/store/Store.java @@ -49,7 +49,6 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; @@ -61,7 +60,7 @@ import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.store.ByteArrayIndexInput; import org.elasticsearch.common.lucene.store.InputStreamIndexInput; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.Callback; @@ -91,7 +90,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.zip.Adler32; import java.util.zip.CRC32; import java.util.zip.Checksum; @@ -126,7 +124,7 @@ public class Store extends AbstractIndexShardComponent implements Closeable, Ref static final int VERSION = VERSION_WRITE_THROWABLE; static final String CORRUPTED = "corrupted_"; public static final Setting INDEX_STORE_STATS_REFRESH_INTERVAL_SETTING = - Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), SettingsProperty.IndexScope); + Setting.timeSetting("index.store.stats_refresh_interval", TimeValue.timeValueSeconds(10), Property.IndexScope); private final AtomicBoolean isClosed = new AtomicBoolean(false); private final StoreDirectory directory; diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java index 9dbb673fa5b..bd01e7f0183 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java @@ -32,7 +32,7 @@ import org.apache.lucene.search.Weight; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.lucene.ShardCoreKeyMap; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.cache.query.QueryCacheStats; @@ -49,9 +49,9 @@ import java.util.concurrent.ConcurrentHashMap; public class IndicesQueryCache extends AbstractComponent implements QueryCache, Closeable { public static final Setting INDICES_CACHE_QUERY_SIZE_SETTING = Setting.byteSizeSetting( - "indices.queries.cache.size", "10%", SettingsProperty.ClusterScope); + "indices.queries.cache.size", "10%", Property.NodeScope); public static final Setting INDICES_CACHE_QUERY_COUNT_SETTING = Setting.intSetting( - "indices.queries.cache.count", 10000, 1, SettingsProperty.ClusterScope); + "indices.queries.cache.count", 10000, 1, Property.NodeScope); private final LRUQueryCache cache; private final ShardCoreKeyMap shardKeyMap = new ShardCoreKeyMap(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java index 02aa09f138c..0e7b5dd9eb0 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java @@ -34,7 +34,7 @@ import org.elasticsearch.common.cache.RemovalNotification; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -70,11 +70,11 @@ public final class IndicesRequestCache extends AbstractComponent implements Remo * since we are checking on the cluster state IndexMetaData always. */ public static final Setting INDEX_CACHE_REQUEST_ENABLED_SETTING = - Setting.boolSetting("index.requests.cache.enable", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting.boolSetting("index.requests.cache.enable", false, Property.Dynamic, Property.IndexScope); public static final Setting INDICES_CACHE_QUERY_SIZE = - Setting.byteSizeSetting("indices.requests.cache.size", "1%", SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.requests.cache.size", "1%", Property.NodeScope); public static final Setting INDICES_CACHE_QUERY_EXPIRE = - Setting.positiveTimeSetting("indices.requests.cache.expire", new TimeValue(0), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.requests.cache.expire", new TimeValue(0), Property.NodeScope); private final ConcurrentMap registeredClosedListeners = ConcurrentCollections.newConcurrentMap(); private final Set keysToClean = ConcurrentCollections.newConcurrentSet(); diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesService.java b/core/src/main/java/org/elasticsearch/indices/IndicesService.java index c37a5d5cf6d..4b6c954a71a 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesService.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesService.java @@ -47,7 +47,7 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -117,7 +117,7 @@ public class IndicesService extends AbstractLifecycleComponent i public static final String INDICES_SHARDS_CLOSED_TIMEOUT = "indices.shards_closed_timeout"; public static final Setting INDICES_CACHE_CLEAN_INTERVAL_SETTING = - Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("indices.cache.cleanup_interval", TimeValue.timeValueMinutes(1), Property.NodeScope); private final PluginsService pluginsService; private final NodeEnvironment nodeEnv; private final TimeValue shardsClosedTimeout; diff --git a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java index b1189fbd286..06d5b2164e0 100644 --- a/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java +++ b/core/src/main/java/org/elasticsearch/indices/analysis/HunspellService.java @@ -24,7 +24,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; @@ -73,11 +73,11 @@ import java.util.function.Function; public class HunspellService extends AbstractComponent { public final static Setting HUNSPELL_LAZY_LOAD = - Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.analysis.hunspell.dictionary.lazy", Boolean.FALSE, Property.NodeScope); public final static Setting HUNSPELL_IGNORE_CASE = - Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, SettingsProperty.ClusterScope); + Setting.boolSetting("indices.analysis.hunspell.dictionary.ignore_case", Boolean.FALSE, Property.NodeScope); public final static Setting HUNSPELL_DICTIONARY_OPTIONS = - Setting.groupSetting("indices.analysis.hunspell.dictionary.", SettingsProperty.ClusterScope); + Setting.groupSetting("indices.analysis.hunspell.dictionary.", Property.NodeScope); private final ConcurrentHashMap dictionaries = new ConcurrentHashMap<>(); private final Map knownDictionaries; private final boolean defaultIgnoreCase; diff --git a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java index 3a3fede9af0..d2d96092186 100644 --- a/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java +++ b/core/src/main/java/org/elasticsearch/indices/breaker/HierarchyCircuitBreakerService.java @@ -27,7 +27,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; @@ -48,21 +48,21 @@ public class HierarchyCircuitBreakerService extends CircuitBreakerService { private final ConcurrentMap breakers = new ConcurrentHashMap(); public static final Setting TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.total.limit", "70%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.total.limit", "70%", Property.Dynamic, Property.NodeScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.fielddata.limit", "60%", Property.Dynamic, Property.NodeScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING = - Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.doubleSetting("indices.breaker.fielddata.overhead", 1.03d, 0.0d, Property.Dynamic, Property.NodeScope); public static final Setting FIELDDATA_CIRCUIT_BREAKER_TYPE_SETTING = - new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, SettingsProperty.ClusterScope); + new Setting<>("indices.breaker.fielddata.type", "memory", CircuitBreaker.Type::parseValue, Property.NodeScope); public static final Setting REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING = - Setting.byteSizeSetting("indices.breaker.request.limit", "40%", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.breaker.request.limit", "40%", Property.Dynamic, Property.NodeScope); public static final Setting REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING = - Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.doubleSetting("indices.breaker.request.overhead", 1.0d, 0.0d, Property.Dynamic, Property.NodeScope); public static final Setting REQUEST_CIRCUIT_BREAKER_TYPE_SETTING = - new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, SettingsProperty.ClusterScope); + new Setting<>("indices.breaker.request.type", "memory", CircuitBreaker.Type::parseValue, Property.NodeScope); diff --git a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java index a5bb8696999..46744f4d848 100644 --- a/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java +++ b/core/src/main/java/org/elasticsearch/indices/fielddata/cache/IndicesFieldDataCache.java @@ -34,7 +34,7 @@ import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.Index; @@ -54,7 +54,7 @@ import java.util.function.ToLongBiFunction; public class IndicesFieldDataCache extends AbstractComponent implements RemovalListener, Releasable{ public static final Setting INDICES_FIELDDATA_CACHE_SIZE_KEY = - Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("indices.fielddata.cache.size", new ByteSizeValue(-1), Property.NodeScope); private final IndexFieldDataCache.Listener indicesFieldDataCacheListener; private final Cache cache; diff --git a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java index f58dc1ca8b8..82595458479 100644 --- a/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java +++ b/core/src/main/java/org/elasticsearch/indices/recovery/RecoverySettings.java @@ -25,7 +25,7 @@ import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -35,7 +35,7 @@ public class RecoverySettings extends AbstractComponent { public static final Setting INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING = Setting.byteSizeSetting("indices.recovery.max_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** * how long to wait before retrying after issues cause by cluster state syncing between nodes @@ -43,17 +43,17 @@ public class RecoverySettings extends AbstractComponent { */ public static final Setting INDICES_RECOVERY_RETRY_DELAY_STATE_SYNC_SETTING = Setting.positiveTimeSetting("indices.recovery.retry_delay_state_sync", TimeValue.timeValueMillis(500), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** how long to wait before retrying after network related issues */ public static final Setting INDICES_RECOVERY_RETRY_DELAY_NETWORK_SETTING = Setting.positiveTimeSetting("indices.recovery.retry_delay_network", TimeValue.timeValueSeconds(5), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** timeout value to use for requests made as part of the recovery process */ public static final Setting INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING = Setting.positiveTimeSetting("indices.recovery.internal_action_timeout", TimeValue.timeValueMinutes(15), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); /** * timeout value to use for requests made as part of the recovery process that are expected to take long time. @@ -62,7 +62,7 @@ public class RecoverySettings extends AbstractComponent { public static final Setting INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.internal_action_long_timeout", (s) -> TimeValue.timeValueMillis(INDICES_RECOVERY_INTERNAL_ACTION_TIMEOUT_SETTING.get(s).millis() * 2).toString(), - TimeValue.timeValueSeconds(0), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + TimeValue.timeValueSeconds(0), Property.Dynamic, Property.NodeScope); /** * recoveries that don't show any activity for more then this interval will be failed. @@ -71,7 +71,7 @@ public class RecoverySettings extends AbstractComponent { public static final Setting INDICES_RECOVERY_ACTIVITY_TIMEOUT_SETTING = Setting.timeSetting("indices.recovery.recovery_activity_timeout", (s) -> INDICES_RECOVERY_INTERNAL_LONG_ACTION_TIMEOUT_SETTING.getRaw(s) , TimeValue.timeValueSeconds(0), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); public static final ByteSizeValue DEFAULT_CHUNK_SIZE = new ByteSizeValue(512, ByteSizeUnit.KB); diff --git a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java index 3851b4571b6..fa724bf9511 100644 --- a/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java +++ b/core/src/main/java/org/elasticsearch/indices/store/IndicesStore.java @@ -36,7 +36,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; @@ -58,7 +58,6 @@ import org.elasticsearch.transport.TransportService; import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.concurrent.TimeUnit; @@ -72,7 +71,7 @@ public class IndicesStore extends AbstractComponent implements ClusterStateListe // TODO this class can be foled into either IndicesService and partially into IndicesClusterStateService there is no need for a separate public service public static final Setting INDICES_STORE_DELETE_SHARD_TIMEOUT = Setting.positiveTimeSetting("indices.store.delete.shard.timeout", new TimeValue(30, TimeUnit.SECONDS), - SettingsProperty.ClusterScope); + Property.NodeScope); public static final String ACTION_SHARD_EXISTS = "internal:index/shard/exists"; private static final EnumSet ACTIVE_STATES = EnumSet.of(IndexShardState.STARTED, IndexShardState.RELOCATED); private final IndicesService indicesService; diff --git a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java index 0f9c9d425e1..b73fce540dc 100644 --- a/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java +++ b/core/src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java @@ -38,7 +38,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -70,7 +70,7 @@ public class IndicesTTLService extends AbstractLifecycleComponent INDICES_TTL_INTERVAL_SETTING = Setting.positiveTimeSetting("indices.ttl.interval", TimeValue.timeValueSeconds(60), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); private final ClusterService clusterService; private final IndicesService indicesService; diff --git a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java index 71a9743f78a..0287d5c522c 100644 --- a/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/fs/FsService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.fs; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -39,7 +39,7 @@ public class FsService extends AbstractComponent { public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.fs.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), - SettingsProperty.ClusterScope); + Property.NodeScope); public FsService(Settings settings, NodeEnvironment nodeEnvironment) throws IOException { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java index 301b86674c6..5a2d591c7dc 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.jvm; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.FutureUtils; @@ -48,13 +48,13 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent ENABLED_SETTING = - Setting.boolSetting("monitor.jvm.gc.enabled", true, SettingsProperty.ClusterScope); + Setting.boolSetting("monitor.jvm.gc.enabled", true, Property.NodeScope); public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), - SettingsProperty.ClusterScope); + Property.NodeScope); private static String GC_COLLECTOR_PREFIX = "monitor.jvm.gc.collector."; - public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, SettingsProperty.ClusterScope); + public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, Property.NodeScope); static class GcThreshold { public final String name; diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java index 5e03ab3e31c..e91c05e75ac 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.jvm; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -38,7 +38,7 @@ public class JvmService extends AbstractComponent { public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.jvm.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), - SettingsProperty.ClusterScope); + Property.NodeScope); public JvmService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java index df750c7247c..d452094d7b0 100644 --- a/core/src/main/java/org/elasticsearch/monitor/os/OsService.java +++ b/core/src/main/java/org/elasticsearch/monitor/os/OsService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.os; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -40,7 +40,7 @@ public class OsService extends AbstractComponent { public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.os.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), - SettingsProperty.ClusterScope); + Property.NodeScope); public OsService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java index 0370011e7c0..30c24f34c66 100644 --- a/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java +++ b/core/src/main/java/org/elasticsearch/monitor/process/ProcessService.java @@ -21,7 +21,7 @@ package org.elasticsearch.monitor.process; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.SingleObjectCache; @@ -37,7 +37,7 @@ public final class ProcessService extends AbstractComponent { public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.process.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), - SettingsProperty.ClusterScope); + Property.NodeScope); public ProcessService(Settings settings) { super(settings); diff --git a/core/src/main/java/org/elasticsearch/node/Node.java b/core/src/main/java/org/elasticsearch/node/Node.java index 7169be7d1f1..17b0b0d1e05 100644 --- a/core/src/main/java/org/elasticsearch/node/Node.java +++ b/core/src/main/java/org/elasticsearch/node/Node.java @@ -53,7 +53,7 @@ import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.transport.BoundTransportAddress; @@ -131,22 +131,22 @@ import static org.elasticsearch.common.settings.Settings.settingsBuilder; public class Node implements Closeable { public static final Setting WRITE_PORTS_FIELD_SETTING = - Setting.boolSetting("node.portsfile", false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.portsfile", false, Property.NodeScope); public static final Setting NODE_CLIENT_SETTING = - Setting.boolSetting("node.client", false, SettingsProperty.ClusterScope); - public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, SettingsProperty.ClusterScope); + Setting.boolSetting("node.client", false, Property.NodeScope); + public static final Setting NODE_DATA_SETTING = Setting.boolSetting("node.data", true, Property.NodeScope); public static final Setting NODE_MASTER_SETTING = - Setting.boolSetting("node.master", true, SettingsProperty.ClusterScope); + Setting.boolSetting("node.master", true, Property.NodeScope); public static final Setting NODE_LOCAL_SETTING = - Setting.boolSetting("node.local", false, SettingsProperty.ClusterScope); + Setting.boolSetting("node.local", false, Property.NodeScope); public static final Setting NODE_MODE_SETTING = - new Setting<>("node.mode", "network", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("node.mode", "network", Function.identity(), Property.NodeScope); public static final Setting NODE_INGEST_SETTING = - Setting.boolSetting("node.ingest", true, SettingsProperty.ClusterScope); - public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", SettingsProperty.ClusterScope); + Setting.boolSetting("node.ingest", true, Property.NodeScope); + public static final Setting NODE_NAME_SETTING = Setting.simpleString("node.name", Property.NodeScope); // this sucks that folks can mistype client etc and get away with it. // TODO: we should move this to node.attribute.${name} = ${value} instead. - public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", SettingsProperty.ClusterScope); + public static final Setting NODE_ATTRIBUTES = Setting.groupSetting("node.", Property.NodeScope); private static final String CLIENT_TYPE = "node"; diff --git a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java index 5f8107ba758..21801681437 100644 --- a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java +++ b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java @@ -26,7 +26,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.env.Environment; @@ -59,7 +59,7 @@ public class InternalSettingsPreparer { public static final String SECRET_PROMPT_VALUE = "${prompt.secret}"; public static final String TEXT_PROMPT_VALUE = "${prompt.text}"; public static final Setting IGNORE_SYSTEM_PROPERTIES_SETTING = - Setting.boolSetting("config.ignore_system_properties", false, SettingsProperty.ClusterScope); + Setting.boolSetting("config.ignore_system_properties", false, Property.NodeScope); /** * Prepares the settings by gathering all elasticsearch system properties and setting defaults. diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index 1aafcd0f6fb..cf953cd1529 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -37,7 +37,7 @@ import org.elasticsearch.common.io.FileSystemUtils; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexModule; @@ -73,7 +73,7 @@ public class PluginsService extends AbstractComponent { private final List> plugins; private final PluginsAndModules info; public static final Setting> MANDATORY_SETTING = - Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("plugin.mandatory", Collections.emptyList(), Function.identity(), Property.NodeScope); private final Map> onModuleReferences; diff --git a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java index 8ac297e072f..56e7e08c2c3 100644 --- a/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java @@ -24,7 +24,7 @@ import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.blobstore.fs.FsBlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -53,16 +53,16 @@ public class FsRepository extends BlobStoreRepository { public final static String TYPE = "fs"; public static final Setting LOCATION_SETTING = - new Setting<>("location", "", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("location", "", Function.identity(), Property.NodeScope); public static final Setting REPOSITORIES_LOCATION_SETTING = - new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), Property.NodeScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("chunk_size", "-1", SettingsProperty.ClusterScope); + Setting.byteSizeSetting("chunk_size", "-1", Property.NodeScope); public static final Setting REPOSITORIES_CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", SettingsProperty.ClusterScope); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.fs.chunk_size", "-1", Property.NodeScope); + public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, Property.NodeScope); public static final Setting REPOSITORIES_COMPRESS_SETTING = - Setting.boolSetting("repositories.fs.compress", false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.fs.compress", false, Property.NodeScope); private final FsBlobStore blobStore; diff --git a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java index 5086902d9fc..77d4f1cc816 100644 --- a/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java +++ b/core/src/main/java/org/elasticsearch/repositories/uri/URLRepository.java @@ -25,7 +25,7 @@ import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.blobstore.url.URLBlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.util.URIPattern; import org.elasticsearch.env.Environment; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -58,20 +58,20 @@ public class URLRepository extends BlobStoreRepository { public static final Setting> SUPPORTED_PROTOCOLS_SETTING = Setting.listSetting("repositories.url.supported_protocols", Arrays.asList("http", "https", "ftp", "file", "jar"), - Function.identity(), SettingsProperty.ClusterScope); + Function.identity(), Property.NodeScope); public static final Setting> ALLOWED_URLS_SETTING = - Setting.listSetting("repositories.url.allowed_urls", Collections.emptyList(), URIPattern::new, SettingsProperty.ClusterScope); + Setting.listSetting("repositories.url.allowed_urls", Collections.emptyList(), URIPattern::new, Property.NodeScope); - public static final Setting URL_SETTING = new Setting<>("url", "http:", URLRepository::parseURL, SettingsProperty.ClusterScope); + public static final Setting URL_SETTING = new Setting<>("url", "http:", URLRepository::parseURL, Property.NodeScope); public static final Setting REPOSITORIES_URL_SETTING = new Setting<>("repositories.url.url", (s) -> s.get("repositories.uri.url", "http:"), URLRepository::parseURL, - SettingsProperty.ClusterScope); + Property.NodeScope); public static final Setting LIST_DIRECTORIES_SETTING = - Setting.boolSetting("list_directories", true, SettingsProperty.ClusterScope); + Setting.boolSetting("list_directories", true, Property.NodeScope); public static final Setting REPOSITORIES_LIST_DIRECTORIES_SETTING = - Setting.boolSetting("repositories.uri.list_directories", true, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.uri.list_directories", true, Property.NodeScope); private final List supportedProtocols; diff --git a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java index 5066b4884af..b406dfca545 100644 --- a/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java +++ b/core/src/main/java/org/elasticsearch/rest/BaseRestHandler.java @@ -23,7 +23,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; /** @@ -36,7 +36,7 @@ import org.elasticsearch.common.settings.Settings; */ public abstract class BaseRestHandler extends AbstractComponent implements RestHandler { public static final Setting MULTI_ALLOW_EXPLICIT_INDEX = - Setting.boolSetting("rest.action.multi.allow_explicit_index", true, SettingsProperty.ClusterScope); + Setting.boolSetting("rest.action.multi.allow_explicit_index", true, Property.NodeScope); private final Client client; protected final ParseFieldMatcher parseFieldMatcher; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index c6cdd79e121..d46a12fb496 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -46,7 +46,7 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; @@ -56,7 +56,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.env.Environment; import org.elasticsearch.index.query.TemplateQueryParser; -import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.watcher.FileChangesListener; import org.elasticsearch.watcher.FileWatcher; @@ -86,12 +85,12 @@ public class ScriptService extends AbstractComponent implements Closeable { static final String DISABLE_DYNAMIC_SCRIPTING_SETTING = "script.disable_dynamic"; public static final Setting SCRIPT_CACHE_SIZE_SETTING = - Setting.intSetting("script.cache.max_size", 100, 0, SettingsProperty.ClusterScope); + Setting.intSetting("script.cache.max_size", 100, 0, Property.NodeScope); public static final Setting SCRIPT_CACHE_EXPIRE_SETTING = - Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("script.cache.expire", TimeValue.timeValueMillis(0), Property.NodeScope); public static final String SCRIPT_INDEX = ".scripts"; public static final Setting SCRIPT_AUTO_RELOAD_ENABLED_SETTING = - Setting.boolSetting("script.auto_reload_enabled", true, SettingsProperty.ClusterScope); + Setting.boolSetting("script.auto_reload_enabled", true, Property.NodeScope); private final String defaultLang; diff --git a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java index 26cb7eaa278..1bf7fdfc843 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptSettings.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptSettings.java @@ -21,7 +21,7 @@ package org.elasticsearch.script; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.ArrayList; @@ -45,7 +45,7 @@ public class ScriptSettings { ScriptModes.sourceKey(scriptType), scriptType.getDefaultScriptMode().getMode(), ScriptMode::parse, - SettingsProperty.ClusterScope)); + Property.NodeScope)); } SCRIPT_TYPE_SETTING_MAP = Collections.unmodifiableMap(scriptTypeSettingMap); } @@ -66,7 +66,7 @@ public class ScriptSettings { throw new IllegalArgumentException("unregistered default language [" + setting + "]"); } return setting; - }, SettingsProperty.ClusterScope); + }, Property.NodeScope); } private static Map> contextSettings(ScriptContextRegistry scriptContextRegistry) { @@ -76,7 +76,7 @@ public class ScriptSettings { ScriptModes.operationKey(scriptContext), ScriptMode.OFF.getMode(), ScriptMode::parse, - SettingsProperty.ClusterScope + Property.NodeScope )); } return scriptContextSettingMap; @@ -136,7 +136,7 @@ public class ScriptSettings { ScriptModes.getKey(language, scriptType, scriptContext), defaultSetting, ScriptMode::parse, - SettingsProperty.ClusterScope); + Property.NodeScope); scriptModeSettings.add(setting); } } diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index 856885c3ae4..d94d83b3070 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -34,7 +34,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.BigArrays; @@ -55,7 +55,6 @@ import org.elasticsearch.index.search.stats.StatsGroupsParseElement; import org.elasticsearch.index.shard.IndexEventListener; import org.elasticsearch.index.shard.IndexShard; import org.elasticsearch.indices.IndicesService; -import org.elasticsearch.indices.IndicesRequestCache; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptService; @@ -113,13 +112,13 @@ public class SearchService extends AbstractLifecycleComponent imp // we can have 5 minutes here, since we make sure to clean with search requests and when shard/index closes public static final Setting DEFAULT_KEEPALIVE_SETTING = - Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("search.default_keep_alive", timeValueMinutes(5), Property.NodeScope); public static final Setting KEEPALIVE_INTERVAL_SETTING = - Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("search.keep_alive_interval", timeValueMinutes(1), Property.NodeScope); public static final TimeValue NO_TIMEOUT = timeValueMillis(-1); public static final Setting DEFAULT_SEARCH_TIMEOUT_SETTING = - Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.timeSetting("search.default_search_timeout", NO_TIMEOUT, Property.Dynamic, Property.NodeScope); private final ThreadPool threadPool; diff --git a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java index 150325ff242..ebff17bfb76 100644 --- a/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java +++ b/core/src/main/java/org/elasticsearch/threadpool/ThreadPool.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.unit.SizeValue; @@ -190,7 +190,7 @@ public class ThreadPool extends AbstractComponent implements Closeable { } public static final Setting THREADPOOL_GROUP_SETTING = - Setting.groupSetting("threadpool.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.groupSetting("threadpool.", Property.Dynamic, Property.NodeScope); private volatile Map executors; diff --git a/core/src/main/java/org/elasticsearch/transport/Transport.java b/core/src/main/java/org/elasticsearch/transport/Transport.java index d6dee1953a4..532c9d99ace 100644 --- a/core/src/main/java/org/elasticsearch/transport/Transport.java +++ b/core/src/main/java/org/elasticsearch/transport/Transport.java @@ -22,7 +22,7 @@ package org.elasticsearch.transport; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -36,7 +36,7 @@ import java.util.Map; public interface Transport extends LifecycleComponent { - Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, SettingsProperty.ClusterScope); + Setting TRANSPORT_TCP_COMPRESS = Setting.boolSetting("transport.tcp.compress", false, Property.NodeScope); void transportServiceAdapter(TransportServiceAdapter service); diff --git a/core/src/main/java/org/elasticsearch/transport/TransportService.java b/core/src/main/java/org/elasticsearch/transport/TransportService.java index daa3409b40a..735a04455fb 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportService.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportService.java @@ -33,7 +33,7 @@ import org.elasticsearch.common.metrics.MeanMetric; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -99,10 +99,10 @@ public class TransportService extends AbstractLifecycleComponent> TRACE_LOG_INCLUDE_SETTING = - listSetting("transport.tracer.include", emptyList(), Function.identity(), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + listSetting("transport.tracer.include", emptyList(), Function.identity(), Property.Dynamic, Property.NodeScope); public static final Setting> TRACE_LOG_EXCLUDE_SETTING = listSetting("transport.tracer.exclude", Arrays.asList("internal:discovery/zen/fd*", TransportLivenessAction.NAME), - Function.identity(), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Function.identity(), Property.Dynamic, Property.NodeScope); private final ESLogger tracerLog; diff --git a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java index b52a54509bd..e36d4e403c4 100644 --- a/core/src/main/java/org/elasticsearch/transport/TransportSettings.java +++ b/core/src/main/java/org/elasticsearch/transport/TransportSettings.java @@ -19,7 +19,7 @@ package org.elasticsearch.transport; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import java.util.List; @@ -37,18 +37,18 @@ import static org.elasticsearch.common.settings.Setting.listSetting; final public class TransportSettings { public static final Setting> HOST = - listSetting("transport.host", emptyList(), Function.identity(), SettingsProperty.ClusterScope); + listSetting("transport.host", emptyList(), Function.identity(), Property.NodeScope); public static final Setting> PUBLISH_HOST = - listSetting("transport.publish_host", HOST, Function.identity(), SettingsProperty.ClusterScope); + listSetting("transport.publish_host", HOST, Function.identity(), Property.NodeScope); public static final Setting> BIND_HOST = - listSetting("transport.bind_host", HOST, Function.identity(), SettingsProperty.ClusterScope); + listSetting("transport.bind_host", HOST, Function.identity(), Property.NodeScope); public static final Setting PORT = - new Setting<>("transport.tcp.port", "9300-9400", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("transport.tcp.port", "9300-9400", Function.identity(), Property.NodeScope); public static final Setting PUBLISH_PORT = - intSetting("transport.publish_port", -1, -1, SettingsProperty.ClusterScope); + intSetting("transport.publish_port", -1, -1, Property.NodeScope); public static final String DEFAULT_PROFILE = "default"; public static final Setting TRANSPORT_PROFILES_SETTING = - groupSetting("transport.profiles.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + groupSetting("transport.profiles.", Property.Dynamic, Property.NodeScope); private TransportSettings() { diff --git a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java index 29c5fe05ee7..d844bd55658 100644 --- a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java +++ b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java @@ -44,7 +44,7 @@ import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.network.NetworkService.TcpSettings; import org.elasticsearch.common.network.NetworkUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -152,42 +152,42 @@ public class NettyTransport extends AbstractLifecycleComponent implem public static final Setting WORKER_COUNT = new Setting<>("transport.netty.worker_count", (s) -> Integer.toString(EsExecutors.boundedNumberOfProcessors(s) * 2), - (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), SettingsProperty.ClusterScope); + (s) -> Setting.parseInt(s, 1, "transport.netty.worker_count"), Property.NodeScope); public static final Setting CONNECTIONS_PER_NODE_RECOVERY = - intSetting("transport.connections_per_node.recovery", 2, 1, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.recovery", 2, 1, Property.NodeScope); public static final Setting CONNECTIONS_PER_NODE_BULK = - intSetting("transport.connections_per_node.bulk", 3, 1, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.bulk", 3, 1, Property.NodeScope); public static final Setting CONNECTIONS_PER_NODE_REG = - intSetting("transport.connections_per_node.reg", 6, 1, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.reg", 6, 1, Property.NodeScope); public static final Setting CONNECTIONS_PER_NODE_STATE = - intSetting("transport.connections_per_node.state", 1, 1, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.state", 1, 1, Property.NodeScope); public static final Setting CONNECTIONS_PER_NODE_PING = - intSetting("transport.connections_per_node.ping", 1, 1, SettingsProperty.ClusterScope); + intSetting("transport.connections_per_node.ping", 1, 1, Property.NodeScope); // the scheduled internal ping interval setting, defaults to disabled (-1) public static final Setting PING_SCHEDULE = - timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), SettingsProperty.ClusterScope); + timeSetting("transport.ping_schedule", TimeValue.timeValueSeconds(-1), Property.NodeScope); public static final Setting TCP_BLOCKING_CLIENT = - boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.blocking_client", TcpSettings.TCP_BLOCKING_CLIENT, Property.NodeScope); public static final Setting TCP_CONNECT_TIMEOUT = - timeSetting("transport.tcp.connect_timeout", TcpSettings.TCP_CONNECT_TIMEOUT, SettingsProperty.ClusterScope); + timeSetting("transport.tcp.connect_timeout", TcpSettings.TCP_CONNECT_TIMEOUT, Property.NodeScope); public static final Setting TCP_NO_DELAY = - boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, SettingsProperty.ClusterScope); + boolSetting("transport.tcp_no_delay", TcpSettings.TCP_NO_DELAY, Property.NodeScope); public static final Setting TCP_KEEP_ALIVE = - boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.keep_alive", TcpSettings.TCP_KEEP_ALIVE, Property.NodeScope); public static final Setting TCP_BLOCKING_SERVER = - boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.blocking_server", TcpSettings.TCP_BLOCKING_SERVER, Property.NodeScope); public static final Setting TCP_REUSE_ADDRESS = - boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, SettingsProperty.ClusterScope); + boolSetting("transport.tcp.reuse_address", TcpSettings.TCP_REUSE_ADDRESS, Property.NodeScope); public static final Setting TCP_SEND_BUFFER_SIZE = - Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.tcp.send_buffer_size", TcpSettings.TCP_SEND_BUFFER_SIZE, Property.NodeScope); public static final Setting TCP_RECEIVE_BUFFER_SIZE = - Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.tcp.receive_buffer_size", TcpSettings.TCP_RECEIVE_BUFFER_SIZE, Property.NodeScope); public static final Setting NETTY_MAX_CUMULATION_BUFFER_CAPACITY = - Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("transport.netty.max_cumulation_buffer_capacity", new ByteSizeValue(-1), Property.NodeScope); public static final Setting NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS = - Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, SettingsProperty.ClusterScope); + Setting.intSetting("transport.netty.max_composite_buffer_components", -1, -1, Property.NodeScope); // See AdaptiveReceiveBufferSizePredictor#DEFAULT_XXX for default values in netty..., we can use higher ones for us, even fixed one public static final Setting NETTY_RECEIVE_PREDICTOR_SIZE = Setting.byteSizeSetting( @@ -200,13 +200,13 @@ public class NettyTransport extends AbstractLifecycleComponent implem defaultReceiverPredictor = Math.min(defaultReceiverPredictor, Math.max(l, 64 * 1024)); } return new ByteSizeValue(defaultReceiverPredictor).toString(); - }, SettingsProperty.ClusterScope); + }, Property.NodeScope); public static final Setting NETTY_RECEIVE_PREDICTOR_MIN = - byteSizeSetting("transport.netty.receive_predictor_min", NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); + byteSizeSetting("transport.netty.receive_predictor_min", NETTY_RECEIVE_PREDICTOR_SIZE, Property.NodeScope); public static final Setting NETTY_RECEIVE_PREDICTOR_MAX = - byteSizeSetting("transport.netty.receive_predictor_max", NETTY_RECEIVE_PREDICTOR_SIZE, SettingsProperty.ClusterScope); + byteSizeSetting("transport.netty.receive_predictor_max", NETTY_RECEIVE_PREDICTOR_SIZE, Property.NodeScope); public static final Setting NETTY_BOSS_COUNT = - intSetting("transport.netty.boss_count", 1, 1, SettingsProperty.ClusterScope); + intSetting("transport.netty.boss_count", 1, 1, Property.NodeScope); protected final NetworkService networkService; protected final Version version; diff --git a/core/src/main/java/org/elasticsearch/tribe/TribeService.java b/core/src/main/java/org/elasticsearch/tribe/TribeService.java index 8872bcdd406..4f316f568ab 100644 --- a/core/src/main/java/org/elasticsearch/tribe/TribeService.java +++ b/core/src/main/java/org/elasticsearch/tribe/TribeService.java @@ -43,7 +43,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.set.Sets; @@ -120,7 +120,7 @@ public class TribeService extends AbstractLifecycleComponent { } // internal settings only - public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", SettingsProperty.ClusterScope); + public static final Setting TRIBE_NAME_SETTING = Setting.simpleString("tribe.name", Property.NodeScope); private final ClusterService clusterService; private final String[] blockIndicesWrite; private final String[] blockIndicesRead; @@ -139,18 +139,18 @@ public class TribeService extends AbstractLifecycleComponent { throw new IllegalArgumentException( "Invalid value for [tribe.on_conflict] must be either [any, drop or start with prefer_] but was: [" + s + "]"); } - }, SettingsProperty.ClusterScope); + }, Property.NodeScope); public static final Setting BLOCKS_METADATA_SETTING = - Setting.boolSetting("tribe.blocks.metadata", false, SettingsProperty.ClusterScope); + Setting.boolSetting("tribe.blocks.metadata", false, Property.NodeScope); public static final Setting BLOCKS_WRITE_SETTING = - Setting.boolSetting("tribe.blocks.write", false, SettingsProperty.ClusterScope); + Setting.boolSetting("tribe.blocks.write", false, Property.NodeScope); public static final Setting> BLOCKS_WRITE_INDICES_SETTING = - Setting.listSetting("tribe.blocks.write.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.write.indices", Collections.emptyList(), Function.identity(), Property.NodeScope); public static final Setting> BLOCKS_READ_INDICES_SETTING = - Setting.listSetting("tribe.blocks.read.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.read.indices", Collections.emptyList(), Function.identity(), Property.NodeScope); public static final Setting> BLOCKS_METADATA_INDICES_SETTING = - Setting.listSetting("tribe.blocks.metadata.indices", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("tribe.blocks.metadata.indices", Collections.emptyList(), Function.identity(), Property.NodeScope); public static final Set TRIBE_SETTING_KEYS = Sets.newHashSet(TRIBE_NAME_SETTING.getKey(), ON_CONFLICT_SETTING.getKey(), BLOCKS_METADATA_INDICES_SETTING.getKey(), BLOCKS_METADATA_SETTING.getKey(), BLOCKS_READ_INDICES_SETTING.getKey(), BLOCKS_WRITE_INDICES_SETTING.getKey(), BLOCKS_WRITE_SETTING.getKey()); diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/repositories/RepositoryBlocksIT.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/repositories/RepositoryBlocksIT.java index 9c554da781a..503db65e810 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/repositories/RepositoryBlocksIT.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/repositories/RepositoryBlocksIT.java @@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.hasSize; /** * This class tests that repository operations (Put, Delete, Verify) are blocked when the cluster is read-only. * - * The @ClusterScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only". + * The @NodeScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only". */ @ClusterScope(scope = ESIntegTestCase.Scope.TEST) public class RepositoryBlocksIT extends ESIntegTestCase { diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index f3a23be919d..82a2637d76b 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -41,7 +41,7 @@ import static org.hamcrest.Matchers.hasSize; /** * This class tests that snapshot operations (Create, Delete, Restore) are blocked when the cluster is read-only. * - * The @ClusterScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only". + * The @NodeScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only". */ @ClusterScope(scope = ESIntegTestCase.Scope.TEST) public class SnapshotBlocksIT extends ESIntegTestCase { diff --git a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java index cdf4185c94d..c266943737c 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/ClusterModuleTests.java @@ -35,7 +35,7 @@ import org.elasticsearch.common.inject.ModuleTestCase; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; @@ -84,7 +84,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterClusterDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.NodeScope)); assertInstanceBinding(module, ClusterSettings.class, service -> service.hasDynamicSetting("foo.bar")); } @@ -99,7 +99,7 @@ public class ClusterModuleTests extends ModuleTestCase { public void testRegisterIndexDynamicSetting() { SettingsModule module = new SettingsModule(Settings.EMPTY); - module.registerSetting(Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope)); + module.registerSetting(Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.IndexScope)); assertInstanceBinding(module, IndexScopedSettings.class, service -> service.hasDynamicSetting("foo.bar")); } diff --git a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java index 811ddc7ae5a..e61bbc5f719 100644 --- a/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/settings/SettingsFilteringIT.java @@ -23,7 +23,7 @@ import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; @@ -47,9 +47,9 @@ public class SettingsFilteringIT extends ESIntegTestCase { public static class SettingsFilteringPlugin extends Plugin { public static final Setting SOME_NODE_SETTING = - Setting.boolSetting("some.node.setting", false, SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.boolSetting("some.node.setting", false, Property.NodeScope, Property.Filtered); public static final Setting SOME_OTHER_NODE_SETTING = - Setting.boolSetting("some.other.node.setting", false, SettingsProperty.ClusterScope); + Setting.boolSetting("some.other.node.setting", false, Property.NodeScope); /** * The name of the plugin. @@ -75,7 +75,7 @@ public class SettingsFilteringIT extends ESIntegTestCase { public void onModule(SettingsModule module) { module.registerSetting(SOME_NODE_SETTING); module.registerSetting(SOME_OTHER_NODE_SETTING); - module.registerSetting(Setting.groupSetting("index.filter_test.", SettingsProperty.IndexScope)); + module.registerSetting(Setting.groupSetting("index.filter_test.", Property.IndexScope)); module.registerSettingsFilter("index.filter_test.foo"); module.registerSettingsFilter("index.filter_test.bar*"); } diff --git a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index 84adee21b32..48a49616b7b 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -23,7 +23,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.routing.allocation.decider.FilterAllocationDecider; import org.elasticsearch.cluster.routing.allocation.decider.ShardsLimitAllocationDecider; import org.elasticsearch.common.logging.ESLoggerFactory; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.index.IndexModule; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.TransportService; @@ -42,8 +42,8 @@ import java.util.function.Function; public class ScopedSettingsTests extends ESTestCase { public void testAddConsumer() { - Setting testSetting = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting testSetting = Setting.intSetting("foo.bar", 1, Property.Dynamic, Property.NodeScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, Property.Dynamic, Property.NodeScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, Collections.singleton(testSetting)); AtomicInteger consumer = new AtomicInteger(); @@ -70,8 +70,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testApply() { - Setting testSetting = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); - Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting testSetting = Setting.intSetting("foo.bar", 1, Property.Dynamic, Property.NodeScope); + Setting testSetting2 = Setting.intSetting("foo.bar.baz", 1, Property.Dynamic, Property.NodeScope); AbstractScopedSettings service = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(testSetting, testSetting2))); AtomicInteger consumer = new AtomicInteger(); @@ -142,8 +142,8 @@ public class ScopedSettingsTests extends ESTestCase { public void testIsDynamic(){ ClusterSettings settings = new ClusterSettings(Settings.EMPTY, - new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope), - Setting.intSetting("foo.bar.baz", 1, SettingsProperty.ClusterScope)))); + new HashSet<>(Arrays.asList(Setting.intSetting("foo.bar", 1, Property.Dynamic, Property.NodeScope), + Setting.intSetting("foo.bar.baz", 1, Property.NodeScope)))); assertFalse(settings.hasDynamicSetting("foo.bar.baz")); assertTrue(settings.hasDynamicSetting("foo.bar")); assertNotNull(settings.get("foo.bar.baz")); @@ -154,8 +154,8 @@ public class ScopedSettingsTests extends ESTestCase { } public void testDiff() throws IOException { - Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, SettingsProperty.ClusterScope); - Setting foobar = Setting.intSetting("foo.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting foobarbaz = Setting.intSetting("foo.bar.baz", 1, Property.NodeScope); + Setting foobar = Setting.intSetting("foo.bar", 1, Property.Dynamic, Property.NodeScope); ClusterSettings settings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(foobar, foobarbaz))); Settings diff = settings.diff(Settings.builder().put("foo.bar", 5).build(), Settings.EMPTY); assertEquals(diff.getAsMap().size(), 1); @@ -244,22 +244,22 @@ public class ScopedSettingsTests extends ESTestCase { try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo .", Property.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo .]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.groupSetting("boo.", Property.IndexScope))); try { new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo.", true, Property.IndexScope))); fail(); } catch (IllegalArgumentException e) { assertEquals("illegal settings key: [boo.]", e.getMessage()); } new IndexScopedSettings( - Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, SettingsProperty.IndexScope))); + Settings.EMPTY, Collections.singleton(Setting.boolSetting("boo", true, Property.IndexScope))); } public void testLoggingUpdates() { @@ -310,9 +310,9 @@ public class ScopedSettingsTests extends ESTestCase { public void testOverlappingComplexMatchSettings() { Set> settings = new LinkedHashSet<>(2); final boolean groupFirst = randomBoolean(); - final Setting groupSetting = Setting.groupSetting("foo.", SettingsProperty.ClusterScope); + final Setting groupSetting = Setting.groupSetting("foo.", Property.NodeScope); final Setting listSetting = - Setting.listSetting("foo.bar", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("foo.bar", Collections.emptyList(), Function.identity(), Property.NodeScope); settings.add(groupFirst ? groupSetting : listSetting); settings.add(groupFirst ? listSetting : groupSetting); diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java index 841126d1415..e8f754e15c5 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java @@ -19,7 +19,7 @@ package org.elasticsearch.common.settings; import org.elasticsearch.common.collect.Tuple; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.test.ESTestCase; @@ -38,7 +38,7 @@ public class SettingTests extends ESTestCase { public void testGet() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.NodeScope); assertFalse(booleanSetting.get(Settings.EMPTY)); assertFalse(booleanSetting.get(Settings.builder().put("foo.bar", false).build())); assertTrue(booleanSetting.get(Settings.builder().put("foo.bar", true).build())); @@ -46,12 +46,12 @@ public class SettingTests extends ESTestCase { public void testByteSize() { Setting byteSizeValueSetting = - Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("a.byte.size", new ByteSizeValue(1024), Property.Dynamic, Property.NodeScope); assertFalse(byteSizeValueSetting.isGroupSetting()); ByteSizeValue byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 1024); - byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + byteSizeValueSetting = Setting.byteSizeSetting("a.byte.size", s -> "2048b", Property.Dynamic, Property.NodeScope); byteSizeValue = byteSizeValueSetting.get(Settings.EMPTY); assertEquals(byteSizeValue.bytes(), 2048); @@ -70,7 +70,7 @@ public class SettingTests extends ESTestCase { } public void testSimpleUpdate() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.NodeScope); AtomicReference atomicBoolean = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(atomicBoolean::set, logger); Settings build = Settings.builder().put("foo.bar", false).build(); @@ -91,7 +91,7 @@ public class SettingTests extends ESTestCase { } public void testUpdateNotDynamic() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, Property.NodeScope); assertFalse(booleanSetting.isGroupSetting()); AtomicReference atomicBoolean = new AtomicReference<>(null); try { @@ -103,7 +103,7 @@ public class SettingTests extends ESTestCase { } public void testUpdaterIsIsolated() { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.NodeScope); AtomicReference ab1 = new AtomicReference<>(null); AtomicReference ab2 = new AtomicReference<>(null); ClusterSettings.SettingUpdater settingUpdater = booleanSetting.newUpdater(ab1::set, logger); @@ -115,7 +115,7 @@ public class SettingTests extends ESTestCase { public void testDefault() { TimeValue defautlValue = TimeValue.timeValueMillis(randomIntBetween(0, 1000000)); Setting setting = - Setting.positiveTimeSetting("my.time.value", defautlValue, SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("my.time.value", defautlValue, Property.NodeScope); assertFalse(setting.isGroupSetting()); String aDefault = setting.getDefaultRaw(Settings.EMPTY); assertEquals(defautlValue.millis() + "ms", aDefault); @@ -123,11 +123,11 @@ public class SettingTests extends ESTestCase { assertEquals(defautlValue, setting.getDefault(Settings.EMPTY)); Setting secondaryDefault = - new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("foo.bar", (s) -> s.get("old.foo.bar", "some_default"), Function.identity(), Property.NodeScope); assertEquals("some_default", secondaryDefault.get(Settings.EMPTY)); assertEquals("42", secondaryDefault.get(Settings.builder().put("old.foo.bar", 42).build())); Setting secondaryDefaultViaSettings = - new Setting<>("foo.bar", secondaryDefault, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("foo.bar", secondaryDefault, Function.identity(), Property.NodeScope); assertEquals("some_default", secondaryDefaultViaSettings.get(Settings.EMPTY)); assertEquals("42", secondaryDefaultViaSettings.get(Settings.builder().put("old.foo.bar", 42).build())); } @@ -135,7 +135,7 @@ public class SettingTests extends ESTestCase { public void testComplexType() { AtomicReference ref = new AtomicReference<>(null); Setting setting = new Setting<>("foo.bar", (s) -> "", (s) -> new ComplexType(s), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); assertFalse(setting.isGroupSetting()); ref.set(setting.get(Settings.EMPTY)); ComplexType type = ref.get(); @@ -156,19 +156,17 @@ public class SettingTests extends ESTestCase { } public void testType() { - Setting integerSetting = Setting.intSetting("foo.int.bar", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); - assertThat(integerSetting.hasClusterScope(), is(true)); + Setting integerSetting = Setting.intSetting("foo.int.bar", 1, Property.Dynamic, Property.NodeScope); + assertThat(integerSetting.hasNodeScope(), is(true)); assertThat(integerSetting.hasIndexScope(), is(false)); - assertThat(integerSetting.hasNodeScope(), is(false)); - integerSetting = Setting.intSetting("foo.int.bar", 1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + integerSetting = Setting.intSetting("foo.int.bar", 1, Property.Dynamic, Property.IndexScope); assertThat(integerSetting.hasIndexScope(), is(true)); - assertThat(integerSetting.hasClusterScope(), is(false)); assertThat(integerSetting.hasNodeScope(), is(false)); } public void testGroups() { AtomicReference ref = new AtomicReference<>(null); - Setting setting = Setting.groupSetting("foo.bar.", SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting setting = Setting.groupSetting("foo.bar.", Property.Dynamic, Property.NodeScope); assertTrue(setting.isGroupSetting()); ClusterSettings.SettingUpdater settingUpdater = setting.newUpdater(ref::set, logger); @@ -246,8 +244,8 @@ public class SettingTests extends ESTestCase { public void testComposite() { Composite c = new Composite(); - Setting a = Setting.intSetting("foo.int.bar.a", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); - Setting b = Setting.intSetting("foo.int.bar.b", 1, SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Setting a = Setting.intSetting("foo.int.bar.a", 1, Property.Dynamic, Property.NodeScope); + Setting b = Setting.intSetting("foo.int.bar.b", 1, Property.Dynamic, Property.NodeScope); ClusterSettings.SettingUpdater> settingUpdater = Setting.compoundUpdater(c::set, a, b, logger); assertFalse(settingUpdater.apply(Settings.EMPTY, Settings.EMPTY)); assertNull(c.a); @@ -276,7 +274,7 @@ public class SettingTests extends ESTestCase { public void testListSettings() { Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); List value = listSetting.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -316,7 +314,7 @@ public class SettingTests extends ESTestCase { assertEquals("foo,bar", ref.get().get(0)); Setting> otherSettings = Setting.listSetting("foo.bar", Collections.emptyList(), Integer::parseInt, - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); List defaultValue = otherSettings.get(Settings.EMPTY); assertEquals(0, defaultValue.size()); List intValues = otherSettings.get(Settings.builder().put("foo.bar", "0,1,2,3").build()); @@ -326,7 +324,7 @@ public class SettingTests extends ESTestCase { } Setting> settingWithFallback = Setting.listSetting("foo.baz", listSetting, Function.identity(), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); value = settingWithFallback.get(Settings.EMPTY); assertEquals(1, value.size()); assertEquals("foo,bar", value.get(0)); @@ -349,7 +347,7 @@ public class SettingTests extends ESTestCase { public void testListSettingAcceptsNumberSyntax() { Setting> listSetting = Setting.listSetting("foo.bar", Arrays.asList("foo,bar"), (s) -> s.toString(), - SettingsProperty.Dynamic, SettingsProperty.ClusterScope); + Property.Dynamic, Property.NodeScope); List input = Arrays.asList("test", "test1, test2", "test", ",,,,"); Settings.Builder builder = Settings.builder().putArray("foo.bar", input.toArray(new String[0])); // try to parse this really annoying format @@ -367,7 +365,7 @@ public class SettingTests extends ESTestCase { } public void testDynamicKeySetting() { - Setting setting = Setting.prefixKeySetting("foo.", "false", Boolean::parseBoolean, SettingsProperty.ClusterScope); + Setting setting = Setting.prefixKeySetting("foo.", "false", Boolean::parseBoolean, Property.NodeScope); assertTrue(setting.hasComplexMatcher()); assertTrue(setting.match("foo.bar")); assertFalse(setting.match("foo")); @@ -385,7 +383,7 @@ public class SettingTests extends ESTestCase { public void testAdfixKeySetting() { Setting setting = - Setting.adfixKeySetting("foo", "enable", "false", Boolean::parseBoolean, Setting.SettingsProperty.ClusterScope); + Setting.adfixKeySetting("foo", "enable", "false", Boolean::parseBoolean, Property.NodeScope); assertTrue(setting.hasComplexMatcher()); assertTrue(setting.match("foo.bar.enable")); assertTrue(setting.match("foo.baz.enable")); @@ -406,7 +404,7 @@ public class SettingTests extends ESTestCase { } public void testMinMaxInt() { - Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, SettingsProperty.ClusterScope); + Setting integerSetting = Setting.intSetting("foo.bar", 1, 0, 10, Property.NodeScope); try { integerSetting.get(Settings.builder().put("foo.bar", 11).build()); fail(); @@ -430,46 +428,21 @@ public class SettingTests extends ESTestCase { */ public void testMutuallyExclusiveScopes() { // Those should pass - Setting setting = Setting.simpleString("foo.bar", SettingsProperty.ClusterScope); - assertThat(setting.hasClusterScope(), is(true)); - assertThat(setting.hasNodeScope(), is(false)); - assertThat(setting.hasIndexScope(), is(false)); - setting = Setting.simpleString("foo.bar", SettingsProperty.NodeScope); + Setting setting = Setting.simpleString("foo.bar", Property.NodeScope); assertThat(setting.hasNodeScope(), is(true)); assertThat(setting.hasIndexScope(), is(false)); - assertThat(setting.hasClusterScope(), is(false)); - setting = Setting.simpleString("foo.bar", SettingsProperty.IndexScope); + setting = Setting.simpleString("foo.bar", Property.IndexScope); assertThat(setting.hasIndexScope(), is(true)); assertThat(setting.hasNodeScope(), is(false)); - assertThat(setting.hasClusterScope(), is(false)); // We test the default scope setting = Setting.simpleString("foo.bar"); assertThat(setting.hasNodeScope(), is(true)); assertThat(setting.hasIndexScope(), is(false)); - assertThat(setting.hasClusterScope(), is(false)); // Those should fail try { - Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.ClusterScope); - fail("Multiple scopes should fail"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); - } - try { - Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.NodeScope); - fail("Multiple scopes should fail"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); - } - try { - Setting.simpleString("foo.bar", SettingsProperty.ClusterScope, SettingsProperty.NodeScope); - fail("Multiple scopes should fail"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); - } - try { - Setting.simpleString("foo.bar", SettingsProperty.IndexScope, SettingsProperty.ClusterScope, SettingsProperty.NodeScope); + Setting.simpleString("foo.bar", Property.IndexScope, Property.NodeScope); fail("Multiple scopes should fail"); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("More than one scope has been added to the setting")); diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java index f5fd760297b..a8b5824f8ec 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java @@ -20,7 +20,7 @@ package org.elasticsearch.common.settings; import org.elasticsearch.common.inject.ModuleTestCase; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; public class SettingsModuleTests extends ModuleTestCase { @@ -46,13 +46,13 @@ public class SettingsModuleTests extends ModuleTestCase { { Settings settings = Settings.builder().put("some.custom.setting", "2.0").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, Property.NodeScope)); assertInstanceBinding(module, Settings.class, (s) -> s == settings); } { Settings settings = Settings.builder().put("some.custom.setting", "false").build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.floatSetting("some.custom.setting", 1.0f, Property.NodeScope)); try { assertInstanceBinding(module, Settings.class, (s) -> s == settings); fail(); @@ -132,9 +132,9 @@ public class SettingsModuleTests extends ModuleTestCase { public void testRegisterSettingsFilter() { Settings settings = Settings.builder().put("foo.bar", "false").put("bar.foo", false).put("bar.baz", false).build(); SettingsModule module = new SettingsModule(settings); - module.registerSetting(Setting.boolSetting("foo.bar", true, SettingsProperty.ClusterScope)); - module.registerSetting(Setting.boolSetting("bar.foo", true, SettingsProperty.ClusterScope, SettingsProperty.Filtered)); - module.registerSetting(Setting.boolSetting("bar.baz", true, SettingsProperty.ClusterScope)); + module.registerSetting(Setting.boolSetting("foo.bar", true, Property.NodeScope)); + module.registerSetting(Setting.boolSetting("bar.foo", true, Property.NodeScope, Property.Filtered)); + module.registerSetting(Setting.boolSetting("bar.baz", true, Property.NodeScope)); module.registerSettingsFilter("foo.*"); try { diff --git a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java index 7da2b0aaa2d..aa4fa81bc5b 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexModuleTests.java @@ -34,7 +34,7 @@ import org.elasticsearch.cache.recycler.PageCacheRecycler; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.env.Environment; @@ -195,9 +195,9 @@ public class IndexModuleTests extends ESTestCase { public void testListener() throws IOException { - Setting booleanSetting = Setting.boolSetting("foo.bar", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting booleanSetting = Setting.boolSetting("foo.bar", false, Property.Dynamic, Property.IndexScope); IndexModule module = new IndexModule(IndexSettingsModule.newIndexSettings(index, settings, booleanSetting), null, new AnalysisRegistry(null, environment)); - Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting booleanSetting2 = Setting.boolSetting("foo.bar.baz", false, Property.Dynamic, Property.IndexScope); AtomicBoolean atomicBoolean = new AtomicBoolean(false); module.addSettingsUpdateConsumer(booleanSetting, atomicBoolean::set); diff --git a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java index 18af7e13f7d..46d99e3b4bc 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java +++ b/core/src/test/java/org/elasticsearch/index/IndexSettingsTests.java @@ -23,7 +23,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -46,7 +46,7 @@ public class IndexSettingsTests extends ESTestCase { Settings theSettings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).put(IndexMetaData.SETTING_INDEX_UUID, "0xdeadbeef").build(); final AtomicInteger integer = new AtomicInteger(0); Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); IndexMetaData metaData = newIndexMeta("index", theSettings); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -68,9 +68,9 @@ public class IndexSettingsTests extends ESTestCase { final AtomicInteger integer = new AtomicInteger(0); final StringBuilder builder = new StringBuilder(); Setting integerSetting = Setting.intSetting("index.test.setting.int", -1, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); Setting notUpdated = new Setting<>("index.not.updated", "", Function.identity(), - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), Settings.EMPTY, integerSetting, notUpdated); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, integer::set); @@ -132,7 +132,7 @@ public class IndexSettingsTests extends ESTestCase { Settings nodeSettings = Settings.settingsBuilder().put("index.foo.bar", 43).build(); final AtomicInteger indexValue = new AtomicInteger(0); - Setting integerSetting = Setting.intSetting("index.foo.bar", -1, SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Setting integerSetting = Setting.intSetting("index.foo.bar", -1, Property.Dynamic, Property.IndexScope); IndexSettings settings = newIndexSettings(newIndexMeta("index", theSettings), nodeSettings, integerSetting); settings.getScopedSettings().addSettingsUpdateConsumer(integerSetting, indexValue::set); assertEquals(numReplicas, settings.getNumberOfReplicas()); diff --git a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java index 666994e823a..e9e8dcfc007 100644 --- a/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java +++ b/core/src/test/java/org/elasticsearch/index/SettingsListenerIT.java @@ -21,7 +21,7 @@ package org.elasticsearch.index; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; @@ -45,7 +45,7 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsListenerPlugin extends Plugin { private final SettingsTestingService service = new SettingsTestingService(); private static final Setting SETTING = Setting.intSetting("index.test.new.setting", 0, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); /** * The name of the plugin. */ @@ -96,7 +96,7 @@ public class SettingsListenerIT extends ESIntegTestCase { public static class SettingsTestingService { public volatile int value; public static Setting VALUE = Setting.intSetting("index.test.new.setting", -1, -1, - SettingsProperty.Dynamic, SettingsProperty.IndexScope); + Property.Dynamic, Property.IndexScope); public void setValue(int value) { this.value = value; diff --git a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java index 9f9a075ea28..aaac9c0cca4 100644 --- a/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/indices/IndicesOptionsIntegrationIT.java @@ -47,7 +47,7 @@ import org.elasticsearch.action.suggest.SuggestRequestBuilder; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.index.IndexNotFoundException; @@ -644,11 +644,11 @@ public class IndicesOptionsIntegrationIT extends ESIntegTestCase { } private static final Setting INDEX_A = - new Setting<>("index.a", "", Function.identity(), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + new Setting<>("index.a", "", Function.identity(), Property.Dynamic, Property.IndexScope); private static final Setting INDEX_C = - new Setting<>("index.c", "", Function.identity(), SettingsProperty.Dynamic, SettingsProperty.IndexScope); + new Setting<>("index.c", "", Function.identity(), Property.Dynamic, Property.IndexScope); private static final Setting INDEX_E = - new Setting<>("index.e", "", Function.identity(), SettingsProperty.IndexScope); + new Setting<>("index.e", "", Function.identity(), Property.IndexScope); public void onModule(SettingsModule module) { diff --git a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java index e025246a2f0..6bea3217894 100644 --- a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java +++ b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java @@ -31,7 +31,7 @@ import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.Requests; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.unit.TimeValue; @@ -199,9 +199,9 @@ public class RandomExceptionCircuitBreakerIT extends ESIntegTestCase { public static class RandomExceptionDirectoryReaderWrapper extends MockEngineSupport.DirectoryReaderWrapper { public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, Property.IndexScope); public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, Property.IndexScope); public static class TestPlugin extends Plugin { @Override public String name() { diff --git a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java index f53ca39941a..489a604292d 100644 --- a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java +++ b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java @@ -29,7 +29,7 @@ import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings.Builder; import org.elasticsearch.common.settings.SettingsModule; @@ -154,9 +154,9 @@ public class SearchWithRandomExceptionsIT extends ESIntegTestCase { public static class TestPlugin extends Plugin { public static final Setting EXCEPTION_TOP_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_TOP_LEVEL_RATIO_KEY, 0.1d, 0.0d, Property.IndexScope); public static final Setting EXCEPTION_LOW_LEVEL_RATIO_SETTING = - Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, SettingsProperty.IndexScope); + Setting.doubleSetting(EXCEPTION_LOW_LEVEL_RATIO_KEY, 0.1d, 0.0d, Property.IndexScope); @Override public String name() { return "random-exception-reader-wrapper"; diff --git a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java index 8669a38087e..0dcc345f01b 100644 --- a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java +++ b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java @@ -31,7 +31,7 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.env.Environment; @@ -60,9 +60,9 @@ public class MockRepository extends FsRepository { public static class Plugin extends org.elasticsearch.plugins.Plugin { - public static final Setting USERNAME_SETTING = Setting.simpleString("secret.mock.username", SettingsProperty.ClusterScope); + public static final Setting USERNAME_SETTING = Setting.simpleString("secret.mock.username", Property.NodeScope); public static final Setting PASSWORD_SETTING = - Setting.simpleString("secret.mock.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("secret.mock.password", Property.NodeScope, Property.Filtered); @Override public String name() { diff --git a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java index a59510b8873..acc1e76bde4 100644 --- a/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java +++ b/plugins/discovery-azure/src/main/java/org/elasticsearch/cloud/azure/management/AzureComputeService.java @@ -22,7 +22,7 @@ package org.elasticsearch.cloud.azure.management; import com.microsoft.windowsazure.core.utils.KeyStoreType; import com.microsoft.windowsazure.management.compute.models.HostedServiceGetDetailedResponse; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.azure.AzureUnicastHostsProvider; @@ -30,28 +30,28 @@ public interface AzureComputeService { final class Management { public static final Setting SUBSCRIPTION_ID_SETTING = - Setting.simpleString("cloud.azure.management.subscription.id", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.azure.management.subscription.id", Property.NodeScope, Property.Filtered); public static final Setting SERVICE_NAME_SETTING = - Setting.simpleString("cloud.azure.management.cloud.service.name", SettingsProperty.ClusterScope); + Setting.simpleString("cloud.azure.management.cloud.service.name", Property.NodeScope); // Keystore settings public static final Setting KEYSTORE_PATH_SETTING = - Setting.simpleString("cloud.azure.management.keystore.path", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.azure.management.keystore.path", Property.NodeScope, Property.Filtered); public static final Setting KEYSTORE_PASSWORD_SETTING = - Setting.simpleString("cloud.azure.management.keystore.password", SettingsProperty.ClusterScope, - SettingsProperty.Filtered); + Setting.simpleString("cloud.azure.management.keystore.password", Property.NodeScope, + Property.Filtered); public static final Setting KEYSTORE_TYPE_SETTING = new Setting<>("cloud.azure.management.keystore.type", KeyStoreType.pkcs12.name(), KeyStoreType::fromString, - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); } final class Discovery { public static final Setting REFRESH_SETTING = - Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), SettingsProperty.ClusterScope); + Setting.positiveTimeSetting("discovery.azure.refresh_interval", TimeValue.timeValueSeconds(0), Property.NodeScope); public static final Setting HOST_TYPE_SETTING = new Setting<>("discovery.azure.host.type", AzureUnicastHostsProvider.HostType.PRIVATE_IP.name(), - AzureUnicastHostsProvider.HostType::fromString, SettingsProperty.ClusterScope); + AzureUnicastHostsProvider.HostType::fromString, Property.NodeScope); public static final String ENDPOINT_NAME = "discovery.azure.endpoint.name"; public static final String DEPLOYMENT_NAME = "discovery.azure.deployment.name"; diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java index 2f2c423afb7..8cfe6c43108 100644 --- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java +++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/cloud/aws/AwsEc2Service.java @@ -22,7 +22,7 @@ package org.elasticsearch.cloud.aws; import com.amazonaws.Protocol; import com.amazonaws.services.ec2.AmazonEC2; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -33,7 +33,7 @@ import java.util.Locale; import java.util.function.Function; public interface AwsEc2Service { - Setting AUTO_ATTRIBUTE_SETTING = Setting.boolSetting("cloud.node.auto_attributes", false, SettingsProperty.ClusterScope); + Setting AUTO_ATTRIBUTE_SETTING = Setting.boolSetting("cloud.node.auto_attributes", false, Property.NodeScope); // Global AWS settings (shared between discovery-ec2 and repository-s3) // Each setting starting with `cloud.aws` also exists in repository-s3 project. Don't forget to update @@ -42,43 +42,43 @@ public interface AwsEc2Service { * cloud.aws.access_key: AWS Access key. Shared with repository-s3 plugin */ Setting KEY_SETTING = - Setting.simpleString("cloud.aws.access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.access_key", Property.NodeScope, Property.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with repository-s3 plugin */ Setting SECRET_SETTING = - Setting.simpleString("cloud.aws.secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.secret_key", Property.NodeScope, Property.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with repository-s3 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with repository-s3 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", SettingsProperty.ClusterScope); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", Property.NodeScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with repository-s3 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, SettingsProperty.ClusterScope); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, Property.NodeScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with repository-s3 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", SettingsProperty.ClusterScope); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", Property.NodeScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with repository-s3 plugin */ Setting PROXY_PASSWORD_SETTING = - Setting.simpleString("cloud.aws.proxy.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.proxy.password", Property.NodeScope, Property.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with repository-s3 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", SettingsProperty.ClusterScope); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", Property.NodeScope); /** * cloud.aws.region: Region. Shared with repository-s3 plugin */ Setting REGION_SETTING = - new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * Defines specific ec2 settings starting with cloud.aws.ec2. @@ -89,62 +89,62 @@ public interface AwsEc2Service { * @see AwsEc2Service#KEY_SETTING */ Setting KEY_SETTING = new Setting<>("cloud.aws.ec2.access_key", AwsEc2Service.KEY_SETTING, Function.identity(), - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); /** * cloud.aws.ec2.secret_key: AWS Secret key specific for EC2 API calls. Defaults to cloud.aws.secret_key. * @see AwsEc2Service#SECRET_SETTING */ Setting SECRET_SETTING = new Setting<>("cloud.aws.ec2.secret_key", AwsEc2Service.SECRET_SETTING, Function.identity(), - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); /** * cloud.aws.ec2.protocol: Protocol for AWS API specific for EC2 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsEc2Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.ec2.protocol", AwsEc2Service.PROTOCOL_SETTING, - s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); + s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope); /** * cloud.aws.ec2.proxy.host: In case of proxy, define its hostname/IP specific for EC2 API calls. Defaults to cloud.aws.proxy.host. * @see AwsEc2Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = new Setting<>("cloud.aws.ec2.proxy.host", AwsEc2Service.PROXY_HOST_SETTING, - Function.identity(), SettingsProperty.ClusterScope); + Function.identity(), Property.NodeScope); /** * cloud.aws.ec2.proxy.port: In case of proxy, define its port specific for EC2 API calls. Defaults to cloud.aws.proxy.port. * @see AwsEc2Service#PROXY_PORT_SETTING */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.ec2.proxy.port", AwsEc2Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), SettingsProperty.ClusterScope); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.ec2.proxy.port"), Property.NodeScope); /** * cloud.aws.ec2.proxy.username: In case of proxy with auth, define the username specific for EC2 API calls. * Defaults to cloud.aws.proxy.username. * @see AwsEc2Service#PROXY_USERNAME_SETTING */ Setting PROXY_USERNAME_SETTING = new Setting<>("cloud.aws.ec2.proxy.username", AwsEc2Service.PROXY_USERNAME_SETTING, - Function.identity(), SettingsProperty.ClusterScope); + Function.identity(), Property.NodeScope); /** * cloud.aws.ec2.proxy.password: In case of proxy with auth, define the password specific for EC2 API calls. * Defaults to cloud.aws.proxy.password. * @see AwsEc2Service#PROXY_PASSWORD_SETTING */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.ec2.proxy.password", AwsEc2Service.PROXY_PASSWORD_SETTING, - Function.identity(), SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Function.identity(), Property.NodeScope, Property.Filtered); /** * cloud.aws.ec2.signer: If you are using an old AWS API version, you can define a Signer. Specific for EC2 API calls. * Defaults to cloud.aws.signer. * @see AwsEc2Service#SIGNER_SETTING */ Setting SIGNER_SETTING = new Setting<>("cloud.aws.ec2.signer", AwsEc2Service.SIGNER_SETTING, Function.identity(), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.ec2.region: Region specific for EC2 API calls. Defaults to cloud.aws.region. * @see AwsEc2Service#REGION_SETTING */ Setting REGION_SETTING = new Setting<>("cloud.aws.ec2.region", AwsEc2Service.REGION_SETTING, - s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * cloud.aws.ec2.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ - Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.ec2.endpoint", Property.NodeScope); } /** @@ -164,31 +164,31 @@ public interface AwsEc2Service { */ Setting HOST_TYPE_SETTING = new Setting<>("discovery.ec2.host_type", HostType.PRIVATE_IP.name(), s -> HostType.valueOf(s.toUpperCase(Locale.ROOT)), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * discovery.ec2.any_group: If set to false, will require all security groups to be present for the instance to be used for the * discovery. Defaults to true. */ Setting ANY_GROUP_SETTING = - Setting.boolSetting("discovery.ec2.any_group", true, SettingsProperty.ClusterScope); + Setting.boolSetting("discovery.ec2.any_group", true, Property.NodeScope); /** * discovery.ec2.groups: Either a comma separated list or array based list of (security) groups. Only instances with the provided * security groups will be used in the cluster discovery. (NOTE: You could provide either group NAME or group ID.) */ Setting> GROUPS_SETTING = - Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), SettingsProperty.ClusterScope); + Setting.listSetting("discovery.ec2.groups", new ArrayList<>(), s -> s.toString(), Property.NodeScope); /** * discovery.ec2.availability_zones: Either a comma separated list or array based list of availability zones. Only instances within * the provided availability zones will be used in the cluster discovery. */ Setting> AVAILABILITY_ZONES_SETTING = Setting.listSetting("discovery.ec2.availability_zones", Collections.emptyList(), s -> s.toString(), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * discovery.ec2.node_cache_time: How long the list of hosts is cached to prevent further requests to the AWS API. Defaults to 10s. */ Setting NODE_CACHE_TIME_SETTING = - Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), SettingsProperty.ClusterScope); + Setting.timeSetting("discovery.ec2.node_cache_time", TimeValue.timeValueSeconds(10), Property.NodeScope); /** * discovery.ec2.tag.*: The ec2 discovery can filter machines to include in the cluster based on tags (and not just groups). @@ -196,7 +196,7 @@ public interface AwsEc2Service { * instances with a tag key set to stage, and a value of dev. Several tags set will require all of those tags to be set for the * instance to be included. */ - Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", SettingsProperty.ClusterScope); + Setting TAG_SETTING = Setting.groupSetting("discovery.ec2.tag.", Property.NodeScope); } AmazonEC2 client(); diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java index 7a46768e5a0..a6faa390e5d 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeService.java @@ -22,7 +22,7 @@ package org.elasticsearch.cloud.gce; import com.google.api.services.compute.model.Instance; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.TimeValue; import java.io.IOException; @@ -43,25 +43,25 @@ public interface GceComputeService extends LifecycleComponent /** * cloud.gce.project_id: Google project id */ - Setting PROJECT_SETTING = Setting.simpleString("cloud.gce.project_id", SettingsProperty.ClusterScope); + Setting PROJECT_SETTING = Setting.simpleString("cloud.gce.project_id", Property.NodeScope); /** * cloud.gce.zone: Google Compute Engine zones */ Setting> ZONE_SETTING = - Setting.listSetting("cloud.gce.zone", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("cloud.gce.zone", Collections.emptyList(), Function.identity(), Property.NodeScope); /** * cloud.gce.refresh_interval: How long the list of hosts is cached to prevent further requests to the AWS API. 0 disables caching. * A negative value will cause infinite caching. Defaults to 0s. */ Setting REFRESH_SETTING = - Setting.timeSetting("cloud.gce.refresh_interval", TimeValue.timeValueSeconds(0), SettingsProperty.ClusterScope); + Setting.timeSetting("cloud.gce.refresh_interval", TimeValue.timeValueSeconds(0), Property.NodeScope); /** * cloud.gce.retry: Should we retry calling GCE API in case of error? Defaults to true. */ - Setting RETRY_SETTING = Setting.boolSetting("cloud.gce.retry", true, SettingsProperty.ClusterScope); + Setting RETRY_SETTING = Setting.boolSetting("cloud.gce.retry", true, Property.NodeScope); /** * cloud.gce.max_wait: How long exponential backoff should retry before definitely failing. @@ -69,7 +69,7 @@ public interface GceComputeService extends LifecycleComponent * A negative value will retry indefinitely. Defaults to `-1s` (retry indefinitely). */ Setting MAX_WAIT_SETTING = - Setting.timeSetting("cloud.gce.max_wait", TimeValue.timeValueSeconds(-1), SettingsProperty.ClusterScope); + Setting.timeSetting("cloud.gce.max_wait", TimeValue.timeValueSeconds(-1), Property.NodeScope); /** * Return a collection of running instances within the same GCE project diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java index b0cfeb16c51..85e0910736f 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/cloud/gce/GceComputeServiceImpl.java @@ -38,14 +38,13 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.gce.RetryHttpInitializerWrapper; import java.io.IOException; import java.net.URL; -import java.nio.file.Files; import java.security.AccessController; import java.security.GeneralSecurityException; import java.security.PrivilegedAction; @@ -62,11 +61,11 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent GCE_VALIDATE_CERTIFICATES = - Setting.boolSetting("cloud.gce.validate_certificates", true, SettingsProperty.ClusterScope); + Setting.boolSetting("cloud.gce.validate_certificates", true, Property.NodeScope); public static final Setting GCE_HOST = - new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), Property.NodeScope); public static final Setting GCE_ROOT_URL = - new Setting<>("cloud.gce.root_url", "https://www.googleapis.com", Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("cloud.gce.root_url", "https://www.googleapis.com", Function.identity(), Property.NodeScope); private final String project; private final List zones; diff --git a/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java b/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java index d162ad8894c..85f3e3a9585 100644 --- a/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java +++ b/plugins/discovery-gce/src/main/java/org/elasticsearch/discovery/gce/GceUnicastHostsProvider.java @@ -31,7 +31,7 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; @@ -55,7 +55,7 @@ public class GceUnicastHostsProvider extends AbstractComponent implements Unicas * discovery.gce.tags: The gce discovery can filter machines to include in the cluster based on tags. */ public static final Setting> TAGS_SETTING = - Setting.listSetting("discovery.gce.tags", Collections.emptyList(), Function.identity(), SettingsProperty.ClusterScope); + Setting.listSetting("discovery.gce.tags", Collections.emptyList(), Function.identity(), Property.NodeScope); static final class Status { private static final String TERMINATED = "TERMINATED"; diff --git a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java index dd721f77ea0..cf5a0cf41d7 100644 --- a/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java +++ b/plugins/mapper-attachments/src/main/java/org/elasticsearch/mapper/attachments/AttachmentMapper.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.collect.Iterators; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -73,11 +73,11 @@ public class AttachmentMapper extends FieldMapper { private static ESLogger logger = ESLoggerFactory.getLogger("mapper.attachment"); public static final Setting INDEX_ATTACHMENT_IGNORE_ERRORS_SETTING = - Setting.boolSetting("index.mapping.attachment.ignore_errors", true, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.attachment.ignore_errors", true, Property.IndexScope); public static final Setting INDEX_ATTACHMENT_DETECT_LANGUAGE_SETTING = - Setting.boolSetting("index.mapping.attachment.detect_language", false, SettingsProperty.IndexScope); + Setting.boolSetting("index.mapping.attachment.detect_language", false, Property.IndexScope); public static final Setting INDEX_ATTACHMENT_INDEXED_CHARS_SETTING = - Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, SettingsProperty.IndexScope); + Setting.intSetting("index.mapping.attachment.indexed_chars", 100000, Property.IndexScope); public static final String CONTENT_TYPE = "attachment"; diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java index f9509bea57a..01d66c177a2 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageService.java @@ -24,7 +24,7 @@ import com.microsoft.azure.storage.StorageException; import org.elasticsearch.common.blobstore.BlobMetaData; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; @@ -42,19 +42,19 @@ public interface AzureStorageService { final class Storage { public static final String PREFIX = "cloud.azure.storage."; public static final Setting TIMEOUT_SETTING = - Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(-1), SettingsProperty.ClusterScope); + Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(-1), Property.NodeScope); public static final Setting ACCOUNT_SETTING = - Setting.simpleString("repositories.azure.account", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("repositories.azure.account", Property.NodeScope, Property.Filtered); public static final Setting CONTAINER_SETTING = - Setting.simpleString("repositories.azure.container", SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.container", Property.NodeScope); public static final Setting BASE_PATH_SETTING = - Setting.simpleString("repositories.azure.base_path", SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.base_path", Property.NodeScope); public static final Setting LOCATION_MODE_SETTING = - Setting.simpleString("repositories.azure.location_mode", SettingsProperty.ClusterScope); + Setting.simpleString("repositories.azure.location_mode", Property.NodeScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.azure.chunk_size", new ByteSizeValue(-1), Property.NodeScope); public static final Setting COMPRESS_SETTING = - Setting.boolSetting("repositories.azure.compress", false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.azure.compress", false, Property.NodeScope); } boolean doesContainerExist(String account, LocationMode mode, String container); diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java index 06185845ffb..281ef79cb27 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/cloud/azure/storage/AzureStorageSettings.java @@ -46,13 +46,13 @@ public final class AzureStorageSettings { TIMEOUT_KEY, (s) -> Storage.TIMEOUT_SETTING.get(s).toString(), (s) -> Setting.parseTimeValue(s, TimeValue.timeValueSeconds(-1), TIMEOUT_KEY.toString()), - Setting.SettingsProperty.ClusterScope); + Setting.Property.NodeScope); private static final Setting ACCOUNT_SETTING = - Setting.adfixKeySetting(Storage.PREFIX, ACCOUNT_SUFFIX, "", Function.identity(), Setting.SettingsProperty.ClusterScope); + Setting.adfixKeySetting(Storage.PREFIX, ACCOUNT_SUFFIX, "", Function.identity(), Setting.Property.NodeScope); private static final Setting KEY_SETTING = - Setting.adfixKeySetting(Storage.PREFIX, KEY_SUFFIX, "", Function.identity(), Setting.SettingsProperty.ClusterScope); + Setting.adfixKeySetting(Storage.PREFIX, KEY_SUFFIX, "", Function.identity(), Setting.Property.NodeScope); private static final Setting DEFAULT_SETTING = - Setting.adfixKeySetting(Storage.PREFIX, DEFAULT_SUFFIX, "false", Boolean::valueOf, Setting.SettingsProperty.ClusterScope); + Setting.adfixKeySetting(Storage.PREFIX, DEFAULT_SUFFIX, "false", Boolean::valueOf, Setting.Property.NodeScope); private final String name; @@ -112,7 +112,7 @@ public final class AzureStorageSettings { } private static List createStorageSettings(Settings settings) { - Setting storageGroupSetting = Setting.groupSetting(Storage.PREFIX, Setting.SettingsProperty.ClusterScope); + Setting storageGroupSetting = Setting.groupSetting(Storage.PREFIX, Setting.Property.NodeScope); // ignore global timeout which has the same prefix but does not belong to any group Settings groups = storageGroupSetting.get(settings.filter((k) -> k.equals(Storage.TIMEOUT_SETTING.getKey()) == false)); List storageSettings = new ArrayList<>(); diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index 56b2d9fc253..66db57fdd92 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -30,7 +30,7 @@ import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -68,14 +68,14 @@ public class AzureRepository extends BlobStoreRepository { public final static String TYPE = "azure"; public static final class Repository { - public static final Setting ACCOUNT_SETTING = Setting.simpleString("account", SettingsProperty.ClusterScope); + public static final Setting ACCOUNT_SETTING = Setting.simpleString("account", Property.NodeScope); public static final Setting CONTAINER_SETTING = - new Setting<>("container", "elasticsearch-snapshots", Function.identity(), SettingsProperty.ClusterScope); - public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", SettingsProperty.ClusterScope); - public static final Setting LOCATION_MODE_SETTING = Setting.simpleString("location_mode", SettingsProperty.ClusterScope); + new Setting<>("container", "elasticsearch-snapshots", Function.identity(), Property.NodeScope); + public static final Setting BASE_PATH_SETTING = Setting.simpleString("base_path", Property.NodeScope); + public static final Setting LOCATION_MODE_SETTING = Setting.simpleString("location_mode", Property.NodeScope); public static final Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, SettingsProperty.ClusterScope); - public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, Property.NodeScope); + public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, Property.NodeScope); } private final AzureBlobStore blobStore; diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java index 6f18bd3e6fd..427c454fa28 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/cloud/aws/AwsS3Service.java @@ -23,7 +23,7 @@ import com.amazonaws.Protocol; import com.amazonaws.services.s3.AmazonS3; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import java.util.Locale; import java.util.function.Function; @@ -40,43 +40,43 @@ public interface AwsS3Service extends LifecycleComponent { * cloud.aws.access_key: AWS Access key. Shared with discovery-ec2 plugin */ Setting KEY_SETTING = - Setting.simpleString("cloud.aws.access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.access_key", Property.NodeScope, Property.Filtered); /** * cloud.aws.secret_key: AWS Secret key. Shared with discovery-ec2 plugin */ Setting SECRET_SETTING = - Setting.simpleString("cloud.aws.secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.secret_key", Property.NodeScope, Property.Filtered); /** * cloud.aws.protocol: Protocol for AWS API: http or https. Defaults to https. Shared with discovery-ec2 plugin */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.proxy.host: In case of proxy, define its hostname/IP. Shared with discovery-ec2 plugin */ - Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", SettingsProperty.ClusterScope); + Setting PROXY_HOST_SETTING = Setting.simpleString("cloud.aws.proxy.host", Property.NodeScope); /** * cloud.aws.proxy.port: In case of proxy, define its port. Defaults to 80. Shared with discovery-ec2 plugin */ - Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, SettingsProperty.ClusterScope); + Setting PROXY_PORT_SETTING = Setting.intSetting("cloud.aws.proxy.port", 80, 0, 1<<16, Property.NodeScope); /** * cloud.aws.proxy.username: In case of proxy with auth, define the username. Shared with discovery-ec2 plugin */ - Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", SettingsProperty.ClusterScope); + Setting PROXY_USERNAME_SETTING = Setting.simpleString("cloud.aws.proxy.username", Property.NodeScope); /** * cloud.aws.proxy.password: In case of proxy with auth, define the password. Shared with discovery-ec2 plugin */ Setting PROXY_PASSWORD_SETTING = - Setting.simpleString("cloud.aws.proxy.password", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting.simpleString("cloud.aws.proxy.password", Property.NodeScope, Property.Filtered); /** * cloud.aws.signer: If you are using an old AWS API version, you can define a Signer. Shared with discovery-ec2 plugin */ - Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", SettingsProperty.ClusterScope); + Setting SIGNER_SETTING = Setting.simpleString("cloud.aws.signer", Property.NodeScope); /** * cloud.aws.region: Region. Shared with discovery-ec2 plugin */ Setting REGION_SETTING = - new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.region", "", s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * Defines specific s3 settings starting with cloud.aws.s3. @@ -88,35 +88,35 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting KEY_SETTING = new Setting<>("cloud.aws.s3.access_key", AwsS3Service.KEY_SETTING, Function.identity(), - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); /** * cloud.aws.s3.secret_key: AWS Secret key specific for S3 API calls. Defaults to cloud.aws.secret_key. * @see AwsS3Service#SECRET_SETTING */ Setting SECRET_SETTING = new Setting<>("cloud.aws.s3.secret_key", AwsS3Service.SECRET_SETTING, Function.identity(), - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); /** * cloud.aws.s3.protocol: Protocol for AWS API specific for S3 API calls: http or https. Defaults to cloud.aws.protocol. * @see AwsS3Service#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = new Setting<>("cloud.aws.s3.protocol", AwsS3Service.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.s3.proxy.host: In case of proxy, define its hostname/IP specific for S3 API calls. Defaults to cloud.aws.proxy.host. * @see AwsS3Service#PROXY_HOST_SETTING */ Setting PROXY_HOST_SETTING = new Setting<>("cloud.aws.s3.proxy.host", AwsS3Service.PROXY_HOST_SETTING, Function.identity(), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.s3.proxy.port: In case of proxy, define its port specific for S3 API calls. Defaults to cloud.aws.proxy.port. * @see AwsS3Service#PROXY_PORT_SETTING */ Setting PROXY_PORT_SETTING = new Setting<>("cloud.aws.s3.proxy.port", AwsS3Service.PROXY_PORT_SETTING, - s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), SettingsProperty.ClusterScope); + s -> Setting.parseInt(s, 0, 1<<16, "cloud.aws.s3.proxy.port"), Property.NodeScope); /** * cloud.aws.s3.proxy.username: In case of proxy with auth, define the username specific for S3 API calls. * Defaults to cloud.aws.proxy.username. @@ -124,7 +124,7 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_USERNAME_SETTING = new Setting<>("cloud.aws.s3.proxy.username", AwsS3Service.PROXY_USERNAME_SETTING, Function.identity(), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.s3.proxy.password: In case of proxy with auth, define the password specific for S3 API calls. * Defaults to cloud.aws.proxy.password. @@ -132,25 +132,25 @@ public interface AwsS3Service extends LifecycleComponent { */ Setting PROXY_PASSWORD_SETTING = new Setting<>("cloud.aws.s3.proxy.password", AwsS3Service.PROXY_PASSWORD_SETTING, Function.identity(), - SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Property.NodeScope, Property.Filtered); /** * cloud.aws.s3.signer: If you are using an old AWS API version, you can define a Signer. Specific for S3 API calls. * Defaults to cloud.aws.signer. * @see AwsS3Service#SIGNER_SETTING */ Setting SIGNER_SETTING = - new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("cloud.aws.s3.signer", AwsS3Service.SIGNER_SETTING, Function.identity(), Property.NodeScope); /** * cloud.aws.s3.region: Region specific for S3 API calls. Defaults to cloud.aws.region. * @see AwsS3Service#REGION_SETTING */ Setting REGION_SETTING = new Setting<>("cloud.aws.s3.region", AwsS3Service.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), - SettingsProperty.ClusterScope); + Property.NodeScope); /** * cloud.aws.s3.endpoint: Endpoint. If not set, endpoint will be guessed based on region setting. */ - Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.s3.endpoint", SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("cloud.aws.s3.endpoint", Property.NodeScope); } AmazonS3 client(String endpoint, Protocol protocol, String region, String account, String key, Integer maxRetries); diff --git a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java index dc0915cd276..fde774a6b92 100644 --- a/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java +++ b/plugins/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3Repository.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.blobstore.BlobPath; import org.elasticsearch.common.blobstore.BlobStore; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.index.snapshots.IndexShardRepository; @@ -67,41 +67,41 @@ public class S3Repository extends BlobStoreRepository { * @see CLOUD_S3#KEY_SETTING */ Setting KEY_SETTING = - new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.access_key", CLOUD_S3.KEY_SETTING, Function.identity(), Property.NodeScope); /** * repositories.s3.secret_key: AWS Secret key specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.secret_key. * @see CLOUD_S3#SECRET_SETTING */ Setting SECRET_SETTING = - new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.secret_key", CLOUD_S3.SECRET_SETTING, Function.identity(), Property.NodeScope); /** * repositories.s3.region: Region specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.region. * @see CLOUD_S3#REGION_SETTING */ Setting REGION_SETTING = - new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.region", CLOUD_S3.REGION_SETTING, s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * repositories.s3.endpoint: Endpoint specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.endpoint. * @see CLOUD_S3#ENDPOINT_SETTING */ Setting ENDPOINT_SETTING = - new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.endpoint", CLOUD_S3.ENDPOINT_SETTING, s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * repositories.s3.protocol: Protocol specific for all S3 Repositories API calls. Defaults to cloud.aws.s3.protocol. * @see CLOUD_S3#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = - new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); + new Setting<>("repositories.s3.protocol", CLOUD_S3.PROTOCOL_SETTING, s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope); /** * repositories.s3.bucket: The name of the bucket to be used for snapshots. */ - Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", SettingsProperty.ClusterScope); + Setting BUCKET_SETTING = Setting.simpleString("repositories.s3.bucket", Property.NodeScope); /** * repositories.s3.server_side_encryption: When set to true files are encrypted on server side using AES256 algorithm. * Defaults to false. */ Setting SERVER_SIDE_ENCRYPTION_SETTING = - Setting.boolSetting("repositories.s3.server_side_encryption", false, SettingsProperty.ClusterScope); + Setting.boolSetting("repositories.s3.server_side_encryption", false, Property.NodeScope); /** * repositories.s3.buffer_size: Minimum threshold below which the chunk is uploaded using a single request. Beyond this threshold, * the S3 repository will use the AWS Multipart Upload API to split the chunk into several parts, each of buffer_size length, and @@ -109,35 +109,35 @@ public class S3Repository extends BlobStoreRepository { * use of the Multipart API and may result in upload errors. Defaults to 5mb. */ Setting BUFFER_SIZE_SETTING = - Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.s3.buffer_size", S3BlobStore.MIN_BUFFER_SIZE, Property.NodeScope); /** * repositories.s3.max_retries: Number of retries in case of S3 errors. Defaults to 3. */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, SettingsProperty.ClusterScope); + Setting MAX_RETRIES_SETTING = Setting.intSetting("repositories.s3.max_retries", 3, Property.NodeScope); /** * repositories.s3.chunk_size: Big files can be broken down into chunks during snapshotting if needed. Defaults to 100m. */ Setting CHUNK_SIZE_SETTING = - Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), SettingsProperty.ClusterScope); + Setting.byteSizeSetting("repositories.s3.chunk_size", new ByteSizeValue(100, ByteSizeUnit.MB), Property.NodeScope); /** * repositories.s3.compress: When set to true metadata files are stored in compressed format. This setting doesn’t affect index * files that are already compressed by default. Defaults to false. */ - Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, SettingsProperty.ClusterScope); + Setting COMPRESS_SETTING = Setting.boolSetting("repositories.s3.compress", false, Property.NodeScope); /** * repositories.s3.storage_class: Sets the S3 storage class type for the backup files. Values may be standard, reduced_redundancy, * standard_ia. Defaults to standard. */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", SettingsProperty.ClusterScope); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("repositories.s3.storage_class", Property.NodeScope); /** * repositories.s3.canned_acl: The S3 repository supports all S3 canned ACLs : private, public-read, public-read-write, * authenticated-read, log-delivery-write, bucket-owner-read, bucket-owner-full-control. Defaults to private. */ - Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", SettingsProperty.ClusterScope); + Setting CANNED_ACL_SETTING = Setting.simpleString("repositories.s3.canned_acl", Property.NodeScope); /** * repositories.s3.base_path: Specifies the path within bucket to repository data. Defaults to root directory. */ - Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", SettingsProperty.ClusterScope); + Setting BASE_PATH_SETTING = Setting.simpleString("repositories.s3.base_path", Property.NodeScope); } /** @@ -149,75 +149,75 @@ public class S3Repository extends BlobStoreRepository { * access_key * @see Repositories#KEY_SETTING */ - Setting KEY_SETTING = Setting.simpleString("access_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting KEY_SETTING = Setting.simpleString("access_key", Property.NodeScope, Property.Filtered); /** * secret_key * @see Repositories#SECRET_SETTING */ - Setting SECRET_SETTING = Setting.simpleString("secret_key", SettingsProperty.ClusterScope, SettingsProperty.Filtered); + Setting SECRET_SETTING = Setting.simpleString("secret_key", Property.NodeScope, Property.Filtered); /** * bucket * @see Repositories#BUCKET_SETTING */ - Setting BUCKET_SETTING = Setting.simpleString("bucket", SettingsProperty.ClusterScope); + Setting BUCKET_SETTING = Setting.simpleString("bucket", Property.NodeScope); /** * endpoint * @see Repositories#ENDPOINT_SETTING */ - Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", SettingsProperty.ClusterScope); + Setting ENDPOINT_SETTING = Setting.simpleString("endpoint", Property.NodeScope); /** * protocol * @see Repositories#PROTOCOL_SETTING */ Setting PROTOCOL_SETTING = - new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), SettingsProperty.ClusterScope); + new Setting<>("protocol", "https", s -> Protocol.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope); /** * region * @see Repositories#REGION_SETTING */ - Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), SettingsProperty.ClusterScope); + Setting REGION_SETTING = new Setting<>("region", "", s -> s.toLowerCase(Locale.ROOT), Property.NodeScope); /** * server_side_encryption * @see Repositories#SERVER_SIDE_ENCRYPTION_SETTING */ Setting SERVER_SIDE_ENCRYPTION_SETTING = - Setting.boolSetting("server_side_encryption", false, SettingsProperty.ClusterScope); + Setting.boolSetting("server_side_encryption", false, Property.NodeScope); /** * buffer_size * @see Repositories#BUFFER_SIZE_SETTING */ Setting BUFFER_SIZE_SETTING = - Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, SettingsProperty.ClusterScope); + Setting.byteSizeSetting("buffer_size", S3BlobStore.MIN_BUFFER_SIZE, Property.NodeScope); /** * max_retries * @see Repositories#MAX_RETRIES_SETTING */ - Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, SettingsProperty.ClusterScope); + Setting MAX_RETRIES_SETTING = Setting.intSetting("max_retries", 3, Property.NodeScope); /** * chunk_size * @see Repositories#CHUNK_SIZE_SETTING */ - Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", SettingsProperty.ClusterScope); + Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", "-1", Property.NodeScope); /** * compress * @see Repositories#COMPRESS_SETTING */ - Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, SettingsProperty.ClusterScope); + Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, Property.NodeScope); /** * storage_class * @see Repositories#STORAGE_CLASS_SETTING */ - Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", SettingsProperty.ClusterScope); + Setting STORAGE_CLASS_SETTING = Setting.simpleString("storage_class", Property.NodeScope); /** * canned_acl * @see Repositories#CANNED_ACL_SETTING */ - Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", SettingsProperty.ClusterScope); + Setting CANNED_ACL_SETTING = Setting.simpleString("canned_acl", Property.NodeScope); /** * base_path * @see Repositories#BASE_PATH_SETTING */ - Setting BASE_PATH_SETTING = Setting.simpleString("base_path", SettingsProperty.ClusterScope); + Setting BASE_PATH_SETTING = Setting.simpleString("base_path", Property.NodeScope); } private final S3BlobStore blobStore; diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index 22a06957d38..d92f450d689 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -77,7 +77,7 @@ import org.elasticsearch.common.network.NetworkAddress; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Setting.SettingsProperty; +import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -197,7 +197,7 @@ import static org.hamcrest.Matchers.startsWith; * should be used, here is an example: *
  *
- * {@literal @}ClusterScope(scope=Scope.TEST) public class SomeIT extends ESIntegTestCase {
+ * {@literal @}NodeScope(scope=Scope.TEST) public class SomeIT extends ESIntegTestCase {
  * public void testMethod() {}
  * }
  * 
@@ -208,7 +208,7 @@ import static org.hamcrest.Matchers.startsWith; * determined at random and can change across tests. The {@link ClusterScope} allows configuring the initial number of nodes * that are created before the tests start. *
- * {@literal @}ClusterScope(scope=Scope.SUITE, numDataNodes=3)
+ * {@literal @}NodeScope(scope=Scope.SUITE, numDataNodes=3)
  * public class SomeIT extends ESIntegTestCase {
  * public void testMethod() {}
  * }
@@ -270,7 +270,7 @@ public abstract class ESIntegTestCase extends ESTestCase {
      * It's set once per test via a generic index template.
      */
     public static final Setting INDEX_TEST_SEED_SETTING =
-        Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, SettingsProperty.IndexScope);
+        Setting.longSetting("index.tests.seed", 0, Long.MIN_VALUE, Property.IndexScope);
 
     /**
      * A boolean value to enable or disable mock modules. This is useful to test the
diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java
index f10039391db..4a03389cb9c 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/InternalSettingsPlugin.java
@@ -20,7 +20,7 @@ package org.elasticsearch.test;
 
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.SettingsModule;
 import org.elasticsearch.plugins.Plugin;
 
@@ -36,11 +36,11 @@ public final class InternalSettingsPlugin extends Plugin {
     }
 
     public static final Setting VERSION_CREATED =
-        Setting.intSetting("index.version.created", 0, SettingsProperty.IndexScope);
+        Setting.intSetting("index.version.created", 0, Property.IndexScope);
     public static final Setting MERGE_ENABLED =
-        Setting.boolSetting("index.merge.enabled", true, SettingsProperty.IndexScope);
+        Setting.boolSetting("index.merge.enabled", true, Property.IndexScope);
     public static final Setting INDEX_CREATION_DATE_SETTING =
-        Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, SettingsProperty.IndexScope);
+        Setting.longSetting(IndexMetaData.SETTING_CREATION_DATE, -1, -1, Property.IndexScope);
 
     public void onModule(SettingsModule module) {
         module.registerSetting(VERSION_CREATED);
diff --git a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java
index d7bc9a7e0db..f17fe024f14 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/MockIndexEventListener.java
@@ -22,7 +22,7 @@ import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.inject.Module;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.SettingsModule;
 import org.elasticsearch.index.Index;
@@ -64,7 +64,7 @@ public final class MockIndexEventListener {
         /**
          * For tests to pass in to fail on listener invocation
          */
-        public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, SettingsProperty.IndexScope);
+        public static final Setting INDEX_FAIL = Setting.boolSetting("index.fail", false, Property.IndexScope);
         public void onModule(SettingsModule module) {
             module.registerSetting(INDEX_FAIL);
         }
diff --git a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java
index 2fad1fc05e8..bf32b6b8575 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/engine/MockEngineSupport.java
@@ -31,7 +31,7 @@ import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.index.engine.Engine;
 import org.elasticsearch.index.engine.EngineConfig;
@@ -57,12 +57,12 @@ public final class MockEngineSupport {
      * slow if {@link org.apache.lucene.index.AssertingDirectoryReader} is used.
      */
     public static final Setting WRAP_READER_RATIO =
-        Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, SettingsProperty.IndexScope);
+        Setting.doubleSetting("index.engine.mock.random.wrap_reader_ratio", 0.0d, 0.0d, Property.IndexScope);
     /**
      * Allows tests to prevent an engine from being flushed on close ie. to test translog recovery...
      */
     public static final Setting DISABLE_FLUSH_ON_CLOSE =
-        Setting.boolSetting("index.mock.disable_flush_on_close", false, SettingsProperty.IndexScope);
+        Setting.boolSetting("index.mock.disable_flush_on_close", false, Property.IndexScope);
 
 
     private final AtomicBoolean closing = new AtomicBoolean(false);
diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java
index 2cb5367e642..d267e9d7d51 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSDirectoryService.java
@@ -23,7 +23,6 @@ import com.carrotsearch.randomizedtesting.SeedUtils;
 import com.carrotsearch.randomizedtesting.generators.RandomPicks;
 
 import org.apache.lucene.index.CheckIndex;
-import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.store.BaseDirectoryWrapper;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.LockFactory;
@@ -32,14 +31,13 @@ import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.store.StoreRateLimiting;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestRuleMarkFailure;
-import org.elasticsearch.cluster.metadata.AliasOrIndex;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.io.stream.BytesStreamOutput;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.lucene.Lucene;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.index.IndexModule;
 import org.elasticsearch.index.IndexSettings;
@@ -63,15 +61,15 @@ import java.util.Random;
 public class MockFSDirectoryService extends FsDirectoryService {
 
     public static final Setting RANDOM_IO_EXCEPTION_RATE_ON_OPEN_SETTING =
-        Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d,  0.0d, SettingsProperty.IndexScope);
+        Setting.doubleSetting("index.store.mock.random.io_exception_rate_on_open", 0.0d,  0.0d, Property.IndexScope);
     public static final Setting RANDOM_IO_EXCEPTION_RATE_SETTING =
-        Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d,  0.0d, SettingsProperty.IndexScope);
+        Setting.doubleSetting("index.store.mock.random.io_exception_rate", 0.0d,  0.0d, Property.IndexScope);
     public static final Setting RANDOM_PREVENT_DOUBLE_WRITE_SETTING =
-        Setting.boolSetting("index.store.mock.random.prevent_double_write", true, SettingsProperty.IndexScope);// true is default in MDW
+        Setting.boolSetting("index.store.mock.random.prevent_double_write", true, Property.IndexScope);// true is default in MDW
     public static final Setting RANDOM_NO_DELETE_OPEN_FILE_SETTING =
-        Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, SettingsProperty.IndexScope);// true is default in MDW
+        Setting.boolSetting("index.store.mock.random.no_delete_open_file", true, Property.IndexScope);// true is default in MDW
     public static final Setting CRASH_INDEX_SETTING =
-        Setting.boolSetting("index.store.mock.random.crash_index", true, SettingsProperty.IndexScope);// true is default in MDW
+        Setting.boolSetting("index.store.mock.random.crash_index", true, Property.IndexScope);// true is default in MDW
 
     private final FsDirectoryService delegateService;
     private final Random random;
diff --git a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java
index 3d535d67799..44e3ad598eb 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/store/MockFSIndexStore.java
@@ -23,7 +23,7 @@ import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.SettingsModule;
 import org.elasticsearch.index.IndexModule;
@@ -46,7 +46,7 @@ import java.util.Map;
 public class MockFSIndexStore extends IndexStore {
 
     public static final Setting INDEX_CHECK_INDEX_ON_CLOSE_SETTING =
-        Setting.boolSetting("index.store.mock.check_index_on_close", true, SettingsProperty.IndexScope);
+        Setting.boolSetting("index.store.mock.check_index_on_close", true, Property.IndexScope);
 
     public static class TestPlugin extends Plugin {
         @Override
diff --git a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java
index 6009929e38e..fc090e151a3 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/tasks/MockTaskManager.java
@@ -20,7 +20,7 @@
 package org.elasticsearch.test.tasks;
 
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.tasks.Task;
 import org.elasticsearch.tasks.TaskManager;
@@ -35,7 +35,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
 public class MockTaskManager extends TaskManager {
 
     public static final Setting USE_MOCK_TASK_MANAGER_SETTING =
-        Setting.boolSetting("tests.mock.taskmanager.enabled", false, SettingsProperty.ClusterScope);
+        Setting.boolSetting("tests.mock.taskmanager.enabled", false, Property.NodeScope);
 
     private final Collection listeners = new CopyOnWriteArrayList<>();
 
diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java
index 88cdd325448..322882a7b3c 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/transport/AssertingLocalTransport.java
@@ -25,7 +25,7 @@ import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.settings.Setting;
-import org.elasticsearch.common.settings.Setting.SettingsProperty;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.SettingsModule;
 import org.elasticsearch.plugins.Plugin;
@@ -70,10 +70,10 @@ public class AssertingLocalTransport extends LocalTransport {
 
     public static final Setting ASSERTING_TRANSPORT_MIN_VERSION_KEY =
         new Setting<>("transport.asserting.version.min", Integer.toString(Version.CURRENT.minimumCompatibilityVersion().id),
-            (s) -> Version.fromId(Integer.parseInt(s)), SettingsProperty.ClusterScope);
+            (s) -> Version.fromId(Integer.parseInt(s)), Property.NodeScope);
     public static final Setting ASSERTING_TRANSPORT_MAX_VERSION_KEY =
         new Setting<>("transport.asserting.version.max", Integer.toString(Version.CURRENT.id),
-            (s) -> Version.fromId(Integer.parseInt(s)), SettingsProperty.ClusterScope);
+            (s) -> Version.fromId(Integer.parseInt(s)), Property.NodeScope);
     private final Random random;
     private final Version minVersion;
     private final Version maxVersion;

From 5c2ca3c9f526ae2bba0ed022d62e925fb64c3900 Mon Sep 17 00:00:00 2001
From: David Pilato 
Date: Fri, 4 Mar 2016 17:05:31 +0100
Subject: [PATCH 16/49] Check that we must have one and only one scope for a 
 Setting

---
 .../org/elasticsearch/common/settings/Setting.java  | 12 ++++--------
 .../elasticsearch/common/settings/SettingTests.java | 13 +++++++------
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
index 7464e06c179..606326dd295 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
@@ -119,12 +119,7 @@ public class Setting extends ToXContentToBytes {
         this.key = key;
         this.defaultValue = defaultValue;
         this.parser = parser;
-        if (properties.length == 0) {
-            this.properties = EnumSet.of(Property.NodeScope);
-        } else {
-            this.properties = EnumSet.copyOf(Arrays.asList(properties));
-        }
-        // We validate scope settings. They are mutually exclusive
+        // We validate scope settings. We should have one and only one.
         int numScopes = 0;
         for (Property property : properties) {
             if (property == Property.NodeScope ||
@@ -132,9 +127,10 @@ public class Setting extends ToXContentToBytes {
                 numScopes++;
             }
         }
-        if (numScopes > 1) {
-            throw new IllegalArgumentException("More than one scope has been added to the setting [" + key + "]");
+        if (numScopes != 1) {
+            throw new IllegalArgumentException("Zero or more than one scope has been added to the setting [" + key + "]");
         }
+        this.properties = EnumSet.copyOf(Arrays.asList(properties));
     }
 
     /**
diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
index e8f754e15c5..b2654092067 100644
--- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
+++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
@@ -435,17 +435,18 @@ public class SettingTests extends ESTestCase {
         assertThat(setting.hasIndexScope(), is(true));
         assertThat(setting.hasNodeScope(), is(false));
 
-        // We test the default scope
-        setting = Setting.simpleString("foo.bar");
-        assertThat(setting.hasNodeScope(), is(true));
-        assertThat(setting.hasIndexScope(), is(false));
-
         // Those should fail
+        try {
+            Setting.simpleString("foo.bar");
+            fail("Zero scope should fail");
+        } catch (IllegalArgumentException e) {
+            assertThat(e.getMessage(), containsString("Zero or more than one scope has been added to the setting"));
+        }
         try {
             Setting.simpleString("foo.bar", Property.IndexScope, Property.NodeScope);
             fail("Multiple scopes should fail");
         } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("More than one scope has been added to the setting"));
+            assertThat(e.getMessage(), containsString("Zero or more than one scope has been added to the setting"));
         }
     }
 }

From 8321d7c5c24444b82cba2f2b0468564a525688fb Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Fri, 4 Mar 2016 12:11:25 -0800
Subject: [PATCH 17/49] Catch option error during execution too, since
 OptionSet is passed there

---
 core/src/main/java/org/elasticsearch/cli/Command.java | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/cli/Command.java b/core/src/main/java/org/elasticsearch/cli/Command.java
index bc44a8eb635..d688347099d 100644
--- a/core/src/main/java/org/elasticsearch/cli/Command.java
+++ b/core/src/main/java/org/elasticsearch/cli/Command.java
@@ -56,7 +56,7 @@ public abstract class Command {
             options = parser.parse(args);
         } catch (OptionException e) {
             printHelp(terminal);
-            terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
+            terminal.println("ERROR: " + e.getMessage());
             return ExitCodes.USAGE;
         }
 
@@ -69,7 +69,7 @@ public abstract class Command {
             if (options.has(verboseOption)) {
                 // mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it
                 printHelp(terminal);
-                terminal.println(Terminal.Verbosity.SILENT, "ERROR: Cannot specify -s and -v together");
+                terminal.println("ERROR: Cannot specify -s and -v together");
                 return ExitCodes.USAGE;
             }
             terminal.setVerbosity(Terminal.Verbosity.SILENT);
@@ -81,6 +81,10 @@ public abstract class Command {
 
         try {
             return execute(terminal, options);
+        } catch (OptionException e) {
+            printHelp(terminal);
+            terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
+            return ExitCodes.USAGE;
         } catch (UserError e) {
             terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
             return e.exitCode;

From bde97e1d9c2fe2104065e95f78d98cf9954c4b28 Mon Sep 17 00:00:00 2001
From: David Pilato 
Date: Fri, 4 Mar 2016 21:44:01 +0100
Subject: [PATCH 18/49] Move validation logic to
 `SettingsModule.registerSetting`

---
 .../common/settings/Setting.java              | 17 +++++---------
 .../common/settings/SettingsModule.java       |  5 ++++
 .../common/settings/SettingTests.java         | 22 ++++++++----------
 .../common/settings/SettingsModuleTests.java  | 23 +++++++++++++++++++
 4 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
index 606326dd295..44e440500ff 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
@@ -38,7 +38,9 @@ import org.elasticsearch.common.xcontent.XContentType;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.EnumSet;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.Objects;
 import java.util.function.BiConsumer;
@@ -119,18 +121,11 @@ public class Setting extends ToXContentToBytes {
         this.key = key;
         this.defaultValue = defaultValue;
         this.parser = parser;
-        // We validate scope settings. We should have one and only one.
-        int numScopes = 0;
-        for (Property property : properties) {
-            if (property == Property.NodeScope ||
-                property == Property.IndexScope) {
-                numScopes++;
-            }
+        if (properties.length == 0) {
+            this.properties = EnumSet.noneOf(Property.class);
+        } else {
+            this.properties = EnumSet.copyOf(Arrays.asList(properties));
         }
-        if (numScopes != 1) {
-            throw new IllegalArgumentException("Zero or more than one scope has been added to the setting [" + key + "]");
-        }
-        this.properties = EnumSet.copyOf(Arrays.asList(properties));
     }
 
     /**
diff --git a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
index ee770f74756..9fc2ee257a0 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
@@ -76,6 +76,11 @@ public class SettingsModule extends AbstractModule {
                 registerSettingsFilter(setting.getKey());
             }
         }
+
+        // We validate scope settings. We should have one and only one scope.
+        if (setting.hasNodeScope() && setting.hasIndexScope()) {
+            throw new IllegalArgumentException("More than one scope has been added to the setting [" + setting.getKey() + "]");
+        }
         if (setting.hasNodeScope()) {
             if (nodeSettings.containsKey(setting.getKey())) {
                 throw new IllegalArgumentException("Cannot register setting [" + setting.getKey() + "] twice");
diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
index b2654092067..1c1f06f5914 100644
--- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
+++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
@@ -435,18 +435,14 @@ public class SettingTests extends ESTestCase {
         assertThat(setting.hasIndexScope(), is(true));
         assertThat(setting.hasNodeScope(), is(false));
 
-        // Those should fail
-        try {
-            Setting.simpleString("foo.bar");
-            fail("Zero scope should fail");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("Zero or more than one scope has been added to the setting"));
-        }
-        try {
-            Setting.simpleString("foo.bar", Property.IndexScope, Property.NodeScope);
-            fail("Multiple scopes should fail");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("Zero or more than one scope has been added to the setting"));
-        }
+        // We accept settings with no scope but they will be rejected when we register with SettingsModule.registerSetting
+        setting = Setting.simpleString("foo.bar");
+        assertThat(setting.hasIndexScope(), is(false));
+        assertThat(setting.hasNodeScope(), is(false));
+
+        // We accept settings with multiple scopes but they will be rejected when we register with SettingsModule.registerSetting
+        setting = Setting.simpleString("foo.bar", Property.IndexScope, Property.NodeScope);
+        assertThat(setting.hasIndexScope(), is(true));
+        assertThat(setting.hasNodeScope(), is(true));
     }
 }
diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java
index a8b5824f8ec..bc6afda9a01 100644
--- a/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java
+++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsModuleTests.java
@@ -22,6 +22,9 @@ package org.elasticsearch.common.settings;
 import org.elasticsearch.common.inject.ModuleTestCase;
 import org.elasticsearch.common.settings.Setting.Property;
 
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+
 public class SettingsModuleTests extends ModuleTestCase {
 
     public void testValidate() {
@@ -149,4 +152,24 @@ public class SettingsModuleTests extends ModuleTestCase {
         assertInstanceBinding(module, SettingsFilter.class, (s) -> s.filter(settings).getAsMap().get("bar.baz").equals("false"));
 
     }
+
+    public void testMutuallyExclusiveScopes() {
+        new SettingsModule(Settings.EMPTY).registerSetting(Setting.simpleString("foo.bar", Property.NodeScope));
+        new SettingsModule(Settings.EMPTY).registerSetting(Setting.simpleString("foo.bar", Property.IndexScope));
+
+        // Those should fail
+        try {
+            new SettingsModule(Settings.EMPTY).registerSetting(Setting.simpleString("foo.bar"));
+            fail("No scope should fail");
+        } catch (IllegalArgumentException e) {
+            assertThat(e.getMessage(), containsString("No scope found for setting"));
+        }
+        // Those should fail
+        try {
+            new SettingsModule(Settings.EMPTY).registerSetting(Setting.simpleString("foo.bar", Property.IndexScope, Property.NodeScope));
+            fail("Multiple scopes should fail");
+        } catch (IllegalArgumentException e) {
+            assertThat(e.getMessage(), containsString("More than one scope has been added to the setting"));
+        }
+    }
 }

From 45b5ab24fec2fae36e0eb205ccd00d8040ed9c7e Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Mon, 7 Mar 2016 12:42:15 -0800
Subject: [PATCH 19/49] Moved MockTerminal and created a base test case for cli
 commands.

---
 .../java/org/elasticsearch/cli/Command.java   |   6 +-
 .../common/cli/CheckFileCommand.java          | 138 ------------------
 .../common/cli/TerminalTests.java             |   7 +-
 .../logging/LoggingConfigurationTests.java    |   2 +-
 .../InternalSettingsPreparerTests.java        |   2 +-
 .../elasticsearch/plugins/PluginCliTests.java |   4 +-
 .../bootstrap/BootstrapCliParserTests.java    |  10 +-
 .../plugins/InstallPluginCommandTests.java    |   7 +-
 .../plugins/ListPluginsCommandTests.java      |   7 +-
 .../plugins/RemovePluginCommandTests.java     |   4 +-
 .../elasticsearch/cli/CommandTestCase.java    |  48 ++++++
 .../{common => }/cli/MockTerminal.java        |  10 +-
 .../common/cli/CliToolTestCase.java           |   1 +
 13 files changed, 75 insertions(+), 171 deletions(-)
 delete mode 100644 core/src/main/java/org/elasticsearch/common/cli/CheckFileCommand.java
 create mode 100644 test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
 rename test/framework/src/main/java/org/elasticsearch/{common => }/cli/MockTerminal.java (92%)

diff --git a/core/src/main/java/org/elasticsearch/cli/Command.java b/core/src/main/java/org/elasticsearch/cli/Command.java
index d688347099d..6e57905b5b2 100644
--- a/core/src/main/java/org/elasticsearch/cli/Command.java
+++ b/core/src/main/java/org/elasticsearch/cli/Command.java
@@ -49,14 +49,14 @@ public abstract class Command {
     }
 
     /** Parses options for this command from args and executes it. */
-    public final int main(String[] args, Terminal terminal) throws Exception {
+    protected final int main(String[] args, Terminal terminal) throws Exception {
 
         final OptionSet options;
         try {
             options = parser.parse(args);
         } catch (OptionException e) {
             printHelp(terminal);
-            terminal.println("ERROR: " + e.getMessage());
+            terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
             return ExitCodes.USAGE;
         }
 
@@ -69,7 +69,7 @@ public abstract class Command {
             if (options.has(verboseOption)) {
                 // mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it
                 printHelp(terminal);
-                terminal.println("ERROR: Cannot specify -s and -v together");
+                terminal.println(Terminal.Verbosity.SILENT, "ERROR: Cannot specify -s and -v together");
                 return ExitCodes.USAGE;
             }
             terminal.setVerbosity(Terminal.Verbosity.SILENT);
diff --git a/core/src/main/java/org/elasticsearch/common/cli/CheckFileCommand.java b/core/src/main/java/org/elasticsearch/common/cli/CheckFileCommand.java
deleted file mode 100644
index e2fcbe89df8..00000000000
--- a/core/src/main/java/org/elasticsearch/common/cli/CheckFileCommand.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.common.cli;
-
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.Environment;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFileAttributeView;
-import java.nio.file.attribute.PosixFileAttributes;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.PosixFilePermissions;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A helper command that checks if configured paths have been changed when running a CLI command.
- * It is only executed in case of specified paths by the command and if the paths underlying filesystem
- * supports posix permissions.
- *
- * If this is the case, a warn message is issued whenever an owner, a group or the file permissions is changed by
- * the command being executed and not configured back to its prior state, which should be the task of the command
- * being executed.
- *
- */
-public abstract class CheckFileCommand extends CliTool.Command {
-
-    public CheckFileCommand(Terminal terminal) {
-        super(terminal);
-    }
-
-    /**
-     * abstract method, which should implement the same logic as CliTool.Command.execute(), but is wrapped
-     */
-    public abstract CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception;
-
-    /**
-     * Returns the array of paths, that should be checked if the permissions, user or groups have changed
-     * before and after execution of the command
-     *
-     */
-    protected abstract Path[] pathsForPermissionsCheck(Settings settings, Environment env) throws Exception;
-
-    @Override
-    public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception {
-        Path[] paths = pathsForPermissionsCheck(settings, env);
-
-        if (paths == null || paths.length == 0) {
-            return doExecute(settings, env);
-        }
-
-        Map> permissions = new HashMap<>(paths.length);
-        Map owners = new HashMap<>(paths.length);
-        Map groups = new HashMap<>(paths.length);
-
-        if (paths != null && paths.length > 0) {
-            for (Path path : paths) {
-                try {
-                    boolean supportsPosixPermissions = Environment.getFileStore(path).supportsFileAttributeView(PosixFileAttributeView.class);
-                    if (supportsPosixPermissions) {
-                        PosixFileAttributes attributes = Files.readAttributes(path, PosixFileAttributes.class);
-                        permissions.put(path, attributes.permissions());
-                        owners.put(path, attributes.owner().getName());
-                        groups.put(path, attributes.group().getName());
-                    }
-                } catch (IOException e) {
-                    // silently swallow if not supported, no need to log things
-                }
-            }
-        }
-
-        CliTool.ExitStatus status = doExecute(settings, env);
-
-        // check if permissions differ
-        for (Map.Entry> entry : permissions.entrySet()) {
-            if (!Files.exists(entry.getKey())) {
-                continue;
-            }
-
-            Set permissionsBeforeWrite = entry.getValue();
-            Set permissionsAfterWrite = Files.getPosixFilePermissions(entry.getKey());
-            if (!permissionsBeforeWrite.equals(permissionsAfterWrite)) {
-                terminal.println(Terminal.Verbosity.SILENT, "WARNING: The file permissions of [" + entry.getKey() + "] have changed "
-                        + "from [" + PosixFilePermissions.toString(permissionsBeforeWrite) + "] "
-                        + "to [" + PosixFilePermissions.toString(permissionsAfterWrite) + "]");
-                terminal.println(Terminal.Verbosity.SILENT, "Please ensure that the user account running Elasticsearch has read access to this file!");
-            }
-        }
-
-        // check if owner differs
-        for (Map.Entry entry : owners.entrySet()) {
-            if (!Files.exists(entry.getKey())) {
-                continue;
-            }
-
-            String ownerBeforeWrite = entry.getValue();
-            String ownerAfterWrite = Files.getOwner(entry.getKey()).getName();
-            if (!ownerAfterWrite.equals(ownerBeforeWrite)) {
-                terminal.println(Terminal.Verbosity.SILENT, "WARNING: Owner of file [" + entry.getKey() + "] used to be [" + ownerBeforeWrite + "], but now is [" + ownerAfterWrite + "]");
-            }
-        }
-
-        // check if group differs
-        for (Map.Entry entry : groups.entrySet()) {
-            if (!Files.exists(entry.getKey())) {
-                continue;
-            }
-
-            String groupBeforeWrite = entry.getValue();
-            String groupAfterWrite = Files.readAttributes(entry.getKey(), PosixFileAttributes.class).group().getName();
-            if (!groupAfterWrite.equals(groupBeforeWrite)) {
-                terminal.println(Terminal.Verbosity.SILENT, "WARNING: Group of file [" + entry.getKey() + "] used to be [" + groupBeforeWrite + "], but now is [" + groupAfterWrite + "]");
-            }
-        }
-
-        return status;
-    }
-}
diff --git a/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java b/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java
index deb64e906b4..12fc4cb77e4 100644
--- a/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java
+++ b/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java
@@ -19,7 +19,10 @@
 
 package org.elasticsearch.common.cli;
 
-public class TerminalTests extends CliToolTestCase {
+import org.elasticsearch.cli.MockTerminal;
+import org.elasticsearch.test.ESTestCase;
+
+public class TerminalTests extends ESTestCase {
     public void testVerbosity() throws Exception {
         MockTerminal terminal = new MockTerminal();
         terminal.setVerbosity(Terminal.Verbosity.SILENT);
@@ -48,7 +51,7 @@ public class TerminalTests extends CliToolTestCase {
         logTerminal.println(verbosity, text);
         String output = logTerminal.getOutput();
         assertTrue(output, output.contains(text));
-        logTerminal.resetOutput();
+        logTerminal.reset();
     }
 
     private void assertNotPrinted(MockTerminal logTerminal, Terminal.Verbosity verbosity, String text) throws Exception {
diff --git a/core/src/test/java/org/elasticsearch/common/logging/LoggingConfigurationTests.java b/core/src/test/java/org/elasticsearch/common/logging/LoggingConfigurationTests.java
index 0cca19d33bf..5c812cca0a7 100644
--- a/core/src/test/java/org/elasticsearch/common/logging/LoggingConfigurationTests.java
+++ b/core/src/test/java/org/elasticsearch/common/logging/LoggingConfigurationTests.java
@@ -27,7 +27,7 @@ import java.util.Arrays;
 
 import org.apache.log4j.Appender;
 import org.apache.log4j.Logger;
-import org.elasticsearch.common.cli.MockTerminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
diff --git a/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java b/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java
index 33876ef61ad..c979b2f4013 100644
--- a/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java
+++ b/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java
@@ -24,7 +24,7 @@ import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import org.elasticsearch.common.cli.MockTerminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.cluster.ClusterName;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.SettingsException;
diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
index 7a4590f8e25..708cefd91b2 100644
--- a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
+++ b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
@@ -20,10 +20,8 @@
 package org.elasticsearch.plugins;
 
 import org.elasticsearch.common.cli.CliToolTestCase;
-import org.elasticsearch.common.cli.MockTerminal;
+import org.elasticsearch.cli.MockTerminal;
 
-import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK_AND_EXIT;
-import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.is;
 
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
index 12b5ab9eb39..18d6e0ac3c9 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
@@ -25,7 +25,7 @@ import org.elasticsearch.common.SuppressForbidden;
 import org.elasticsearch.common.cli.CliTool.ExitStatus;
 import org.elasticsearch.common.cli.CliToolTestCase;
 import org.elasticsearch.cli.UserError;
-import org.elasticsearch.common.cli.MockTerminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.collect.Tuple;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 import org.junit.After;
@@ -89,7 +89,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         assertTrue(output, output.contains(Build.CURRENT.date()));
         assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
 
-        terminal.resetOutput();
+        terminal.reset();
         parser = new BootstrapCLIParser(terminal);
         status = parser.execute(args("start --version"));
         assertStatus(status, OK_AND_EXIT);
@@ -177,7 +177,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         String output = terminal.getOutput();
         assertTrue(output, output.contains("Parameter [network.host] needs value"));
 
-        terminal.resetOutput();
+        terminal.reset();
         status = parser.execute(args("start --network.host --foo"));
         assertStatus(status, USAGE);
         output = terminal.getOutput();
@@ -194,7 +194,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         assertTrue(output, output.contains("Unrecognized option: --unknown-param"));
 
         // single dash in extra params
-        terminal.resetOutput();
+        terminal.reset();
         parser = new BootstrapCLIParser(terminal);
         status = parser.execute(args("start -network.host 127.0.0.1"));
         assertStatus(status, USAGE);
@@ -228,7 +228,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         tuples.add(new Tuple<>("-h", "elasticsearch.help"));
 
         for (Tuple tuple : tuples) {
-            terminal.resetOutput();
+            terminal.reset();
             BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
             ExitStatus status = parser.execute(args(tuple.v1()));
             assertStatus(status, OK_AND_EXIT);
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
index 342b579a175..514090d9869 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
@@ -36,7 +36,6 @@ import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.PosixFileAttributeView;
 import java.nio.file.attribute.PosixFileAttributes;
 import java.nio.file.attribute.PosixFilePermission;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -45,11 +44,7 @@ import java.util.zip.ZipOutputStream;
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.elasticsearch.Version;
-import org.elasticsearch.cli.ExitCodes;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.CliToolTestCase;
-import org.elasticsearch.common.cli.MockTerminal;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java
index aed1696898a..cbdd031dea1 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/ListPluginsCommandTests.java
@@ -22,15 +22,10 @@ package org.elasticsearch.plugins;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.elasticsearch.cli.ExitCodes;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.CliToolTestCase;
-import org.elasticsearch.common.cli.MockTerminal;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.test.ESTestCase;
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
index a678d4f25f6..d9d5661b834 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/RemovePluginCommandTests.java
@@ -26,9 +26,7 @@ import java.nio.file.Path;
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.elasticsearch.cli.UserError;
-import org.elasticsearch.common.cli.CliToolTestCase;
-import org.elasticsearch.common.cli.MockTerminal;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.test.ESTestCase;
diff --git a/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
new file mode 100644
index 00000000000..3af25509adb
--- /dev/null
+++ b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.cli;
+
+import joptsimple.OptionSet;
+import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.test.ESTestCase;
+import org.junit.Before;
+
+/**
+ * A base test case for cli tools.
+ */
+public abstract class CommandTestCase extends ESTestCase {
+
+    protected final MockTerminal terminal = new MockTerminal();
+
+    @Before
+    public void resetTerminal() {
+        terminal.reset();
+        terminal.setVerbosity(Terminal.Verbosity.NORMAL);
+    }
+
+    protected abstract Command newCommand();
+
+    public String execute(String... args) throws Exception {
+        Command command = newCommand();
+        OptionSet options = command.parser.parse(args);
+        command.execute(terminal, options);
+        return terminal.getOutput();
+    }
+}
diff --git a/test/framework/src/main/java/org/elasticsearch/common/cli/MockTerminal.java b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
similarity index 92%
rename from test/framework/src/main/java/org/elasticsearch/common/cli/MockTerminal.java
rename to test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
index 3b2903b3fab..bb01369ac50 100644
--- a/test/framework/src/main/java/org/elasticsearch/common/cli/MockTerminal.java
+++ b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.elasticsearch.common.cli;
+package org.elasticsearch.cli;
 
 import java.io.ByteArrayOutputStream;
 import java.io.OutputStreamWriter;
@@ -27,6 +27,8 @@ import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Deque;
 
+import org.elasticsearch.common.cli.Terminal;
+
 /**
  * A terminal for tests which captures all output, and
  * can be plugged with fake input.
@@ -78,8 +80,10 @@ public class MockTerminal extends Terminal {
         return buffer.toString("UTF-8");
     }
 
-    /** Wipes the output. */
-    public void resetOutput() {
+    /** Wipes the input and output. */
+    public void reset() {
         buffer.reset();
+        textInput.clear();
+        secretInput.clear();
     }
 }
diff --git a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java
index 9debf4b8f33..330758223a5 100644
--- a/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java
@@ -21,6 +21,7 @@ package org.elasticsearch.common.cli;
 
 import java.io.IOException;
 
+import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.SuppressForbidden;
 import org.elasticsearch.test.ESTestCase;

From e5c852f7678b6c568811f9bcbc397b864df1c15f Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 13:39:37 -0800
Subject: [PATCH 20/49] Convert bootstrapcli parser to jopt-simple

---
 .../elasticsearch/bootstrap/Bootstrap.java    |  18 +-
 .../bootstrap/BootstrapCLIParser.java         | 199 +++++------------
 .../bootstrap/Elasticsearch.java              |  13 +-
 .../java/org/elasticsearch/cli/Command.java   |  63 +++---
 .../org/elasticsearch/cli/MultiCommand.java   |   4 +-
 .../org/elasticsearch/cli/TestCommand.java    |  41 ----
 .../mapper/attachments/StandaloneRunner.java  | 189 ----------------
 .../bootstrap/BootstrapCliParserTests.java    | 206 +++++-------------
 .../elasticsearch/cli/CommandTestCase.java    |  16 +-
 .../org/elasticsearch/cli/MockTerminal.java   |   4 +-
 10 files changed, 162 insertions(+), 591 deletions(-)
 delete mode 100644 core/src/main/java/org/elasticsearch/cli/TestCommand.java
 delete mode 100644 plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index 215659054d2..73654fdfee5 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -26,7 +26,6 @@ import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.Version;
 import org.elasticsearch.common.PidFile;
 import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.cli.CliTool;
 import org.elasticsearch.common.cli.Terminal;
 import org.elasticsearch.common.inject.CreationException;
 import org.elasticsearch.common.logging.ESLogger;
@@ -218,17 +217,10 @@ final class Bootstrap {
      * This method is invoked by {@link Elasticsearch#main(String[])}
      * to startup elasticsearch.
      */
-    static void init(String[] args) throws Throwable {
+    static void init() throws Throwable {
         // Set the system property before anything has a chance to trigger its use
         initLoggerPrefix();
 
-        BootstrapCLIParser bootstrapCLIParser = new BootstrapCLIParser();
-        CliTool.ExitStatus status = bootstrapCLIParser.execute(args);
-
-        if (CliTool.ExitStatus.OK != status) {
-            exit(status.status());
-        }
-
         INSTANCE = new Bootstrap();
 
         boolean foreground = !"false".equals(System.getProperty("es.foreground", System.getProperty("es-foreground")));
@@ -307,14 +299,6 @@ final class Bootstrap {
         System.err.close();
     }
 
-    @SuppressForbidden(reason = "System#err")
-    private static void sysError(String line, boolean flush) {
-        System.err.println(line);
-        if (flush) {
-            System.err.flush();
-        }
-    }
-
     private static void checkForCustomConfFile() {
         String confFileSetting = System.getProperty("es.default.config");
         checkUnsetAndMaybeExit(confFileSetting, "es.default.config");
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
index ec11a773ccc..3567039cd42 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
@@ -19,165 +19,70 @@
 
 package org.elasticsearch.bootstrap;
 
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
+import java.util.Arrays;
+
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
 import org.elasticsearch.Build;
-import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.CliToolConfig;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Command;
+import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserError;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.Environment;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.cli.Terminal;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
+final class BootstrapCliParser extends Command {
 
-import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd;
-import static org.elasticsearch.common.cli.CliToolConfig.Builder.optionBuilder;
+    private final OptionSpec versionOption;
+    private final OptionSpec daemonizeOption;
+    private final OptionSpec pidfileOption;
+    private final OptionSpec propertyOption;
+    private boolean shouldRun = false;
 
-final class BootstrapCLIParser extends CliTool {
-
-    private static final CliToolConfig CONFIG = CliToolConfig.config("elasticsearch", BootstrapCLIParser.class)
-            .cmds(Start.CMD, Version.CMD)
-            .build();
-
-    public BootstrapCLIParser() {
-        super(CONFIG);
-    }
-
-    public BootstrapCLIParser(Terminal terminal) {
-        super(CONFIG, terminal);
+    BootstrapCliParser() {
+        super("Starts elasticsearch");
+        // TODO: in jopt-simple 5.0, make this mutually exclusive with all other options
+        versionOption = parser.acceptsAll(Arrays.asList("V", "version"),
+            "Prints elasticsearch version information and exits");
+        daemonizeOption = parser.acceptsAll(Arrays.asList("d", "daemonize"),
+            "Starts Elasticsearch in the background");
+        // TODO: in jopt-simple 5.0 this option type can be a Path
+        pidfileOption = parser.acceptsAll(Arrays.asList("p", "pidfile"),
+            "Creates a pid file in the specified path on start")
+            .withRequiredArg();
+        propertyOption = parser.accepts("E", "Configures an Elasticsearch setting")
+            .withRequiredArg();
     }
 
     @Override
-    protected Command parse(String cmdName, CommandLine cli) throws Exception {
-        switch (cmdName.toLowerCase(Locale.ROOT)) {
-            case Start.NAME:
-                return Start.parse(terminal, cli);
-            case Version.NAME:
-                return Version.parse(terminal, cli);
-            default:
-                assert false : "should never get here, if the user enters an unknown command, an error message should be shown before parse is called";
-                return null;
-        }
-    }
-
-    static class Version extends CliTool.Command {
-
-        private static final String NAME = "version";
-
-        private static final CliToolConfig.Cmd CMD = cmd(NAME, Version.class).build();
-
-        public static Command parse(Terminal terminal, CommandLine cli) {
-            return new Version(terminal);
-        }
-
-        public Version(Terminal terminal) {
-            super(terminal);
-        }
-
-        @Override
-        public ExitStatus execute(Settings settings, Environment env) throws Exception {
+    protected void execute(Terminal terminal, OptionSet options) throws Exception {
+        if (options.has(versionOption)) {
             terminal.println("Version: " + org.elasticsearch.Version.CURRENT
-                    + ", Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date()
-                    + ", JVM: " + JvmInfo.jvmInfo().version());
-            return ExitStatus.OK_AND_EXIT;
+                + ", Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date()
+                + ", JVM: " + JvmInfo.jvmInfo().version());
+            return;
         }
+
+        // TODO: don't use sysprops for any of these! pass the args through to bootstrap...
+        if (options.has(daemonizeOption)) {
+            System.setProperty("es.foreground", "false");
+        }
+        String pidFile = pidfileOption.value(options);
+        if (Strings.isNullOrEmpty(pidFile) == false) {
+            System.setProperty("es.pidfile", pidFile);
+        }
+
+        for (String property : propertyOption.values(options)) {
+            String[] keyValue = property.split("=", 2);
+            if (keyValue.length != 2) {
+                throw new UserError(ExitCodes.USAGE, "Malformed elasticsearch setting, must be of the form key=value");
+            }
+            System.setProperty("es." + keyValue[0], keyValue[1]);
+        }
+        shouldRun = true;
     }
 
-    static class Start extends CliTool.Command {
-
-        private static final String NAME = "start";
-
-        private static final CliToolConfig.Cmd CMD = cmd(NAME, Start.class)
-                .options(
-                        optionBuilder("d", "daemonize").hasArg(false).required(false),
-                        optionBuilder("p", "pidfile").hasArg(true).required(false),
-                        optionBuilder("V", "version").hasArg(false).required(false),
-                        Option.builder("D").argName("property=value").valueSeparator('=').numberOfArgs(2)
-                )
-                .stopAtNonOption(true) // needed to parse the --foo.bar options, so this parser must be lenient
-                .build();
-
-        // TODO: don't use system properties as a way to do this, its horrible...
-        @SuppressForbidden(reason = "Sets system properties passed as CLI parameters")
-        public static Command parse(Terminal terminal, CommandLine cli) throws UserError {
-            if (cli.hasOption("V")) {
-                return Version.parse(terminal, cli);
-            }
-
-            if (cli.hasOption("d")) {
-                System.setProperty("es.foreground", "false");
-            }
-
-            String pidFile = cli.getOptionValue("pidfile");
-            if (!Strings.isNullOrEmpty(pidFile)) {
-                System.setProperty("es.pidfile", pidFile);
-            }
-
-            if (cli.hasOption("D")) {
-                Properties properties = cli.getOptionProperties("D");
-                for (Map.Entry entry : properties.entrySet()) {
-                    String key = (String) entry.getKey();
-                    String propertyName = key.startsWith("es.") ? key : "es." + key;
-                    System.setProperty(propertyName, entry.getValue().toString());
-                }
-            }
-
-            // hacky way to extract all the fancy extra args, there is no CLI tool helper for this
-            Iterator iterator = cli.getArgList().iterator();
-            final Map properties = new HashMap<>();
-            while (iterator.hasNext()) {
-                String arg = iterator.next();
-                if (!arg.startsWith("--")) {
-                    if (arg.startsWith("-D") || arg.startsWith("-d") || arg.startsWith("-p")) {
-                        throw new UserError(ExitStatus.USAGE.status(),
-                                "Parameter [" + arg + "] starting with \"-D\", \"-d\" or \"-p\" must be before any parameters starting with --"
-                        );
-                    } else {
-                        throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "]does not start with --");
-                    }
-                }
-                // if there is no = sign, we have to get the next argu
-                arg = arg.replace("--", "");
-                if (arg.contains("=")) {
-                    String[] splitArg = arg.split("=", 2);
-                    String key = splitArg[0];
-                    String value = splitArg[1];
-                    properties.put("es." + key, value);
-                } else {
-                    if (iterator.hasNext()) {
-                        String value = iterator.next();
-                        if (value.startsWith("--")) {
-                            throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "] needs value");
-                        }
-                        properties.put("es." + arg, value);
-                    } else {
-                        throw new UserError(ExitStatus.USAGE.status(), "Parameter [" + arg + "] needs value");
-                    }
-                }
-            }
-            for (Map.Entry entry : properties.entrySet()) {
-                System.setProperty(entry.getKey(), entry.getValue());
-            }
-            return new Start(terminal);
-        }
-
-        public Start(Terminal terminal) {
-            super(terminal);
-
-        }
-
-        @Override
-        public ExitStatus execute(Settings settings, Environment env) throws Exception {
-            return ExitStatus.OK;
-        }
+    boolean shouldRun() {
+        return shouldRun;
     }
-
 }
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
index 107a955696c..214efe483ca 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
@@ -21,6 +21,8 @@ package org.elasticsearch.bootstrap;
 
 import java.io.IOException;
 
+import org.elasticsearch.common.cli.Terminal;
+
 /**
  * This class starts elasticsearch.
  */
@@ -32,9 +34,16 @@ public final class Elasticsearch {
     /**
      * Main entry point for starting elasticsearch
      */
-    public static void main(String[] args) throws StartupError {
+    public static void main(String[] args) throws Exception {
+        BootstrapCliParser parser = new BootstrapCliParser();
+        parser.main(args, Terminal.DEFAULT);
+
+        if (parser.shouldRun() == false) {
+            return;
+        }
+
         try {
-            Bootstrap.init(args);
+            Bootstrap.init();
         } catch (Throwable t) {
             // format exceptions to the console in a special way
             // to avoid 2MB stacktraces from guice, etc.
diff --git a/core/src/main/java/org/elasticsearch/cli/Command.java b/core/src/main/java/org/elasticsearch/cli/Command.java
index 6e57905b5b2..f608d0cefb1 100644
--- a/core/src/main/java/org/elasticsearch/cli/Command.java
+++ b/core/src/main/java/org/elasticsearch/cli/Command.java
@@ -21,6 +21,7 @@ package org.elasticsearch.cli;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.List;
 
 import joptsimple.OptionException;
 import joptsimple.OptionParser;
@@ -49,38 +50,9 @@ public abstract class Command {
     }
 
     /** Parses options for this command from args and executes it. */
-    protected final int main(String[] args, Terminal terminal) throws Exception {
-
-        final OptionSet options;
+    public final int main(String[] args, Terminal terminal) throws Exception {
         try {
-            options = parser.parse(args);
-        } catch (OptionException e) {
-            printHelp(terminal);
-            terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
-            return ExitCodes.USAGE;
-        }
-
-        if (options.has(helpOption)) {
-            printHelp(terminal);
-            return ExitCodes.OK;
-        }
-
-        if (options.has(silentOption)) {
-            if (options.has(verboseOption)) {
-                // mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it
-                printHelp(terminal);
-                terminal.println(Terminal.Verbosity.SILENT, "ERROR: Cannot specify -s and -v together");
-                return ExitCodes.USAGE;
-            }
-            terminal.setVerbosity(Terminal.Verbosity.SILENT);
-        } else if (options.has(verboseOption)) {
-            terminal.setVerbosity(Terminal.Verbosity.VERBOSE);
-        } else {
-            terminal.setVerbosity(Terminal.Verbosity.NORMAL);
-        }
-
-        try {
-            return execute(terminal, options);
+            mainWithoutErrorHandling(args, terminal);
         } catch (OptionException e) {
             printHelp(terminal);
             terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
@@ -89,6 +61,33 @@ public abstract class Command {
             terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
             return e.exitCode;
         }
+        return ExitCodes.OK;
+    }
+
+    /**
+     * Executes the command, but all errors are thrown.
+     */
+    void mainWithoutErrorHandling(String[] args, Terminal terminal) throws Exception {
+        final OptionSet options = parser.parse(args);
+
+        if (options.has(helpOption)) {
+            printHelp(terminal);
+            return;
+        }
+
+        if (options.has(silentOption)) {
+            if (options.has(verboseOption)) {
+                // mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it
+                throw new UserError(ExitCodes.USAGE, "Cannot specify -s and -v together");
+            }
+            terminal.setVerbosity(Terminal.Verbosity.SILENT);
+        } else if (options.has(verboseOption)) {
+            terminal.setVerbosity(Terminal.Verbosity.VERBOSE);
+        } else {
+            terminal.setVerbosity(Terminal.Verbosity.NORMAL);
+        }
+
+        execute(terminal, options);
     }
 
     /** Prints a help message for the command to the terminal. */
@@ -111,5 +110,5 @@ public abstract class Command {
      * Executes this command.
      *
      * Any runtime user errors (like an input file that does not exist), should throw a {@link UserError}. */
-    protected abstract int execute(Terminal terminal, OptionSet options) throws Exception;
+    protected abstract void execute(Terminal terminal, OptionSet options) throws Exception;
 }
diff --git a/core/src/main/java/org/elasticsearch/cli/MultiCommand.java b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
index 94c403d57d0..5862b6f2311 100644
--- a/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
+++ b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
@@ -56,7 +56,7 @@ public class MultiCommand extends Command {
     }
 
     @Override
-    protected int execute(Terminal terminal, OptionSet options) throws Exception {
+    protected void execute(Terminal terminal, OptionSet options) throws Exception {
         if (subcommands.isEmpty()) {
             throw new IllegalStateException("No subcommands configured");
         }
@@ -68,6 +68,6 @@ public class MultiCommand extends Command {
         if (subcommand == null) {
             throw new UserError(ExitCodes.USAGE, "Unknown command [" + args[0] + "]");
         }
-        return subcommand.main(Arrays.copyOfRange(args, 1, args.length), terminal);
+        subcommand.mainWithoutErrorHandling(Arrays.copyOfRange(args, 1, args.length), terminal);
     }
 }
diff --git a/core/src/main/java/org/elasticsearch/cli/TestCommand.java b/core/src/main/java/org/elasticsearch/cli/TestCommand.java
deleted file mode 100644
index fe3fa5c6b8c..00000000000
--- a/core/src/main/java/org/elasticsearch/cli/TestCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.cli;
-
-import joptsimple.OptionSet;
-import org.elasticsearch.common.cli.Terminal;
-
-public class TestCommand extends Command {
-
-    public static void main(String[] args) throws Exception {
-        exit(new TestCommand().main(args, Terminal.DEFAULT));
-    }
-
-    public TestCommand() {
-        super("some test cli");
-        parser.accepts("foo", "some option");
-    }
-
-    @Override
-    protected int execute(Terminal terminal, OptionSet options) throws Exception {
-        terminal.println("running");
-        return ExitCodes.OK;
-    }
-}
diff --git a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java b/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java
deleted file mode 100644
index 03c6e65047a..00000000000
--- a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.mapper.attachments;
-
-import org.apache.commons.cli.CommandLine;
-import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.bytes.BytesReference;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.CliToolConfig;
-import org.elasticsearch.common.cli.Terminal;
-import org.elasticsearch.common.compress.CompressedXContent;
-import org.elasticsearch.common.io.PathUtils;
-import org.elasticsearch.common.io.stream.BytesStreamOutput;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.env.Environment;
-import org.elasticsearch.index.MapperTestUtils;
-import org.elasticsearch.index.mapper.DocumentMapper;
-import org.elasticsearch.index.mapper.DocumentMapperParser;
-import org.elasticsearch.index.mapper.ParseContext;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Locale;
-
-import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd;
-import static org.elasticsearch.common.cli.CliToolConfig.Builder.option;
-import static org.elasticsearch.common.io.Streams.copy;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-import static org.elasticsearch.mapper.attachments.AttachmentUnitTestCase.getIndicesModuleWithRegisteredAttachmentMapper;
-import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
-
-/**
- * This class provides a simple main class which can be used to test what is extracted from a given binary file.
- * You can run it using
- *  -u file://URL/TO/YOUR/DOC
- *  --size set extracted size (default to mapper attachment size)
- *  BASE64 encoded binary
- *
- * Example:
- *  StandaloneRunner BASE64Text
- *  StandaloneRunner -u /tmp/mydoc.pdf
- *  StandaloneRunner -u /tmp/mydoc.pdf --size 1000000
- */
-@SuppressForbidden(reason = "commandline tool")
-public class StandaloneRunner extends CliTool {
-
-    private static final CliToolConfig CONFIG = CliToolConfig.config("tika", StandaloneRunner.class)
-                        .cmds(TikaRunner.CMD)
-                .build();
-
-    static {
-        System.setProperty("es.path.home", "/tmp");
-    }
-
-    static class TikaRunner extends Command {
-        private static final String NAME = "tika";
-        private final String url;
-        private final Integer size;
-        private final String base64text;
-        private final DocumentMapper docMapper;
-
-        private static final CliToolConfig.Cmd CMD = cmd(NAME, TikaRunner.class)
-                .options(option("u", "url").required(false).hasArg(false))
-                .options(option("t", "size").required(false).hasArg(false))
-                .build();
-
-        protected TikaRunner(Terminal terminal, String url, Integer size, String base64text) throws IOException {
-            super(terminal);
-            this.size = size;
-            this.url = url;
-            this.base64text = base64text;
-            DocumentMapperParser mapperParser = MapperTestUtils.newMapperService(PathUtils.get("."), Settings.EMPTY, getIndicesModuleWithRegisteredAttachmentMapper()).documentMapperParser(); // use CWD b/c it won't be used
-
-            String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/attachment/test/standalone/standalone-mapping.json");
-            docMapper = mapperParser.parse("person", new CompressedXContent(mapping));
-        }
-
-        @Override
-        public ExitStatus execute(Settings settings, Environment env) throws Exception {
-            XContentBuilder builder = jsonBuilder().startObject().field("file").startObject();
-
-            if (base64text != null) {
-                // If base64 is provided
-                builder.field("_content", base64text);
-            } else {
-                // A file is provided
-                byte[] bytes = copyToBytes(PathUtils.get(url));
-                builder.field("_content", bytes);
-            }
-
-            if (size >= 0) {
-                builder.field("_indexed_chars", size);
-            }
-
-            BytesReference json = builder.endObject().endObject().bytes();
-
-            ParseContext.Document doc = docMapper.parse("person", "person", "1", json).rootDoc();
-
-            terminal.println("## Extracted text");
-            terminal.println("--------------------- BEGIN -----------------------");
-            terminal.println(doc.get("file.content"));
-            terminal.println("---------------------- END ------------------------");
-            terminal.println("## Metadata");
-            printMetadataContent(doc, AttachmentMapper.FieldNames.AUTHOR);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.CONTENT_LENGTH);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.CONTENT_TYPE);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.DATE);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.KEYWORDS);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.LANGUAGE);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.NAME);
-            printMetadataContent(doc, AttachmentMapper.FieldNames.TITLE);
-
-            return ExitStatus.OK;
-        }
-
-        private void printMetadataContent(ParseContext.Document doc, String field) {
-            terminal.println("- " + field + ":" + doc.get(docMapper.mappers().getMapper("file." + field).fieldType().name()));
-        }
-
-        public static byte[] copyToBytes(Path path) throws IOException {
-            try (InputStream is = Files.newInputStream(path);
-                 BytesStreamOutput out = new BytesStreamOutput()) {
-                copy(is, out);
-                return out.bytes().toBytes();
-            }
-        }
-
-        public static Command parse(Terminal terminal, CommandLine cli) throws IOException {
-            String url = cli.getOptionValue("u");
-            String base64text = null;
-            String sSize = cli.getOptionValue("size");
-            Integer size = sSize != null ? Integer.parseInt(sSize) : -1;
-            if (url == null && cli.getArgs().length == 0) {
-                    return exitCmd(ExitStatus.USAGE, terminal, "url or BASE64 content should be provided (type -h for help)");
-            }
-            if (url == null) {
-                if (cli.getArgs().length == 0) {
-                    return exitCmd(ExitStatus.USAGE, terminal, "url or BASE64 content should be provided (type -h for help)");
-                }
-                base64text = cli.getArgs()[0];
-            } else {
-                if (cli.getArgs().length == 1) {
-                    return exitCmd(ExitStatus.USAGE, terminal, "url or BASE64 content should be provided. Not both. (type -h for help)");
-                }
-            }
-            return new TikaRunner(terminal, url, size, base64text);
-        }
-    }
-
-    public StandaloneRunner() {
-        super(CONFIG);
-    }
-
-
-    public static void main(String[] args) throws Exception {
-        StandaloneRunner pluginManager = new StandaloneRunner();
-        pluginManager.execute(args);
-    }
-
-    @Override
-    protected Command parse(String cmdName, CommandLine cli) throws Exception {
-        switch (cmdName.toLowerCase(Locale.ROOT)) {
-            case TikaRunner.NAME: return TikaRunner.parse(terminal, cli);
-            default:
-                    assert false : "can't get here as cmd name is validated before this method is called";
-                    return exitCmd(ExitStatus.CODE_ERROR);
-        }
-    }
-}
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
index 18d6e0ac3c9..726d17b0938 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
@@ -19,11 +19,14 @@
 
 package org.elasticsearch.bootstrap;
 
+import joptsimple.OptionException;
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;
+import org.elasticsearch.cli.Command;
+import org.elasticsearch.cli.CommandTestCase;
+import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.common.SuppressForbidden;
 import org.elasticsearch.common.cli.CliTool.ExitStatus;
-import org.elasticsearch.common.cli.CliToolTestCase;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.common.collect.Tuple;
@@ -46,9 +49,13 @@ import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 
 @SuppressForbidden(reason = "modifies system properties intentionally")
-public class BootstrapCliParserTests extends CliToolTestCase {
+public class BootstrapCliParserTests extends CommandTestCase {
+
+    @Override
+    protected Command newCommand() {
+        return new BootstrapCliParser();
+    }
 
-    private MockTerminal terminal = new MockTerminal();
     private List propertiesToClear = new ArrayList<>();
     private Map properties;
 
@@ -66,195 +73,86 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         assertEquals("properties leaked", properties, new HashMap<>(System.getProperties()));
     }
 
-    public void testThatVersionIsReturned() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        ExitStatus status = parser.execute(args("version"));
-        assertStatus(status, OK_AND_EXIT);
-
-        String output = terminal.getOutput();
-        assertTrue(output, output.contains(Version.CURRENT.toString()));
-        assertTrue(output, output.contains(Build.CURRENT.shortHash()));
-        assertTrue(output, output.contains(Build.CURRENT.date()));
-        assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
+    void assertShouldRun(boolean shouldRun) {
+        BootstrapCliParser parser = (BootstrapCliParser)command;
+        assertEquals(shouldRun, parser.shouldRun());
     }
 
-    public void testThatVersionIsReturnedAsStartParameter() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        ExitStatus status = parser.execute(args("start -V"));
-        assertStatus(status, OK_AND_EXIT);
-
-        String output = terminal.getOutput();
+    public void testVersion() throws Exception {
+        String output = execute("-V");
         assertTrue(output, output.contains(Version.CURRENT.toString()));
         assertTrue(output, output.contains(Build.CURRENT.shortHash()));
         assertTrue(output, output.contains(Build.CURRENT.date()));
         assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
+        assertShouldRun(false);
 
         terminal.reset();
-        parser = new BootstrapCLIParser(terminal);
-        status = parser.execute(args("start --version"));
-        assertStatus(status, OK_AND_EXIT);
-
-        output = terminal.getOutput();
+        output = execute("--version");
         assertTrue(output, output.contains(Version.CURRENT.toString()));
         assertTrue(output, output.contains(Build.CURRENT.shortHash()));
         assertTrue(output, output.contains(Build.CURRENT.date()));
         assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
+        assertShouldRun(false);
     }
 
-    public void testThatPidFileCanBeConfigured() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
+    public void testPidfile() throws Exception {
         registerProperties("es.pidfile");
 
-        ExitStatus status = parser.execute(args("start --pidfile")); // missing pid file
-        assertStatus(status, USAGE);
+        // missing argument
+        OptionException e = expectThrows(OptionException.class, () -> {
+           execute("-p");
+        });
+        assertEquals("Option p/pidfile requires an argument", e.getMessage());
+        assertShouldRun(false);
 
         // good cases
-        status = parser.execute(args("start --pidfile /tmp/pid"));
-        assertStatus(status, OK);
+        terminal.reset();
+        execute("--pidfile", "/tmp/pid");
         assertSystemProperty("es.pidfile", "/tmp/pid");
+        assertShouldRun(true);
 
         System.clearProperty("es.pidfile");
-        status = parser.execute(args("start -p /tmp/pid"));
-        assertStatus(status, OK);
+        terminal.reset();
+        execute("-p", "/tmp/pid");
         assertSystemProperty("es.pidfile", "/tmp/pid");
+        assertShouldRun(true);
     }
 
-    public void testThatParsingDaemonizeWorks() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
+    public void testNoDaemonize() throws Exception {
         registerProperties("es.foreground");
 
-        ExitStatus status = parser.execute(args("start -d"));
-        assertStatus(status, OK);
-        assertThat(System.getProperty("es.foreground"), is("false"));
+        execute();
+        assertSystemProperty("es.foreground", null);
+        assertShouldRun(true);
     }
 
-    public void testThatNotDaemonizingDoesNotConfigureProperties() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
+    public void testDaemonize() throws Exception {
         registerProperties("es.foreground");
 
-        ExitStatus status = parser.execute(args("start"));
-        assertStatus(status, OK);
-        assertThat(System.getProperty("es.foreground"), is(nullValue()));
+        execute("-d");
+        assertSystemProperty("es.foreground", "false");
+        assertShouldRun(true);
+
+        System.clearProperty("es.foreground");
+        execute("--daemonize");
+        assertSystemProperty("es.foreground", "false");
+        assertShouldRun(true);
     }
 
-    public void testThatJavaPropertyStyleArgumentsCanBeParsed() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
+    public void testConfig() throws Exception {
         registerProperties("es.foo", "es.spam");
 
-        ExitStatus status = parser.execute(args("start -Dfoo=bar -Dspam=eggs"));
-        assertStatus(status, OK);
+        execute("-Efoo=bar", "-Espam=eggs");
         assertSystemProperty("es.foo", "bar");
         assertSystemProperty("es.spam", "eggs");
+        assertShouldRun(true);
     }
 
-    public void testThatJavaPropertyStyleArgumentsWithEsPrefixAreNotPrefixedTwice() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        registerProperties("es.spam", "es.pidfile");
-
-        ExitStatus status = parser.execute(args("start -Des.pidfile=/path/to/foo/elasticsearch/distribution/zip/target/integ-tests/es.pid -Dspam=eggs"));
-        assertStatus(status, OK);
-        assertThat(System.getProperty("es.es.pidfile"), is(nullValue()));
-        assertSystemProperty("es.pidfile", "/path/to/foo/elasticsearch/distribution/zip/target/integ-tests/es.pid");
-        assertSystemProperty("es.spam", "eggs");
-    }
-
-    public void testThatUnknownLongOptionsCanBeParsed() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        registerProperties("es.network.host", "es.my.option");
-
-        ExitStatus status = parser.execute(args("start --network.host 127.0.0.1 --my.option=true"));
-        assertStatus(status, OK);
-        assertSystemProperty("es.network.host", "127.0.0.1");
-        assertSystemProperty("es.my.option", "true");
-    }
-
-    public void testThatUnknownLongOptionsNeedAValue() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        registerProperties("es.network.host");
-
-        ExitStatus status = parser.execute(args("start --network.host"));
-        assertStatus(status, USAGE);
-        String output = terminal.getOutput();
-        assertTrue(output, output.contains("Parameter [network.host] needs value"));
-
-        terminal.reset();
-        status = parser.execute(args("start --network.host --foo"));
-        assertStatus(status, USAGE);
-        output = terminal.getOutput();
-        assertTrue(output, output.contains("Parameter [network.host] needs value"));
-    }
-
-    public void testParsingErrors() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-
-        // unknown params
-        ExitStatus status = parser.execute(args("version --unknown-param /tmp/pid"));
-        assertStatus(status, USAGE);
-        String output = terminal.getOutput();
-        assertTrue(output, output.contains("Unrecognized option: --unknown-param"));
-
-        // single dash in extra params
-        terminal.reset();
-        parser = new BootstrapCLIParser(terminal);
-        status = parser.execute(args("start -network.host 127.0.0.1"));
-        assertStatus(status, USAGE);
-        output = terminal.getOutput();
-        assertTrue(output, output.contains("Parameter [-network.host]does not start with --"));
-
-        // never ended parameter
-        terminal = new MockTerminal();
-        parser = new BootstrapCLIParser(terminal);
-        status = parser.execute(args("start --network.host"));
-        assertStatus(status, USAGE);
-        output = terminal.getOutput();
-        assertTrue(output, output.contains("Parameter [network.host] needs value"));
-
-        // free floating value
-        terminal = new MockTerminal();
-        parser = new BootstrapCLIParser(terminal);
-        status = parser.execute(args("start 127.0.0.1"));
-        assertStatus(status, USAGE);
-        output = terminal.getOutput();
-        assertTrue(output, output.contains("Parameter [127.0.0.1]does not start with --"));
-    }
-
-    public void testHelpWorks() throws Exception {
-        List> tuples = new ArrayList<>();
-        tuples.add(new Tuple<>("version --help", "elasticsearch-version.help"));
-        tuples.add(new Tuple<>("version -h", "elasticsearch-version.help"));
-        tuples.add(new Tuple<>("start --help", "elasticsearch-start.help"));
-        tuples.add(new Tuple<>("start -h", "elasticsearch-start.help"));
-        tuples.add(new Tuple<>("--help", "elasticsearch.help"));
-        tuples.add(new Tuple<>("-h", "elasticsearch.help"));
-
-        for (Tuple tuple : tuples) {
-            terminal.reset();
-            BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-            ExitStatus status = parser.execute(args(tuple.v1()));
-            assertStatus(status, OK_AND_EXIT);
-            assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/bootstrap/" + tuple.v2());
-        }
-    }
-
-    public void testThatSpacesInParametersAreSupported() throws Exception {
-        // emulates: bin/elasticsearch --node.name "'my node with spaces'" --pidfile "'/tmp/my pid.pid'"
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
-        registerProperties("es.pidfile", "es.my.param");
-
-        ExitStatus status = parser.execute("start", "--pidfile", "foo with space", "--my.param", "my awesome neighbour");
-        assertStatus(status, OK);
-        assertSystemProperty("es.pidfile", "foo with space");
-        assertSystemProperty("es.my.param", "my awesome neighbour");
-
-    }
-
-    public void testThatHelpfulErrorMessageIsGivenWhenParametersAreOutOfOrder() throws Exception {
-        BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
+    public void testConfigMalformed() throws Exception {
         UserError e = expectThrows(UserError.class, () -> {
-                parser.parse("start", new String[]{"--foo=bar", "-Dbaz=qux"});
+            execute("-Efoo");
         });
-        assertThat(e.getMessage(), containsString("must be before any parameters starting with --"));
-        assertNull(System.getProperty("es.foo"));
+        assertTrue(e.getMessage(), e.getMessage().contains("Malformed elasticsearch setting"));
     }
 
     private void registerProperties(String ... systemProperties) {
@@ -265,8 +163,4 @@ public class BootstrapCliParserTests extends CliToolTestCase {
         String msg = String.format(Locale.ROOT, "Expected property %s to be %s, terminal output was %s", name, expectedValue, terminal.getOutput());
         assertThat(msg, System.getProperty(name), is(expectedValue));
     }
-
-    private void assertStatus(ExitStatus status, ExitStatus expectedStatus) throws Exception {
-        assertThat(String.format(Locale.ROOT, "Expected status to be [%s], but was [%s], terminal output was %s", expectedStatus, status, terminal.getOutput()), status, is(expectedStatus));
-    }
 }
diff --git a/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
index 3af25509adb..a9b31b636cc 100644
--- a/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
@@ -29,20 +29,30 @@ import org.junit.Before;
  */
 public abstract class CommandTestCase extends ESTestCase {
 
+    /** The terminal that execute uses. */
     protected final MockTerminal terminal = new MockTerminal();
 
+    /** The last command that was executed. */
+    protected Command command;
+
     @Before
     public void resetTerminal() {
         terminal.reset();
         terminal.setVerbosity(Terminal.Verbosity.NORMAL);
     }
 
+    /** Creates a Command to test execution. */
     protected abstract Command newCommand();
 
+    /**
+     * Runs the command with the given args.
+     *
+     * Output can be found in {@link #terminal}.
+     * The command created can be found in {@link #command}.
+     */
     public String execute(String... args) throws Exception {
-        Command command = newCommand();
-        OptionSet options = command.parser.parse(args);
-        command.execute(terminal, options);
+        command = newCommand();
+        command.mainWithoutErrorHandling(args, terminal);
         return terminal.getOutput();
     }
 }
diff --git a/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
index bb01369ac50..b712b216f9a 100644
--- a/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
+++ b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
@@ -47,7 +47,7 @@ public class MockTerminal extends Terminal {
     @Override
     public String readText(String prompt) {
         if (textInput.isEmpty()) {
-            return null;
+            throw new IllegalStateException("No text input configured for prompt [" + prompt + "]");
         }
         return textInput.removeFirst();
     }
@@ -55,7 +55,7 @@ public class MockTerminal extends Terminal {
     @Override
     public char[] readSecret(String prompt) {
         if (secretInput.isEmpty()) {
-            return null;
+            throw new IllegalStateException("No secret input configured for prompt [" + prompt + "]");
         }
         return secretInput.removeFirst().toCharArray();
     }

From 3836f3a73600b7af4751a90d21ac8ef076e9ad7b Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 13:40:39 -0800
Subject: [PATCH 21/49] Remove reference to standalonerunner

---
 .../common/cli/CliToolConfig.java             | 53 -------------------
 .../plugins/InstallPluginCommand.java         | 21 ++++----
 .../plugins/ListPluginsCommand.java           |  4 +-
 .../plugins/RemovePluginCommand.java          |  3 +-
 .../elasticsearch/plugins/PluginCliTests.java | 30 ++++++++++-
 docs/plugins/mapper-attachments.asciidoc      | 38 -------------
 6 files changed, 41 insertions(+), 108 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java b/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
index d0ba897b33d..ff752f45ef0 100644
--- a/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
+++ b/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
@@ -33,10 +33,6 @@ import java.util.Map;
  */
 public class CliToolConfig {
 
-    public static Builder config(String name, Class toolType) {
-        return new Builder(name, toolType);
-    }
-
     private final Class toolType;
     private final String name;
     private final Map cmds;
@@ -82,55 +78,6 @@ public class CliToolConfig {
         helpPrinter.print(this, terminal);
     }
 
-    public static class Builder {
-
-        public static Cmd.Builder cmd(String name, Class cmdType) {
-            return new Cmd.Builder(name, cmdType);
-        }
-
-        public static OptionBuilder option(String shortName, String longName) {
-            return new OptionBuilder(shortName, longName);
-        }
-
-        public static Option.Builder optionBuilder(String shortName, String longName) {
-            return Option.builder(shortName).argName(longName).longOpt(longName);
-        }
-
-        public static OptionGroupBuilder optionGroup(boolean required) {
-            return new OptionGroupBuilder(required);
-        }
-
-        private final Class toolType;
-        private final String name;
-        private Cmd[] cmds;
-
-        private Builder(String name, Class toolType) {
-            this.name = name;
-            this.toolType = toolType;
-        }
-
-        public Builder cmds(Cmd.Builder... cmds) {
-            this.cmds = new Cmd[cmds.length];
-            for (int i = 0; i < cmds.length; i++) {
-                this.cmds[i] = cmds[i].build();
-                this.cmds[i].toolName = name;
-            }
-            return this;
-        }
-
-        public Builder cmds(Cmd... cmds) {
-            for (int i = 0; i < cmds.length; i++) {
-                cmds[i].toolName = name;
-            }
-            this.cmds = cmds;
-            return this;
-        }
-
-        public CliToolConfig build() {
-            return new CliToolConfig(name, toolType, cmds);
-        }
-    }
-
     public static class Cmd {
 
         private String toolName;
diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
index bbe00fddd8c..83273e6c1c4 100644
--- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
@@ -145,7 +145,7 @@ class InstallPluginCommand extends Command {
     }
 
     @Override
-    protected int execute(Terminal terminal, OptionSet options) throws Exception {
+    protected void execute(Terminal terminal, OptionSet options) throws Exception {
         // TODO: in jopt-simple 5.0 we can enforce a min/max number of positional args
         List args = arguments.values(options);
         if (args.size() != 1) {
@@ -154,7 +154,6 @@ class InstallPluginCommand extends Command {
         String pluginId = args.get(0);
         boolean isBatch = options.has(batchOption) || System.console() == null;
         execute(terminal, pluginId, isBatch);
-        return ExitCodes.OK;
     }
 
     // pkg private for testing
@@ -222,14 +221,14 @@ class InstallPluginCommand extends Command {
             BufferedReader checksumReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
             expectedChecksum = checksumReader.readLine();
             if (checksumReader.readLine() != null) {
-                throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "Invalid checksum file at " + checksumUrl);
+                throw new UserError(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl);
             }
         }
 
         byte[] zipbytes = Files.readAllBytes(zip);
         String gotChecksum = MessageDigests.toHexString(MessageDigests.sha1().digest(zipbytes));
         if (expectedChecksum.equals(gotChecksum) == false) {
-            throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "SHA1 mismatch, expected " + expectedChecksum + " but got " + gotChecksum);
+            throw new UserError(ExitCodes.IO_ERROR, "SHA1 mismatch, expected " + expectedChecksum + " but got " + gotChecksum);
         }
 
         return zip;
@@ -271,7 +270,7 @@ class InstallPluginCommand extends Command {
         Files.delete(zip);
         if (hasEsDir == false) {
             IOUtils.rm(target);
-            throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "`elasticsearch` directory is missing in the plugin zip");
+            throw new UserError(ExitCodes.DATA_ERROR, "`elasticsearch` directory is missing in the plugin zip");
         }
         return target;
     }
@@ -285,7 +284,7 @@ class InstallPluginCommand extends Command {
         // don't let luser install plugin as a module...
         // they might be unavoidably in maven central and are packaged up the same way)
         if (MODULES.contains(info.getName())) {
-            throw new UserError(CliTool.ExitStatus.USAGE.status(), "plugin '" + info.getName() + "' cannot be installed like this, it is a system module");
+            throw new UserError(ExitCodes.USAGE, "plugin '" + info.getName() + "' cannot be installed like this, it is a system module");
         }
 
         // check for jar hell before any copying
@@ -341,7 +340,7 @@ class InstallPluginCommand extends Command {
 
             final Path destination = env.pluginsFile().resolve(info.getName());
             if (Files.exists(destination)) {
-                throw new UserError(CliTool.ExitStatus.USAGE.status(), "plugin directory " + destination.toAbsolutePath() + " already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command");
+                throw new UserError(ExitCodes.USAGE, "plugin directory " + destination.toAbsolutePath() + " already exists. To update the plugin, uninstall it first using 'remove " + info.getName() + "' command");
             }
 
             Path tmpBinDir = tmpRoot.resolve("bin");
@@ -374,7 +373,7 @@ class InstallPluginCommand extends Command {
     /** Copies the files from {@code tmpBinDir} into {@code destBinDir}, along with permissions from dest dirs parent. */
     private void installBin(PluginInfo info, Path tmpBinDir, Path destBinDir) throws Exception {
         if (Files.isDirectory(tmpBinDir) == false) {
-            throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "bin in plugin " + info.getName() + " is not a directory");
+            throw new UserError(ExitCodes.IO_ERROR, "bin in plugin " + info.getName() + " is not a directory");
         }
         Files.createDirectory(destBinDir);
 
@@ -392,7 +391,7 @@ class InstallPluginCommand extends Command {
         try (DirectoryStream stream  = Files.newDirectoryStream(tmpBinDir)) {
             for (Path srcFile : stream) {
                 if (Files.isDirectory(srcFile)) {
-                    throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName());
+                    throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in bin dir for plugin " + info.getName() + ", found " + srcFile.getFileName());
                 }
 
                 Path destFile = destBinDir.resolve(tmpBinDir.relativize(srcFile));
@@ -413,7 +412,7 @@ class InstallPluginCommand extends Command {
      */
     private void installConfig(PluginInfo info, Path tmpConfigDir, Path destConfigDir) throws Exception {
         if (Files.isDirectory(tmpConfigDir) == false) {
-            throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "config in plugin " + info.getName() + " is not a directory");
+            throw new UserError(ExitCodes.IO_ERROR, "config in plugin " + info.getName() + " is not a directory");
         }
 
         // create the plugin's config dir "if necessary"
@@ -422,7 +421,7 @@ class InstallPluginCommand extends Command {
         try (DirectoryStream stream  = Files.newDirectoryStream(tmpConfigDir)) {
             for (Path srcFile : stream) {
                 if (Files.isDirectory(srcFile)) {
-                    throw new UserError(CliTool.ExitStatus.DATA_ERROR.status(), "Directories not allowed in config dir for plugin " + info.getName());
+                    throw new UserError(ExitCodes.DATA_ERROR, "Directories not allowed in config dir for plugin " + info.getName());
                 }
 
                 Path destFile = destConfigDir.resolve(tmpConfigDir.relativize(srcFile));
diff --git a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
index 142a18cbde5..276e38f1595 100644
--- a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
@@ -44,7 +44,7 @@ class ListPluginsCommand extends Command {
     }
 
     @Override
-    public int execute(Terminal terminal, OptionSet options) throws Exception {
+    protected void execute(Terminal terminal, OptionSet options) throws Exception {
         if (Files.exists(env.pluginsFile()) == false) {
             throw new IOException("Plugins directory missing: " + env.pluginsFile());
         }
@@ -55,7 +55,5 @@ class ListPluginsCommand extends Command {
                 terminal.println(plugin.getFileName().toString());
             }
         }
-
-        return ExitCodes.OK;
     }
 }
diff --git a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
index 10a73a0fc9a..f435a16edf0 100644
--- a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
@@ -53,14 +53,13 @@ class RemovePluginCommand extends Command {
     }
 
     @Override
-    public int execute(Terminal terminal, OptionSet options) throws Exception {
+    protected void execute(Terminal terminal, OptionSet options) throws Exception {
         // TODO: in jopt-simple 5.0 we can enforce a min/max number of positional args
         List args = arguments.values(options);
         if (args.size() != 1) {
             throw new UserError(ExitCodes.USAGE, "Must supply a single plugin id argument");
         }
         execute(terminal, args.get(0));
-        return ExitCodes.OK;
     }
 
     // pkg private for testing
diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
index 708cefd91b2..73d97949571 100644
--- a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
+++ b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
@@ -19,13 +19,40 @@
 
 package org.elasticsearch.plugins;
 
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.elasticsearch.cli.Command;
+import org.elasticsearch.cli.CommandTestCase;
 import org.elasticsearch.common.cli.CliToolTestCase;
 import org.elasticsearch.cli.MockTerminal;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.env.Environment;
+import org.junit.Before;
 
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.is;
 
-public class PluginCliTests extends CliToolTestCase {
+public class PluginCliTests extends CommandTestCase {
+
+    // the home dir for each test to use
+    Path homeDir;
+
+    // settings used to create an Environment for tools
+    Settings.Builder settingsBuilder;
+
+    @Before
+    public void setupHome() {
+        homeDir = createTempDir();
+        settingsBuilder = Settings.builder()
+            .put("path.home", homeDir);
+    }
+
+    @Override
+    protected Command newCommand() {
+        return new PluginCli(new Environment(settingsBuilder.build()));
+    }
+
     public void testHelpWorks() throws Exception {
         MockTerminal terminal = new MockTerminal();
         /* nocommit
@@ -48,4 +75,5 @@ public class PluginCliTests extends CliToolTestCase {
         assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin-list.help");
         */
     }
+
 }
diff --git a/docs/plugins/mapper-attachments.asciidoc b/docs/plugins/mapper-attachments.asciidoc
index ed992623a50..0ad452d92e9 100644
--- a/docs/plugins/mapper-attachments.asciidoc
+++ b/docs/plugins/mapper-attachments.asciidoc
@@ -405,41 +405,3 @@ It gives back:
    }
 }
 --------------------------
-
-[[mapper-attachments-standalone]]
-==== Stand alone runner
-
-If you want to run some tests within your IDE, you can use `StandaloneRunner` class.
-It accepts arguments:
-
-* `-u file://URL/TO/YOUR/DOC`
-* `--size` set extracted size (default to mapper attachment size)
-* `BASE64` encoded binary
-
-Example:
-
-[source,sh]
---------------------------
-StandaloneRunner BASE64Text
-StandaloneRunner -u /tmp/mydoc.pdf
-StandaloneRunner -u /tmp/mydoc.pdf --size 1000000
---------------------------
-
-It produces something like:
-
-[source,text]
---------------------------
-## Extracted text
---------------------- BEGIN -----------------------
-This is the extracted text
----------------------- END ------------------------
-## Metadata
-- author: null
-- content_length: null
-- content_type: application/pdf
-- date: null
-- keywords: null
-- language: null
-- name: null
-- title: null
---------------------------

From 80198accc11aee7672a309917686cd93cf2a8f86 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 14:13:55 -0800
Subject: [PATCH 22/49] Removed old cli stuff, and add tests for new Command
 behavior

---
 .../elasticsearch/bootstrap/Bootstrap.java    |   2 +-
 .../bootstrap/BootstrapCLIParser.java         |   2 +-
 .../bootstrap/Elasticsearch.java              |   2 +-
 .../java/org/elasticsearch/cli/Command.java   |   2 -
 .../org/elasticsearch/cli/MultiCommand.java   |   2 -
 .../{common => }/cli/Terminal.java            |   2 +-
 .../org/elasticsearch/common/cli/CliTool.java | 252 ------------------
 .../common/cli/CliToolConfig.java             | 249 -----------------
 .../elasticsearch/common/cli/HelpPrinter.java |  57 ----
 .../common/logging/TerminalAppender.java      |   2 +-
 .../internal/InternalSettingsPreparer.java    |   2 +-
 .../plugins/InstallPluginCommand.java         |   5 +-
 .../plugins/ListPluginsCommand.java           |   4 +-
 .../org/elasticsearch/plugins/PluginCli.java  |   2 +-
 .../elasticsearch/plugins/PluginSecurity.java |   4 +-
 .../plugins/RemovePluginCommand.java          |   9 +-
 .../org/elasticsearch/cli/CommandTests.java   | 123 +++++++++
 .../elasticsearch/cli/MultiCommandTests.java  |  28 ++
 .../{common => }/cli/TerminalTests.java       |   3 +-
 .../bootstrap/BootstrapCliParserTests.java    |  31 +--
 .../plugins/PluginSecurityTests.java          |   2 +-
 .../elasticsearch/cli/CommandTestCase.java    |   2 -
 .../org/elasticsearch/cli/MockTerminal.java   |   2 -
 23 files changed, 180 insertions(+), 609 deletions(-)
 rename core/src/main/java/org/elasticsearch/{common => }/cli/Terminal.java (99%)
 delete mode 100644 core/src/main/java/org/elasticsearch/common/cli/CliTool.java
 delete mode 100644 core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
 delete mode 100644 core/src/main/java/org/elasticsearch/common/cli/HelpPrinter.java
 create mode 100644 core/src/test/java/org/elasticsearch/cli/CommandTests.java
 create mode 100644 core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
 rename core/src/test/java/org/elasticsearch/{common => }/cli/TerminalTests.java (96%)

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index 73654fdfee5..5008229f5f8 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -26,7 +26,7 @@ import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.Version;
 import org.elasticsearch.common.PidFile;
 import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.common.inject.CreationException;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.LogConfigurator;
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
index 3567039cd42..e44e397f67a 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
@@ -28,7 +28,7 @@ import org.elasticsearch.cli.Command;
 import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 
 final class BootstrapCliParser extends Command {
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
index 214efe483ca..1d2a0b98232 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
@@ -21,7 +21,7 @@ package org.elasticsearch.bootstrap;
 
 import java.io.IOException;
 
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 
 /**
  * This class starts elasticsearch.
diff --git a/core/src/main/java/org/elasticsearch/cli/Command.java b/core/src/main/java/org/elasticsearch/cli/Command.java
index f608d0cefb1..9e6afdd6638 100644
--- a/core/src/main/java/org/elasticsearch/cli/Command.java
+++ b/core/src/main/java/org/elasticsearch/cli/Command.java
@@ -21,14 +21,12 @@ package org.elasticsearch.cli;
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.List;
 
 import joptsimple.OptionException;
 import joptsimple.OptionParser;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.cli.Terminal;
 
 /**
  * An action to execute within a cli.
diff --git a/core/src/main/java/org/elasticsearch/cli/MultiCommand.java b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
index 5862b6f2311..a9feee0c9bf 100644
--- a/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
+++ b/core/src/main/java/org/elasticsearch/cli/MultiCommand.java
@@ -19,14 +19,12 @@
 
 package org.elasticsearch.cli;
 
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
 import joptsimple.NonOptionArgumentSpec;
 import joptsimple.OptionSet;
-import org.elasticsearch.common.cli.Terminal;
 
 /**
  * A cli tool which is made up of multiple subcommands.
diff --git a/core/src/main/java/org/elasticsearch/common/cli/Terminal.java b/core/src/main/java/org/elasticsearch/cli/Terminal.java
similarity index 99%
rename from core/src/main/java/org/elasticsearch/common/cli/Terminal.java
rename to core/src/main/java/org/elasticsearch/cli/Terminal.java
index 6a1c4382e42..00d886aa8ab 100644
--- a/core/src/main/java/org/elasticsearch/common/cli/Terminal.java
+++ b/core/src/main/java/org/elasticsearch/cli/Terminal.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.elasticsearch.common.cli;
+package org.elasticsearch.cli;
 
 import java.io.BufferedReader;
 import java.io.Console;
diff --git a/core/src/main/java/org/elasticsearch/common/cli/CliTool.java b/core/src/main/java/org/elasticsearch/common/cli/CliTool.java
deleted file mode 100644
index ba2007813d5..00000000000
--- a/core/src/main/java/org/elasticsearch/common/cli/CliTool.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.common.cli;
-
-import org.apache.commons.cli.AlreadySelectedException;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.MissingArgumentException;
-import org.apache.commons.cli.MissingOptionException;
-import org.apache.commons.cli.UnrecognizedOptionException;
-import org.elasticsearch.cli.UserError;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.Environment;
-import org.elasticsearch.node.internal.InternalSettingsPreparer;
-
-import java.util.Locale;
-
-import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
-
-/**
- * A base class for command-line interface tool.
- *
- * Two modes are supported:
- *
- * - Single command mode. The tool exposes a single command that can potentially accept arguments (eg. CLI options).
- * - Multi command mode. The tool support multiple commands, each for different tasks, each potentially accepts arguments.
- *
- * In a multi-command mode. The first argument must be the command name. For example, the plugin manager
- * can be seen as a multi-command tool with two possible commands: install and uninstall
- *
- * The tool is configured using a {@link CliToolConfig} which encapsulates the tool's commands and their
- * potential options. The tool also comes with out of the box simple help support (the -h/--help option is
- * automatically handled) where the help text is configured in a dedicated *.help files located in the same package
- * as the tool.
- */
-public abstract class CliTool {
-
-    // based on sysexits.h
-    public enum ExitStatus {
-        OK(0),
-        OK_AND_EXIT(0),
-        USAGE(64),          /* command line usage error */
-        DATA_ERROR(65),     /* data format error */
-        NO_INPUT(66),       /* cannot open input */
-        NO_USER(67),        /* addressee unknown */
-        NO_HOST(68),        /* host name unknown */
-        UNAVAILABLE(69),    /* service unavailable */
-        CODE_ERROR(70),     /* internal software error */
-        CANT_CREATE(73),    /* can't create (user) output file */
-        IO_ERROR(74),       /* input/output error */
-        TEMP_FAILURE(75),   /* temp failure; user is invited to retry */
-        PROTOCOL(76),       /* remote error in protocol */
-        NOPERM(77),         /* permission denied */
-        CONFIG(78);          /* configuration error */
-
-        final int status;
-
-        ExitStatus(int status) {
-            this.status = status;
-        }
-
-        public int status() {
-            return status;
-        }
-    }
-
-    protected final Terminal terminal;
-    protected final Environment env;
-    protected final Settings settings;
-
-    private final CliToolConfig config;
-
-    protected CliTool(CliToolConfig config) {
-        this(config, Terminal.DEFAULT);
-    }
-
-    protected CliTool(CliToolConfig config, Terminal terminal) {
-        if (config.cmds().size() == 0) {
-            throw new IllegalArgumentException("At least one command must be configured");
-        }
-        this.config = config;
-        this.terminal = terminal;
-        env = InternalSettingsPreparer.prepareEnvironment(EMPTY_SETTINGS, terminal);
-        settings = env.settings();
-    }
-
-    public final ExitStatus execute(String... args) throws Exception {
-
-        // first lets see if the user requests tool help. We're doing it only if
-        // this is a multi-command tool. If it's a single command tool, the -h/--help
-        // option will be taken care of on the command level
-        if (!config.isSingle() && args.length > 0 && (args[0].equals("-h") || args[0].equals("--help"))) {
-            config.printUsage(terminal);
-            return ExitStatus.OK_AND_EXIT;
-        }
-
-        CliToolConfig.Cmd cmd;
-        if (config.isSingle()) {
-            cmd = config.single();
-        } else {
-
-            if (args.length == 0) {
-                terminal.println(Terminal.Verbosity.SILENT, "ERROR: command not specified");
-                config.printUsage(terminal);
-                return ExitStatus.USAGE;
-            }
-
-            String cmdName = args[0];
-            cmd = config.cmd(cmdName);
-            if (cmd == null) {
-                terminal.println(Terminal.Verbosity.SILENT, "ERROR: unknown command [" + cmdName + "]. Use [-h] option to list available commands");
-                return ExitStatus.USAGE;
-            }
-
-            // we now remove the command name from the args
-            if (args.length == 1) {
-                args = new String[0];
-            } else {
-                String[] cmdArgs = new String[args.length - 1];
-                System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length);
-                args = cmdArgs;
-            }
-        }
-
-        try {
-            return parse(cmd, args).execute(settings, env);
-        } catch (UserError error) {
-            terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + error.getMessage());
-            return ExitStatus.USAGE;
-            //return error.exitCode;
-        }
-    }
-
-    public Command parse(String cmdName, String[] args) throws Exception {
-        CliToolConfig.Cmd cmd = config.cmd(cmdName);
-        return parse(cmd, args);
-    }
-
-    public Command parse(CliToolConfig.Cmd cmd, String[] args) throws Exception {
-        CommandLineParser parser = new DefaultParser();
-        CommandLine cli = parser.parse(CliToolConfig.OptionsSource.HELP.options(), args, true);
-        if (cli.hasOption("h")) {
-            return helpCmd(cmd);
-        }
-        try {
-            cli = parser.parse(cmd.options(), args, cmd.isStopAtNonOption());
-        } catch (AlreadySelectedException|MissingArgumentException|MissingOptionException|UnrecognizedOptionException e) {
-            // intentionally drop the stack trace here as these are really user errors,
-            // the stack trace into cli parsing lib is not important
-            throw new UserError(ExitStatus.USAGE.status(), e.toString());
-        }
-
-        if (cli.hasOption("v")) {
-            terminal.setVerbosity(Terminal.Verbosity.VERBOSE);
-        } else if (cli.hasOption("s")) {
-            terminal.setVerbosity(Terminal.Verbosity.SILENT);
-        } else {
-            terminal.setVerbosity(Terminal.Verbosity.NORMAL);
-        }
-        return parse(cmd.name(), cli);
-    }
-
-    protected Command.Help helpCmd(CliToolConfig.Cmd cmd) {
-        return new Command.Help(cmd, terminal);
-    }
-
-    protected static Command.Exit exitCmd(ExitStatus status) {
-        return new Command.Exit(null, status, null);
-    }
-
-    protected static Command.Exit exitCmd(ExitStatus status, Terminal terminal, String msg, Object... args) {
-        return new Command.Exit(String.format(Locale.ROOT, msg, args), status, terminal);
-    }
-
-    protected abstract Command parse(String cmdName, CommandLine cli) throws Exception;
-
-    public static abstract class Command {
-
-        protected final Terminal terminal;
-
-        protected Command(Terminal terminal) {
-            this.terminal = terminal;
-        }
-
-        public abstract ExitStatus execute(Settings settings, Environment env) throws Exception;
-
-        public static class Help extends Command {
-
-            private final CliToolConfig.Cmd cmd;
-
-            private Help(CliToolConfig.Cmd cmd, Terminal terminal) {
-                super(terminal);
-                this.cmd = cmd;
-            }
-
-            @Override
-            public ExitStatus execute(Settings settings, Environment env) throws Exception {
-                cmd.printUsage(terminal);
-                return ExitStatus.OK_AND_EXIT;
-            }
-        }
-
-        public static class Exit extends Command {
-            private final String msg;
-            private final ExitStatus status;
-
-            private Exit(String msg, ExitStatus status, Terminal terminal) {
-                super(terminal);
-                this.msg = msg;
-                this.status = status;
-            }
-
-            @Override
-            public ExitStatus execute(Settings settings, Environment env) throws Exception {
-                if (msg != null) {
-                    if (status != ExitStatus.OK) {
-                        terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + msg);
-                    } else {
-                        terminal.println(msg);
-                    }
-                }
-                return status;
-            }
-
-            public ExitStatus status() {
-                return status;
-            }
-        }
-    }
-
-
-
-}
-
diff --git a/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java b/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
deleted file mode 100644
index ff752f45ef0..00000000000
--- a/core/src/main/java/org/elasticsearch/common/cli/CliToolConfig.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.common.cli;
-
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
-import org.apache.commons.cli.Options;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- */
-public class CliToolConfig {
-
-    private final Class toolType;
-    private final String name;
-    private final Map cmds;
-
-    private static final HelpPrinter helpPrinter = new HelpPrinter();
-
-    private CliToolConfig(String name, Class toolType, Cmd[] cmds) {
-        this.name = name;
-        this.toolType = toolType;
-        final Map cmdsMapping = new HashMap<>();
-        for (int i = 0; i < cmds.length; i++) {
-            cmdsMapping.put(cmds[i].name, cmds[i]);
-        }
-        this.cmds = Collections.unmodifiableMap(cmdsMapping);
-    }
-
-    public boolean isSingle() {
-        return cmds.size() == 1;
-    }
-
-    public Cmd single() {
-        assert isSingle() : "Requesting single command on a multi-command tool";
-        return cmds.values().iterator().next();
-    }
-
-    public Class toolType() {
-        return toolType;
-    }
-
-    public String name() {
-        return name;
-    }
-
-    public Collection cmds() {
-        return cmds.values();
-    }
-
-    public Cmd cmd(String name) {
-        return cmds.get(name);
-    }
-
-    public void printUsage(Terminal terminal) {
-        helpPrinter.print(this, terminal);
-    }
-
-    public static class Cmd {
-
-        private String toolName;
-        private final String name;
-        private final Class cmdType;
-        private final Options options;
-        private final boolean stopAtNonOption;
-
-        private Cmd(String name, Class cmdType, Options options, boolean stopAtNonOption) {
-            this.name = name;
-            this.cmdType = cmdType;
-            this.options = options;
-            this.stopAtNonOption = stopAtNonOption;
-            OptionsSource.VERBOSITY.populate(options);
-        }
-
-        public Class cmdType() {
-            return cmdType;
-        }
-
-        public String name() {
-            return name;
-        }
-
-        public Options options() {
-            return options;
-        }
-
-        public boolean isStopAtNonOption() {
-            return stopAtNonOption;
-        }
-
-        public void printUsage(Terminal terminal) {
-            helpPrinter.print(toolName, this, terminal);
-        }
-
-        public static class Builder {
-
-            private final String name;
-            private final Class cmdType;
-            private Options options = new Options();
-            private boolean stopAtNonOption = false;
-
-            private Builder(String name, Class cmdType) {
-                this.name = name;
-                this.cmdType = cmdType;
-            }
-
-            public Builder options(OptionBuilder... optionBuilder) {
-                for (int i = 0; i < optionBuilder.length; i++) {
-                    options.addOption(optionBuilder[i].build());
-                }
-                return this;
-            }
-
-            public Builder options(Option.Builder... optionBuilders) {
-                for (int i = 0; i < optionBuilders.length; i++) {
-                    options.addOption(optionBuilders[i].build());
-                }
-                return this;
-            }
-
-            public Builder optionGroups(OptionGroupBuilder... optionGroupBuilders) {
-                for (OptionGroupBuilder builder : optionGroupBuilders) {
-                    options.addOptionGroup(builder.build());
-                }
-                return this;
-            }
-
-            /**
-              * @param stopAtNonOption if true an unrecognized argument stops
-              *     the parsing and the remaining arguments are added to the
-              *     args list. If false an unrecognized
-              *     argument triggers a ParseException.
-              */
-            public Builder stopAtNonOption(boolean stopAtNonOption) {
-                this.stopAtNonOption = stopAtNonOption;
-                return this;
-            }
-
-            public Cmd build() {
-                return new Cmd(name, cmdType, options, stopAtNonOption);
-            }
-        }
-    }
-
-    public static class OptionBuilder {
-
-        private final Option option;
-
-        private OptionBuilder(String shortName, String longName) {
-            option = new Option(shortName, "");
-            option.setLongOpt(longName);
-            option.setArgName(longName);
-        }
-
-        public OptionBuilder required(boolean required) {
-            option.setRequired(required);
-            return this;
-        }
-
-        public OptionBuilder hasArg(boolean optional) {
-            option.setOptionalArg(optional);
-            option.setArgs(1);
-            return this;
-        }
-
-        public Option build() {
-            return option;
-        }
-    }
-
-    public static class OptionGroupBuilder {
-
-        private OptionGroup group;
-
-        private OptionGroupBuilder(boolean required) {
-            group = new OptionGroup();
-            group.setRequired(required);
-        }
-
-        public OptionGroupBuilder options(OptionBuilder... optionBuilders) {
-            for (OptionBuilder builder : optionBuilders) {
-                group.addOption(builder.build());
-            }
-            return this;
-        }
-
-        public OptionGroup build() {
-            return group;
-        }
-
-    }
-
-    static abstract class OptionsSource {
-
-        static final OptionsSource HELP = new OptionsSource() {
-
-            @Override
-            void populate(Options options) {
-                options.addOption(new OptionBuilder("h", "help").required(false).build());
-            }
-        };
-
-        static final OptionsSource VERBOSITY = new OptionsSource() {
-            @Override
-            void populate(Options options) {
-                OptionGroup verbosityGroup = new OptionGroup();
-                verbosityGroup.setRequired(false);
-                verbosityGroup.addOption(new OptionBuilder("s", "silent").required(false).build());
-                verbosityGroup.addOption(new OptionBuilder("v", "verbose").required(false).build());
-                options.addOptionGroup(verbosityGroup);
-            }
-        };
-
-        private Options options;
-
-        Options options() {
-            if (options == null) {
-                options = new Options();
-                populate(options);
-            }
-            return options;
-        }
-
-        abstract void populate(Options options);
-
-    }
-}
diff --git a/core/src/main/java/org/elasticsearch/common/cli/HelpPrinter.java b/core/src/main/java/org/elasticsearch/common/cli/HelpPrinter.java
deleted file mode 100644
index ada6cc33a19..00000000000
--- a/core/src/main/java/org/elasticsearch/common/cli/HelpPrinter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.common.cli;
-
-import org.elasticsearch.common.io.Streams;
-import org.elasticsearch.common.util.Callback;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- *
- */
-public class HelpPrinter {
-
-    private static final String HELP_FILE_EXT = ".help";
-
-    public void print(CliToolConfig config, Terminal terminal) {
-        print(config.toolType(), config.name(), terminal);
-    }
-
-    public void print(String toolName, CliToolConfig.Cmd cmd, Terminal terminal) {
-        print(cmd.cmdType(), toolName + "-" + cmd.name(), terminal);
-    }
-
-    private static void print(Class clazz, String name, final Terminal terminal) {
-        terminal.println(Terminal.Verbosity.SILENT, "");
-        try (InputStream input = clazz.getResourceAsStream(name + HELP_FILE_EXT)) {
-            Streams.readAllLines(input, new Callback() {
-                @Override
-                public void handle(String line) {
-                    terminal.println(Terminal.Verbosity.SILENT, line);
-                }
-            });
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe);
-        }
-        terminal.println(Terminal.Verbosity.SILENT, "");
-    }
-}
diff --git a/core/src/main/java/org/elasticsearch/common/logging/TerminalAppender.java b/core/src/main/java/org/elasticsearch/common/logging/TerminalAppender.java
index 7031a62a999..e967ad9d79e 100644
--- a/core/src/main/java/org/elasticsearch/common/logging/TerminalAppender.java
+++ b/core/src/main/java/org/elasticsearch/common/logging/TerminalAppender.java
@@ -22,7 +22,7 @@ package org.elasticsearch.common.logging;
 
 import org.apache.log4j.AppenderSkeleton;
 import org.apache.log4j.spi.LoggingEvent;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 
 /**
  * TerminalAppender logs event to Terminal.DEFAULT. It is used for example by the PluginCli.
diff --git a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java
index faf449586c1..c66cb08dae7 100644
--- a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java
+++ b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java
@@ -23,7 +23,7 @@ import org.elasticsearch.bootstrap.BootstrapInfo;
 import org.elasticsearch.cluster.ClusterName;
 import org.elasticsearch.common.Randomness;
 import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.common.collect.Tuple;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
index 83273e6c1c4..32c4bf18507 100644
--- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
@@ -27,8 +27,7 @@ import org.elasticsearch.Version;
 import org.elasticsearch.bootstrap.JarHell;
 import org.elasticsearch.cli.Command;
 import org.elasticsearch.cli.ExitCodes;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.common.hash.MessageDigests;
 import org.elasticsearch.common.io.FileSystemUtils;
@@ -59,7 +58,7 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
 import static java.util.Collections.unmodifiableSet;
-import static org.elasticsearch.common.cli.Terminal.Verbosity.VERBOSE;
+import static org.elasticsearch.cli.Terminal.Verbosity.VERBOSE;
 import static org.elasticsearch.common.util.set.Sets.newHashSet;
 
 /**
diff --git a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
index 276e38f1595..953e698a4c2 100644
--- a/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/ListPluginsCommand.java
@@ -26,9 +26,7 @@ import java.nio.file.Path;
 
 import joptsimple.OptionSet;
 import org.elasticsearch.cli.Command;
-import org.elasticsearch.cli.ExitCodes;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.env.Environment;
 
 /**
diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginCli.java b/core/src/main/java/org/elasticsearch/plugins/PluginCli.java
index 9f2e432a438..323b872044e 100644
--- a/core/src/main/java/org/elasticsearch/plugins/PluginCli.java
+++ b/core/src/main/java/org/elasticsearch/plugins/PluginCli.java
@@ -22,7 +22,7 @@ package org.elasticsearch.plugins;
 import org.apache.log4j.BasicConfigurator;
 import org.apache.log4j.varia.NullAppender;
 import org.elasticsearch.cli.MultiCommand;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginSecurity.java b/core/src/main/java/org/elasticsearch/plugins/PluginSecurity.java
index b14bcaf2ff3..f9c3d1826c9 100644
--- a/core/src/main/java/org/elasticsearch/plugins/PluginSecurity.java
+++ b/core/src/main/java/org/elasticsearch/plugins/PluginSecurity.java
@@ -20,8 +20,8 @@
 package org.elasticsearch.plugins;
 
 import org.apache.lucene.util.IOUtils;
-import org.elasticsearch.common.cli.Terminal;
-import org.elasticsearch.common.cli.Terminal.Verbosity;
+import org.elasticsearch.cli.Terminal;
+import org.elasticsearch.cli.Terminal.Verbosity;
 import org.elasticsearch.env.Environment;
 
 import java.io.IOException;
diff --git a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
index f435a16edf0..a3e6c375f83 100644
--- a/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/RemovePluginCommand.java
@@ -32,11 +32,10 @@ import org.elasticsearch.cli.Command;
 import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.cli.CliTool;
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.env.Environment;
 
-import static org.elasticsearch.common.cli.Terminal.Verbosity.VERBOSE;
+import static org.elasticsearch.cli.Terminal.Verbosity.VERBOSE;
 
 /**
  * A command for the plugin cli to remove a plugin from elasticsearch.
@@ -68,7 +67,7 @@ class RemovePluginCommand extends Command {
 
         Path pluginDir = env.pluginsFile().resolve(pluginName);
         if (Files.exists(pluginDir) == false) {
-            throw new UserError(CliTool.ExitStatus.USAGE.status(), "Plugin " + pluginName + " not found. Run 'plugin list' to get list of installed plugins.");
+            throw new UserError(ExitCodes.USAGE, "Plugin " + pluginName + " not found. Run 'plugin list' to get list of installed plugins.");
         }
 
         List pluginPaths = new ArrayList<>();
@@ -76,7 +75,7 @@ class RemovePluginCommand extends Command {
         Path pluginBinDir = env.binFile().resolve(pluginName);
         if (Files.exists(pluginBinDir)) {
             if (Files.isDirectory(pluginBinDir) == false) {
-                throw new UserError(CliTool.ExitStatus.IO_ERROR.status(), "Bin dir for " + pluginName + " is not a directory");
+                throw new UserError(ExitCodes.IO_ERROR, "Bin dir for " + pluginName + " is not a directory");
             }
             pluginPaths.add(pluginBinDir);
             terminal.println(VERBOSE, "Removing: " + pluginBinDir);
diff --git a/core/src/test/java/org/elasticsearch/cli/CommandTests.java b/core/src/test/java/org/elasticsearch/cli/CommandTests.java
new file mode 100644
index 00000000000..153bd4600b9
--- /dev/null
+++ b/core/src/test/java/org/elasticsearch/cli/CommandTests.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.cli;
+
+import joptsimple.OptionSet;
+import org.elasticsearch.test.ESTestCase;
+
+public class CommandTests extends ESTestCase {
+
+    static class UserErrorCommand extends Command {
+        UserErrorCommand() {
+            super("Throws a user error");
+        }
+        @Override
+        protected void execute(Terminal terminal, OptionSet options) throws Exception {
+            throw new UserError(ExitCodes.DATA_ERROR, "Bad input");
+        }
+    }
+
+    static class NoopCommand extends Command {
+        boolean executed = false;
+        NoopCommand() {
+            super("Does nothing");
+        }
+        @Override
+        protected void execute(Terminal terminal, OptionSet options) throws Exception {
+            terminal.println("Normal output");
+            terminal.println(Terminal.Verbosity.SILENT, "Silent output");
+            terminal.println(Terminal.Verbosity.VERBOSE, "Verbose output");
+            executed = true;
+        }
+        @Override
+        protected void printAdditionalHelp(Terminal terminal) {
+            terminal.println("Some extra help");
+        }
+    }
+
+    public void testHelp() throws Exception {
+        NoopCommand command = new NoopCommand();
+        MockTerminal terminal = new MockTerminal();
+        String[] args = {"-h"};
+        int status = command.main(args, terminal);
+        String output = terminal.getOutput();
+        assertEquals(output, ExitCodes.OK, status);
+        assertTrue(output, output.contains("Does nothing"));
+        assertTrue(output, output.contains("Some extra help"));
+        assertFalse(command.executed);
+
+        command = new NoopCommand();
+        String[] args2 = {"--help"};
+        status = command.main(args2, terminal);
+        output = terminal.getOutput();
+        assertEquals(output, ExitCodes.OK, status);
+        assertTrue(output, output.contains("Does nothing"));
+        assertTrue(output, output.contains("Some extra help"));
+        assertFalse(command.executed);
+    }
+
+    public void testVerbositySilentAndVerbose() throws Exception {
+        MockTerminal terminal = new MockTerminal();
+        NoopCommand command = new NoopCommand();
+        String[] args = {"-v", "-s"};
+        UserError e = expectThrows(UserError.class, () -> {
+            command.mainWithoutErrorHandling(args, terminal);
+        });
+        assertTrue(e.getMessage(), e.getMessage().contains("Cannot specify -s and -v together"));
+    }
+
+    public void testSilentVerbosity() throws Exception {
+        MockTerminal terminal = new MockTerminal();
+        NoopCommand command = new NoopCommand();
+        String[] args = {"-s"};
+        command.main(args, terminal);
+        String output = terminal.getOutput();
+        assertTrue(output, output.contains("Silent output"));
+    }
+
+    public void testNormalVerbosity() throws Exception {
+        MockTerminal terminal = new MockTerminal();
+        terminal.setVerbosity(Terminal.Verbosity.SILENT);
+        NoopCommand command = new NoopCommand();
+        String[] args = {};
+        command.main(args, terminal);
+        String output = terminal.getOutput();
+        assertTrue(output, output.contains("Normal output"));
+    }
+
+    public void testVerboseVerbosity() throws Exception {
+        MockTerminal terminal = new MockTerminal();
+        NoopCommand command = new NoopCommand();
+        String[] args = {"-v"};
+        command.main(args, terminal);
+        String output = terminal.getOutput();
+        assertTrue(output, output.contains("Verbose output"));
+    }
+
+    public void testUserError() throws Exception {
+        MockTerminal terminal = new MockTerminal();
+        UserErrorCommand command = new UserErrorCommand();
+        String[] args = {};
+        int status = command.main(args, terminal);
+        String output = terminal.getOutput();
+        assertEquals(output, ExitCodes.DATA_ERROR, status);
+        assertTrue(output, output.contains("ERROR: Bad input"));
+    }
+}
diff --git a/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java b/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
new file mode 100644
index 00000000000..cdd7cb7e241
--- /dev/null
+++ b/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.cli;
+
+public class MultiCommandTests extends CommandTestCase {
+
+    @Override
+    protected Command newCommand() {
+        return null;
+    }
+}
diff --git a/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java b/core/src/test/java/org/elasticsearch/cli/TerminalTests.java
similarity index 96%
rename from core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java
rename to core/src/test/java/org/elasticsearch/cli/TerminalTests.java
index 12fc4cb77e4..6673bdbc858 100644
--- a/core/src/test/java/org/elasticsearch/common/cli/TerminalTests.java
+++ b/core/src/test/java/org/elasticsearch/cli/TerminalTests.java
@@ -17,9 +17,8 @@
  * under the License.
  */
 
-package org.elasticsearch.common.cli;
+package org.elasticsearch.cli;
 
-import org.elasticsearch.cli.MockTerminal;
 import org.elasticsearch.test.ESTestCase;
 
 public class TerminalTests extends ESTestCase {
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
index 726d17b0938..2fc08f23a06 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
@@ -19,21 +19,6 @@
 
 package org.elasticsearch.bootstrap;
 
-import joptsimple.OptionException;
-import org.elasticsearch.Build;
-import org.elasticsearch.Version;
-import org.elasticsearch.cli.Command;
-import org.elasticsearch.cli.CommandTestCase;
-import org.elasticsearch.cli.ExitCodes;
-import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.common.cli.CliTool.ExitStatus;
-import org.elasticsearch.cli.UserError;
-import org.elasticsearch.cli.MockTerminal;
-import org.elasticsearch.common.collect.Tuple;
-import org.elasticsearch.monitor.jvm.JvmInfo;
-import org.junit.After;
-import org.junit.Before;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -41,12 +26,18 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK;
-import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK_AND_EXIT;
-import static org.elasticsearch.common.cli.CliTool.ExitStatus.USAGE;
-import static org.hamcrest.Matchers.containsString;
+import joptsimple.OptionException;
+import org.elasticsearch.Build;
+import org.elasticsearch.Version;
+import org.elasticsearch.cli.Command;
+import org.elasticsearch.cli.CommandTestCase;
+import org.elasticsearch.cli.UserError;
+import org.elasticsearch.common.SuppressForbidden;
+import org.elasticsearch.monitor.jvm.JvmInfo;
+import org.junit.After;
+import org.junit.Before;
+
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
 
 @SuppressForbidden(reason = "modifies system properties intentionally")
 public class BootstrapCliParserTests extends CommandTestCase {
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginSecurityTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginSecurityTests.java
index acc300c6cf5..466f7d05cd1 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginSecurityTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginSecurityTests.java
@@ -19,7 +19,7 @@
 
 package org.elasticsearch.plugins;
 
-import org.elasticsearch.common.cli.Terminal;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.test.ESTestCase;
 
 import java.nio.file.Path;
diff --git a/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
index a9b31b636cc..e9c6a2eec9c 100644
--- a/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
+++ b/test/framework/src/main/java/org/elasticsearch/cli/CommandTestCase.java
@@ -19,8 +19,6 @@
 
 package org.elasticsearch.cli;
 
-import joptsimple.OptionSet;
-import org.elasticsearch.common.cli.Terminal;
 import org.elasticsearch.test.ESTestCase;
 import org.junit.Before;
 
diff --git a/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
index b712b216f9a..bd8bd493cea 100644
--- a/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
+++ b/test/framework/src/main/java/org/elasticsearch/cli/MockTerminal.java
@@ -27,8 +27,6 @@ import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Deque;
 
-import org.elasticsearch.common.cli.Terminal;
-
 /**
  * A terminal for tests which captures all output, and
  * can be plugged with fake input.

From 13424318db53cf1790b6539b6ed0d70491808ec2 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 14:16:39 -0800
Subject: [PATCH 23/49] Remove old help files

---
 .../bootstrap/elasticsearch-start.help        | 28 -------------------
 .../bootstrap/elasticsearch-version.help      | 16 -----------
 .../bootstrap/elasticsearch.help              | 22 ---------------
 3 files changed, 66 deletions(-)
 delete mode 100644 core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-start.help
 delete mode 100644 core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-version.help
 delete mode 100644 core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch.help

diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-start.help b/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-start.help
deleted file mode 100644
index 9b27a8dd390..00000000000
--- a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-start.help
+++ /dev/null
@@ -1,28 +0,0 @@
-NAME
-
-    start - Start Elasticsearch
-
-SYNOPSIS
-
-    elasticsearch start
-
-DESCRIPTION
-
-    This command starts Elasticsearch. You can configure it to run in the foreground, write a pid file
-    and configure arbitrary options that override file-based configuration.
-
-OPTIONS
-
-    -h,--help                    Shows this message
-
-    -p,--pidfile        Creates a pid file in the specified path on start
-
-    -d,--daemonize               Starts Elasticsearch in the background
-
-    -Dproperty=value             Configures an Elasticsearch specific property, like -Dnetwork.host=127.0.0.1
-
-    --property=value             Configures an elasticsearch specific property, like --network.host 127.0.0.1
-    --property value
-
-    NOTE: The -d, -p, and -D arguments must appear before any --property arguments.
-
diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-version.help b/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-version.help
deleted file mode 100644
index 00f2a33401c..00000000000
--- a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch-version.help
+++ /dev/null
@@ -1,16 +0,0 @@
-NAME
-
-    version - Show version information and exit
-
-SYNOPSIS
-
-    elasticsearch version
-
-DESCRIPTION
-
-    This command shows Elasticsearch version, timestamp and build information as well as JVM info
-
-OPTIONS
-
-    -h,--help                    Shows this message
-
diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch.help b/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch.help
deleted file mode 100644
index 83ee497dc21..00000000000
--- a/core/src/main/resources/org/elasticsearch/bootstrap/elasticsearch.help
+++ /dev/null
@@ -1,22 +0,0 @@
-NAME
-
-    elasticsearch - Manages elasticsearch
-
-SYNOPSIS
-
-    elasticsearch 
-
-DESCRIPTION
-
-    Start an elasticsearch node
-
-COMMANDS
-
-    start      Start elasticsearch
-
-    version    Show version information and exit
-
-NOTES
-
-    [*] For usage help on specific commands please type "elasticsearch  -h"
-

From 73ebe36ed001e8202b342a66c1f6358b798ee727 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 17:27:53 -0800
Subject: [PATCH 24/49] More tests

---
 .../elasticsearch/bootstrap/Bootstrap.java    | 26 +++---
 .../bootstrap/Elasticsearch.java              | 11 +--
 .../elasticsearch/cli/MultiCommandTests.java  | 79 ++++++++++++++++++-
 .../elasticsearch/plugins/PluginCliTests.java | 79 -------------------
 4 files changed, 96 insertions(+), 99 deletions(-)
 delete mode 100644 core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index 5008229f5f8..6cd2b4d80fe 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -19,14 +19,22 @@
 
 package org.elasticsearch.bootstrap;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Path;
+import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+
 import org.apache.lucene.util.Constants;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.StringHelper;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.Version;
+import org.elasticsearch.cli.ExitCodes;
+import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.common.PidFile;
 import org.elasticsearch.common.SuppressForbidden;
-import org.elasticsearch.cli.Terminal;
 import org.elasticsearch.common.inject.CreationException;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.LogConfigurator;
@@ -39,13 +47,6 @@ import org.elasticsearch.monitor.process.ProcessProbe;
 import org.elasticsearch.node.Node;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.nio.file.Path;
-import java.util.Locale;
-import java.util.concurrent.CountDownLatch;
-
 import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
 
 /**
@@ -217,10 +218,17 @@ final class Bootstrap {
      * This method is invoked by {@link Elasticsearch#main(String[])}
      * to startup elasticsearch.
      */
-    static void init() throws Throwable {
+    static void init(String[] args) throws Throwable {
         // Set the system property before anything has a chance to trigger its use
         initLoggerPrefix();
 
+        BootstrapCliParser parser = new BootstrapCliParser();
+        int status = parser.main(args, Terminal.DEFAULT);
+
+        if (parser.shouldRun() == false || status != ExitCodes.OK) {
+            exit(status);
+        }
+
         INSTANCE = new Bootstrap();
 
         boolean foreground = !"false".equals(System.getProperty("es.foreground", System.getProperty("es-foreground")));
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
index 1d2a0b98232..3b95c3f4a6f 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java
@@ -21,8 +21,6 @@ package org.elasticsearch.bootstrap;
 
 import java.io.IOException;
 
-import org.elasticsearch.cli.Terminal;
-
 /**
  * This class starts elasticsearch.
  */
@@ -35,15 +33,8 @@ public final class Elasticsearch {
      * Main entry point for starting elasticsearch
      */
     public static void main(String[] args) throws Exception {
-        BootstrapCliParser parser = new BootstrapCliParser();
-        parser.main(args, Terminal.DEFAULT);
-
-        if (parser.shouldRun() == false) {
-            return;
-        }
-
         try {
-            Bootstrap.init();
+            Bootstrap.init(args);
         } catch (Throwable t) {
             // format exceptions to the console in a special way
             // to avoid 2MB stacktraces from guice, etc.
diff --git a/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java b/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
index cdd7cb7e241..4f91d378440 100644
--- a/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
+++ b/core/src/test/java/org/elasticsearch/cli/MultiCommandTests.java
@@ -19,10 +19,87 @@
 
 package org.elasticsearch.cli;
 
+import joptsimple.OptionSet;
+import org.junit.Before;
+
 public class MultiCommandTests extends CommandTestCase {
 
+    static class DummyMultiCommand extends MultiCommand {
+        DummyMultiCommand() {
+            super("A dummy multi command");
+        }
+    }
+
+    static class DummySubCommand extends Command {
+        DummySubCommand() {
+            super("A dummy subcommand");
+        }
+        @Override
+        protected void execute(Terminal terminal, OptionSet options) throws Exception {
+            terminal.println("Arguments: " + options.nonOptionArguments().toString());
+        }
+    }
+
+    DummyMultiCommand multiCommand;
+
+    @Before
+    public void setupCommand() {
+        multiCommand = new DummyMultiCommand();
+    }
+
     @Override
     protected Command newCommand() {
-        return null;
+        return multiCommand;
+    }
+
+    public void testNoCommandsConfigured() throws Exception {
+        IllegalStateException e = expectThrows(IllegalStateException.class, () -> {
+            execute();
+        });
+        assertEquals("No subcommands configured", e.getMessage());
+    }
+
+    public void testUnknownCommand() throws Exception {
+        multiCommand.subcommands.put("something", new DummySubCommand());
+        UserError e = expectThrows(UserError.class, () -> {
+            execute("somethingelse");
+        });
+        assertEquals(ExitCodes.USAGE, e.exitCode);
+        assertEquals("Unknown command [somethingelse]", e.getMessage());
+    }
+
+    public void testMissingCommand() throws Exception {
+        multiCommand.subcommands.put("command1", new DummySubCommand());
+        UserError e = expectThrows(UserError.class, () -> {
+            execute();
+        });
+        assertEquals(ExitCodes.USAGE, e.exitCode);
+        assertEquals("Missing command", e.getMessage());
+    }
+
+    public void testHelp() throws Exception {
+        multiCommand.subcommands.put("command1", new DummySubCommand());
+        multiCommand.subcommands.put("command2", new DummySubCommand());
+        execute("-h");
+        String output = terminal.getOutput();
+        assertTrue(output, output.contains("command1"));
+        assertTrue(output, output.contains("command2"));
+    }
+
+    public void testSubcommandHelp() throws Exception {
+        multiCommand.subcommands.put("command1", new DummySubCommand());
+        multiCommand.subcommands.put("command2", new DummySubCommand());
+        execute("command2", "-h");
+        String output = terminal.getOutput();
+        assertFalse(output, output.contains("command1"));
+        assertTrue(output, output.contains("A dummy subcommand"));
+    }
+
+    public void testSubcommandArguments() throws Exception {
+        multiCommand.subcommands.put("command1", new DummySubCommand());
+        execute("command1", "foo", "bar");
+        String output = terminal.getOutput();
+        assertFalse(output, output.contains("command1"));
+        assertTrue(output, output.contains("Arguments: [foo, bar]"));
     }
 }
diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
deleted file mode 100644
index 73d97949571..00000000000
--- a/core/src/test/java/org/elasticsearch/plugins/PluginCliTests.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.plugins;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-import org.elasticsearch.cli.Command;
-import org.elasticsearch.cli.CommandTestCase;
-import org.elasticsearch.common.cli.CliToolTestCase;
-import org.elasticsearch.cli.MockTerminal;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.Environment;
-import org.junit.Before;
-
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.is;
-
-public class PluginCliTests extends CommandTestCase {
-
-    // the home dir for each test to use
-    Path homeDir;
-
-    // settings used to create an Environment for tools
-    Settings.Builder settingsBuilder;
-
-    @Before
-    public void setupHome() {
-        homeDir = createTempDir();
-        settingsBuilder = Settings.builder()
-            .put("path.home", homeDir);
-    }
-
-    @Override
-    protected Command newCommand() {
-        return new PluginCli(new Environment(settingsBuilder.build()));
-    }
-
-    public void testHelpWorks() throws Exception {
-        MockTerminal terminal = new MockTerminal();
-        /* nocommit
-        assertThat(new PluginCli(terminal).execute(args("--help")), is(OK_AND_EXIT));
-        assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin.help");
-
-        terminal.resetOutput();
-        assertThat(new PluginCli(terminal).execute(args("install -h")), is(OK_AND_EXIT));
-        assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin-install.help");
-        for (String plugin : InstallPluginCommand.OFFICIAL_PLUGINS) {
-            assertThat(terminal.getOutput(), containsString(plugin));
-        }
-
-        terminal.resetOutput();
-        assertThat(new PluginCli(terminal).execute(args("remove --help")), is(OK_AND_EXIT));
-        assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin-remove.help");
-
-        terminal.resetOutput();
-        assertThat(new PluginCli(terminal).execute(args("list -h")), is(OK_AND_EXIT));
-        assertTerminalOutputContainsHelpFile(terminal, "/org/elasticsearch/plugins/plugin-list.help");
-        */
-    }
-
-}

From 6cfdf9f4404a82f9da1f9a75d191184659e117c8 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 17:29:31 -0800
Subject: [PATCH 25/49] Remove old commons-cli dep

---
 core/build.gradle | 1 -
 1 file changed, 1 deletion(-)

diff --git a/core/build.gradle b/core/build.gradle
index 226158ca094..ab3754e72ff 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -49,7 +49,6 @@ dependencies {
   compile 'org.elasticsearch:securesm:1.0'
 
   // utilities
-  compile 'commons-cli:commons-cli:1.3.1' // nocommit: remove the old!
   compile 'net.sf.jopt-simple:jopt-simple:4.9'
   compile 'com.carrotsearch:hppc:0.7.1'
 

From cb607a8faee195af9737602be2dc01ac2288a397 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 19:18:14 -0800
Subject: [PATCH 26/49] Remove commons-cli sha and add jopt-simple sha

---
 distribution/licenses/commons-cli-1.3.1.jar.sha1 | 1 -
 distribution/licenses/jopt-simple-4.9.jar.sha1   | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 distribution/licenses/commons-cli-1.3.1.jar.sha1
 create mode 100644 distribution/licenses/jopt-simple-4.9.jar.sha1

diff --git a/distribution/licenses/commons-cli-1.3.1.jar.sha1 b/distribution/licenses/commons-cli-1.3.1.jar.sha1
deleted file mode 100644
index fc366d027f5..00000000000
--- a/distribution/licenses/commons-cli-1.3.1.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-1303efbc4b181e5a58bf2e967dc156a3132b97c0
diff --git a/distribution/licenses/jopt-simple-4.9.jar.sha1 b/distribution/licenses/jopt-simple-4.9.jar.sha1
new file mode 100644
index 00000000000..b86fa62ac20
--- /dev/null
+++ b/distribution/licenses/jopt-simple-4.9.jar.sha1
@@ -0,0 +1 @@
+ee9e9eaa0a35360dcfeac129ff4923215fd65904
\ No newline at end of file

From 1dafead2ebd00de570863d8c4819f0267fdc656a Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 22:55:24 -0800
Subject: [PATCH 27/49] Fix precommit

---
 .../elasticsearch/bootstrap/BootstrapCLIParser.java    |  3 +++
 modules/lang-groovy/build.gradle                       |  9 +++++++++
 plugins/repository-hdfs/build.gradle                   | 10 ++++++++++
 3 files changed, 22 insertions(+)

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
index e44e397f67a..f812bda178c 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
@@ -29,6 +29,7 @@ import org.elasticsearch.cli.ExitCodes;
 import org.elasticsearch.cli.UserError;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.cli.Terminal;
+import org.elasticsearch.common.SuppressForbidden;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 
 final class BootstrapCliParser extends Command {
@@ -54,6 +55,8 @@ final class BootstrapCliParser extends Command {
             .withRequiredArg();
     }
 
+    // TODO: don't use system properties as a way to do this, its horrible...
+    @SuppressForbidden(reason = "Sets system properties passed as CLI parameters")
     @Override
     protected void execute(Terminal terminal, OptionSet options) throws Exception {
         if (options.has(versionOption)) {
diff --git a/modules/lang-groovy/build.gradle b/modules/lang-groovy/build.gradle
index 89444a4e926..005a7d4be18 100644
--- a/modules/lang-groovy/build.gradle
+++ b/modules/lang-groovy/build.gradle
@@ -38,6 +38,15 @@ thirdPartyAudit.excludes = [
   // for example we do not need ivy, scripts arent allowed to download code
   'com.thoughtworks.xstream.XStream', 
   'groovyjarjarasm.asm.util.Textifiable', 
+  'org.apache.commons.cli.CommandLine',
+  'org.apache.commons.cli.CommandLineParser',
+  'org.apache.commons.cli.GnuParser',
+  'org.apache.commons.cli.HelpFormatter',
+  'org.apache.commons.cli.Option',
+  'org.apache.commons.cli.OptionBuilder',
+  'org.apache.commons.cli.Options',
+  'org.apache.commons.cli.Parser',
+  'org.apache.commons.cli.PosixParser',
   'org.apache.ivy.Ivy', 
   'org.apache.ivy.core.event.IvyListener', 
   'org.apache.ivy.core.event.download.PrepareDownloadEvent', 
diff --git a/plugins/repository-hdfs/build.gradle b/plugins/repository-hdfs/build.gradle
index 915a85ebdc4..20050bdc31e 100644
--- a/plugins/repository-hdfs/build.gradle
+++ b/plugins/repository-hdfs/build.gradle
@@ -191,6 +191,16 @@ thirdPartyAudit.excludes = [
   'org.apache.commons.beanutils.DynaClass', 
   'org.apache.commons.beanutils.DynaProperty', 
   'org.apache.commons.beanutils.PropertyUtils', 
+  'org.apache.commons.cli.CommandLine',
+  'org.apache.commons.cli.CommandLineParser',
+  'org.apache.commons.cli.GnuParser',
+  'org.apache.commons.cli.HelpFormatter',
+  'org.apache.commons.cli.Option',
+  'org.apache.commons.cli.OptionBuilder',
+  'org.apache.commons.cli.OptionGroup',
+  'org.apache.commons.cli.Options',
+  'org.apache.commons.cli.ParseException',
+  'org.apache.commons.cli.PosixParser',
   'org.apache.commons.compress.archivers.tar.TarArchiveEntry', 
   'org.apache.commons.compress.archivers.tar.TarArchiveInputStream', 
   'org.apache.commons.codec.DecoderException', 

From d822c6558f5983f7b90ae57ca9cd1f341bd72e59 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Tue, 8 Mar 2016 23:17:35 -0800
Subject: [PATCH 28/49] Fix file rename to match class name

---
 .../{BootstrapCLIParser.java => BootstrapCliParser.java}          | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename core/src/main/java/org/elasticsearch/bootstrap/{BootstrapCLIParser.java => BootstrapCliParser.java} (100%)

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java
similarity index 100%
rename from core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java
rename to core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java

From 80ae2b0002eada4c357cf6fad0a174b0946da3da Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Wed, 9 Mar 2016 00:10:59 -0800
Subject: [PATCH 29/49] Fix more licenses

---
 .../bootstrap/BootstrapCliParser.java         |  8 +++++--
 distribution/licenses/jopt-simple-LICENSE.txt | 24 +++++++++++++++++++
 distribution/licenses/jopt-simple-NOTICE.txt  |  0
 plugins/repository-hdfs/build.gradle          | 11 +--------
 .../licenses/commons-cli-1.2.jar.sha1         |  1 +
 .../licenses/commons-cli-LICENSE.txt          |  0
 .../licenses/commons-cli-NOTICE.txt           |  0
 7 files changed, 32 insertions(+), 12 deletions(-)
 create mode 100644 distribution/licenses/jopt-simple-LICENSE.txt
 create mode 100644 distribution/licenses/jopt-simple-NOTICE.txt
 create mode 100644 plugins/repository-hdfs/licenses/commons-cli-1.2.jar.sha1
 rename {distribution => plugins/repository-hdfs}/licenses/commons-cli-LICENSE.txt (100%)
 rename {distribution => plugins/repository-hdfs}/licenses/commons-cli-NOTICE.txt (100%)

diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java
index f812bda178c..5c927305f14 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCliParser.java
@@ -51,7 +51,7 @@ final class BootstrapCliParser extends Command {
         pidfileOption = parser.acceptsAll(Arrays.asList("p", "pidfile"),
             "Creates a pid file in the specified path on start")
             .withRequiredArg();
-        propertyOption = parser.accepts("E", "Configures an Elasticsearch setting")
+        propertyOption = parser.accepts("D", "Configures an Elasticsearch setting")
             .withRequiredArg();
     }
 
@@ -80,7 +80,11 @@ final class BootstrapCliParser extends Command {
             if (keyValue.length != 2) {
                 throw new UserError(ExitCodes.USAGE, "Malformed elasticsearch setting, must be of the form key=value");
             }
-            System.setProperty("es." + keyValue[0], keyValue[1]);
+            String key = keyValue[0];
+            if (key.startsWith("es.") == false) {
+                key = "es." + key;
+            }
+            System.setProperty(key, keyValue[1]);
         }
         shouldRun = true;
     }
diff --git a/distribution/licenses/jopt-simple-LICENSE.txt b/distribution/licenses/jopt-simple-LICENSE.txt
new file mode 100644
index 00000000000..85f923a9526
--- /dev/null
+++ b/distribution/licenses/jopt-simple-LICENSE.txt
@@ -0,0 +1,24 @@
+/*
+ The MIT License
+
+ Copyright (c) 2004-2015 Paul R. Holser, Jr.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/distribution/licenses/jopt-simple-NOTICE.txt b/distribution/licenses/jopt-simple-NOTICE.txt
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/plugins/repository-hdfs/build.gradle b/plugins/repository-hdfs/build.gradle
index 20050bdc31e..8fc9e50d7f3 100644
--- a/plugins/repository-hdfs/build.gradle
+++ b/plugins/repository-hdfs/build.gradle
@@ -45,6 +45,7 @@ dependencies {
   compile 'com.google.guava:guava:16.0.1'
   compile 'com.google.protobuf:protobuf-java:2.5.0'
   compile 'commons-logging:commons-logging:1.1.3'
+  compile 'commons-cli:commons-cli:1.2'
   compile 'commons-collections:commons-collections:3.2.2'
   compile 'commons-configuration:commons-configuration:1.6'
   compile 'commons-io:commons-io:2.4'
@@ -191,16 +192,6 @@ thirdPartyAudit.excludes = [
   'org.apache.commons.beanutils.DynaClass', 
   'org.apache.commons.beanutils.DynaProperty', 
   'org.apache.commons.beanutils.PropertyUtils', 
-  'org.apache.commons.cli.CommandLine',
-  'org.apache.commons.cli.CommandLineParser',
-  'org.apache.commons.cli.GnuParser',
-  'org.apache.commons.cli.HelpFormatter',
-  'org.apache.commons.cli.Option',
-  'org.apache.commons.cli.OptionBuilder',
-  'org.apache.commons.cli.OptionGroup',
-  'org.apache.commons.cli.Options',
-  'org.apache.commons.cli.ParseException',
-  'org.apache.commons.cli.PosixParser',
   'org.apache.commons.compress.archivers.tar.TarArchiveEntry', 
   'org.apache.commons.compress.archivers.tar.TarArchiveInputStream', 
   'org.apache.commons.codec.DecoderException', 
diff --git a/plugins/repository-hdfs/licenses/commons-cli-1.2.jar.sha1 b/plugins/repository-hdfs/licenses/commons-cli-1.2.jar.sha1
new file mode 100644
index 00000000000..d38d00127e8
--- /dev/null
+++ b/plugins/repository-hdfs/licenses/commons-cli-1.2.jar.sha1
@@ -0,0 +1 @@
+2bf96b7aa8b611c177d329452af1dc933e14501c
\ No newline at end of file
diff --git a/distribution/licenses/commons-cli-LICENSE.txt b/plugins/repository-hdfs/licenses/commons-cli-LICENSE.txt
similarity index 100%
rename from distribution/licenses/commons-cli-LICENSE.txt
rename to plugins/repository-hdfs/licenses/commons-cli-LICENSE.txt
diff --git a/distribution/licenses/commons-cli-NOTICE.txt b/plugins/repository-hdfs/licenses/commons-cli-NOTICE.txt
similarity index 100%
rename from distribution/licenses/commons-cli-NOTICE.txt
rename to plugins/repository-hdfs/licenses/commons-cli-NOTICE.txt

From 422df6089c9813868dabd8eea0aacd885082be5c Mon Sep 17 00:00:00 2001
From: Yannick Welsch 
Date: Fri, 11 Mar 2016 16:35:50 +0100
Subject: [PATCH 30/49] [TEST] Unblock nodes if snapshot/restore test fails

---
 .../SharedClusterSnapshotRestoreIT.java       | 98 ++++++++++---------
 1 file changed, 52 insertions(+), 46 deletions(-)

diff --git a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
index 51924244f5d..cf0e37a51b4 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
@@ -1862,41 +1862,44 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
         } else {
             waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueMinutes(1));
         }
-        if (allowPartial) {
-            // partial snapshots allow close / delete operations
-            if (randomBoolean()) {
-                logger.info("--> delete index while partial snapshot is running");
-                client.admin().indices().prepareDelete("test-idx-1").get();
-            } else {
-                logger.info("--> close index while partial snapshot is running");
-                client.admin().indices().prepareClose("test-idx-1").get();
-            }
-        } else {
-            // non-partial snapshots do not allow close / delete operations on indices where snapshot has not been completed
-            if (randomBoolean()) {
-                try {
-                    logger.info("--> delete index while non-partial snapshot is running");
+        try {
+            if (allowPartial) {
+                // partial snapshots allow close / delete operations
+                if (randomBoolean()) {
+                    logger.info("--> delete index while partial snapshot is running");
                     client.admin().indices().prepareDelete("test-idx-1").get();
-                    fail("Expected deleting index to fail during snapshot");
-                } catch (IllegalArgumentException e) {
-                    assertThat(e.getMessage(), containsString("Cannot delete indices that are being snapshotted: [test-idx-1]"));
+                } else {
+                    logger.info("--> close index while partial snapshot is running");
+                    client.admin().indices().prepareClose("test-idx-1").get();
                 }
             } else {
-                try {
-                    logger.info("--> close index while non-partial snapshot is running");
-                    client.admin().indices().prepareClose("test-idx-1").get();
-                    fail("Expected closing index to fail during snapshot");
-                } catch (IllegalArgumentException e) {
-                    assertThat(e.getMessage(), containsString("Cannot close indices that are being snapshotted: [test-idx-1]"));
+                // non-partial snapshots do not allow close / delete operations on indices where snapshot has not been completed
+                if (randomBoolean()) {
+                    try {
+                        logger.info("--> delete index while non-partial snapshot is running");
+                        client.admin().indices().prepareDelete("test-idx-1").get();
+                        fail("Expected deleting index to fail during snapshot");
+                    } catch (IllegalArgumentException e) {
+                        assertThat(e.getMessage(), containsString("Cannot delete indices that are being snapshotted: [test-idx-1]"));
+                    }
+                } else {
+                    try {
+                        logger.info("--> close index while non-partial snapshot is running");
+                        client.admin().indices().prepareClose("test-idx-1").get();
+                        fail("Expected closing index to fail during snapshot");
+                    } catch (IllegalArgumentException e) {
+                        assertThat(e.getMessage(), containsString("Cannot close indices that are being snapshotted: [test-idx-1]"));
+                    }
                 }
             }
-        }
-        if (initBlocking) {
-            logger.info("--> unblock running master node");
-            unblockNode(internalCluster().getMasterName());
-        } else {
-            logger.info("--> unblock all data nodes");
-            unblockAllDataNodes("test-repo");
+        } finally {
+            if (initBlocking) {
+                logger.info("--> unblock running master node");
+                unblockNode(internalCluster().getMasterName());
+            } else {
+                logger.info("--> unblock all data nodes");
+                unblockAllDataNodes("test-repo");
+            }
         }
         logger.info("--> waiting for snapshot to finish");
         CreateSnapshotResponse createSnapshotResponse = future.get();
@@ -1946,24 +1949,27 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
         blockAllDataNodes("test-repo");
         logger.info("--> execution will be blocked on all data nodes");
 
-        logger.info("--> start restore");
-        ListenableActionFuture restoreFut = client.admin().cluster().prepareRestoreSnapshot("test-repo", "test-snap")
-            .setWaitForCompletion(true)
-            .execute();
-
-        logger.info("--> waiting for block to kick in");
-        waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueSeconds(60));
-
-        logger.info("--> close index while restore is running");
+        final ListenableActionFuture restoreFut;
         try {
-            client.admin().indices().prepareClose("test-idx-1").get();
-            fail("Expected closing index to fail during restore");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("Cannot close indices that are being restored: [test-idx-1]"));
-        }
+            logger.info("--> start restore");
+            restoreFut = client.admin().cluster().prepareRestoreSnapshot("test-repo", "test-snap")
+                .setWaitForCompletion(true)
+                .execute();
 
-        logger.info("--> unblocking all data nodes");
-        unblockAllDataNodes("test-repo");
+            logger.info("--> waiting for block to kick in");
+            waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueSeconds(60));
+
+            logger.info("--> close index while restore is running");
+            try {
+                client.admin().indices().prepareClose("test-idx-1").get();
+                fail("Expected closing index to fail during restore");
+            } catch (IllegalArgumentException e) {
+                assertThat(e.getMessage(), containsString("Cannot close indices that are being restored: [test-idx-1]"));
+            }
+        } finally {
+            logger.info("--> unblocking all data nodes");
+            unblockAllDataNodes("test-repo");
+        }
 
         logger.info("--> wait for restore to finish");
         RestoreSnapshotResponse restoreSnapshotResponse = restoreFut.get();

From e91245e25f908c8bd5f2a3ebe439bd2ce56df86a Mon Sep 17 00:00:00 2001
From: Simon Willnauer 
Date: Fri, 11 Mar 2016 19:20:37 +0100
Subject: [PATCH 31/49] Use a seed node to form multi-node cluster in integ
 tests

Today we use hardcoded ports to form a cluster in the mulit-node case.
The hardcoded URIs are passed to the unicast host list which is error prone and
might cause problems if those ports are exhausted etc. This commit moves to a
less error prone way of forming the cluster where all nodes are started with port `0`
and all but the first node wait for the first node to write it's ports file to form a
cluster. This seed node is enough to form a cluster.
---
 .../gradle/test/ClusterConfiguration.groovy   | 17 +++++++++++
 .../gradle/test/ClusterFormationTasks.groovy  | 29 ++++++++++++-------
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
index c9db5657ba4..3e8b6225329 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
@@ -49,6 +49,15 @@ class ClusterConfiguration {
     @Input
     String jvmArgs = System.getProperty('tests.jvm.argline', '')
 
+    /**
+     * The seed nodes port file. In the case the cluster has more than one node we use a seed node
+     * to form the cluster. The file is null if there is no seed node yet available.
+     *
+     * Note: this can only be null if the cluster has only one node or if the first node is not yet
+     * configured. All nodes but the first node should see a non null value.
+     */
+    File seedNodePortsFile
+
     /**
      * A closure to call before the cluster is considered ready. The closure is passed the node info,
      * as well as a groovy AntBuilder, to enable running ant condition checks. The default wait
@@ -119,4 +128,12 @@ class ClusterConfiguration {
         }
         extraConfigFiles.put(path, sourceFile)
     }
+
+    /** Returns an address and port suitable for a uri to connect to this clusters seed node over transport protocol*/
+    String seedNodeTransportUri() {
+        if (seedNodePortsFile != null) {
+            return seedNodePortsFile.readLines("UTF-8").get(0)
+        }
+        return null;
+    }
 }
diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
index d96ee511051..59a27ea36bd 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
@@ -58,6 +58,13 @@ class ClusterFormationTasks {
         List nodes = []
         for (int i = 0; i < config.numNodes; ++i) {
             NodeInfo node = new NodeInfo(config, i, project, task)
+            if (i == 0) {
+                if (config.seedNodePortsFile != null) {
+                    // we might allow this in the future to be set but for now we are the only authority to set this!
+                    throw new GradleException("seedNodePortsFile has a non-null value but first node has not been intialized")
+                }
+                config.seedNodePortsFile = node.transportPortsFile;
+            }
             nodes.add(node)
             startTasks.add(configureNode(project, task, node))
         }
@@ -220,20 +227,22 @@ class ClusterFormationTasks {
                 'node.testattr'                : 'test',
                 'repositories.url.allowed_urls': 'http://snapshot.test*'
         ]
-        if (node.config.numNodes == 1) {
-            esConfig['http.port'] = node.config.httpPort
-            esConfig['transport.tcp.port'] =  node.config.transportPort
-        } else {
-            // TODO: fix multi node so it doesn't use hardcoded prots
-            esConfig['http.port'] = 9400 + node.nodeNum
-            esConfig['transport.tcp.port'] =  9500 + node.nodeNum
-            esConfig['discovery.zen.ping.unicast.hosts'] = (0.. 0) { // multi-node cluster case, we have to wait for the seed node to startup
+                ant.waitfor(maxwait: '20', maxwaitunit: 'second', checkevery: '500', checkeveryunit: 'millisecond') {
+                    resourceexists {
+                        file(file: node.config.seedNodePortsFile.toString())
+                    }
+                }
+                // the seed node is enough to form the cluster - all subsequent nodes will get the seed node as a unicast
+                // host and join the cluster via that.
+                esConfig['discovery.zen.ping.unicast.hosts'] = "\"${node.config.seedNodeTransportUri()}\""
+            }
             File configFile = new File(node.confDir, 'elasticsearch.yml')
             logger.info("Configuring ${configFile}")
             configFile.setText(esConfig.collect { key, value -> "${key}: ${value}" }.join('\n'), 'UTF-8')

From afb54bab4467a4cac38f314580840470d6907e8e Mon Sep 17 00:00:00 2001
From: Yannick Welsch 
Date: Fri, 11 Mar 2016 20:19:08 +0100
Subject: [PATCH 32/49] [TEST] Wait on all data nodes to be blocked if blocks
 active

Fixes race condition in MockRepository where unblock happens before block
---
 .../snapshots/AbstractSnapshotIntegTestCase.java          | 8 ++++----
 .../snapshots/SharedClusterSnapshotRestoreIT.java         | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
index dc803a46412..5ab6b5855c4 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
@@ -149,15 +149,15 @@ public abstract class AbstractSnapshotIntegTestCase extends ESIntegTestCase {
         }
     }
 
-    public void waitForBlockOnAnyDataNode(String repository, TimeValue timeout) throws InterruptedException {
+    public void waitForBlockOnAllDataNodes(String repository, TimeValue timeout) throws InterruptedException {
         if (false == awaitBusy(() -> {
             for(RepositoriesService repositoriesService : internalCluster().getDataNodeInstances(RepositoriesService.class)) {
                 MockRepository mockRepository = (MockRepository) repositoriesService.repository(repository);
-                if (mockRepository.blocked()) {
-                    return true;
+                if (mockRepository.blocked() == false) {
+                    return false;
                 }
             }
-            return false;
+            return true;
         }, timeout.millis(), TimeUnit.MILLISECONDS)) {
             fail("Timeout waiting for repository block on any data node!!!");
         }
diff --git a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
index cf0e37a51b4..00e4d590991 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
@@ -1860,7 +1860,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
         if (initBlocking) {
             waitForBlock(internalCluster().getMasterName(), "test-repo", TimeValue.timeValueMinutes(1));
         } else {
-            waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueMinutes(1));
+            waitForBlockOnAllDataNodes("test-repo", TimeValue.timeValueMinutes(1));
         }
         try {
             if (allowPartial) {
@@ -1957,7 +1957,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
                 .execute();
 
             logger.info("--> waiting for block to kick in");
-            waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueSeconds(60));
+            waitForBlockOnAllDataNodes("test-repo", TimeValue.timeValueMinutes(1));
 
             logger.info("--> close index while restore is running");
             try {

From 5bd7da56597391cc484873b413e72fa5757418c7 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Fri, 11 Mar 2016 11:46:23 -0800
Subject: [PATCH 33/49] Addressed PR feedback * Fix tests still referring to -E
 * add comment about missing classes * rename writer constant

---
 .../main/java/org/elasticsearch/cli/Terminal.java  | 14 +++++++-------
 modules/lang-groovy/build.gradle                   |  2 ++
 .../bootstrap/BootstrapCliParserTests.java         | 11 +++++++++--
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/cli/Terminal.java b/core/src/main/java/org/elasticsearch/cli/Terminal.java
index 00d886aa8ab..d2dc57263dc 100644
--- a/core/src/main/java/org/elasticsearch/cli/Terminal.java
+++ b/core/src/main/java/org/elasticsearch/cli/Terminal.java
@@ -89,35 +89,35 @@ public abstract class Terminal {
 
     private static class ConsoleTerminal extends Terminal {
 
-        private static final Console console = System.console();
+        private static final Console CONSOLE = System.console();
 
         ConsoleTerminal() {
             super(System.lineSeparator());
         }
 
         static boolean isSupported() {
-            return console != null;
+            return CONSOLE != null;
         }
 
         @Override
         public PrintWriter getWriter() {
-            return console.writer();
+            return CONSOLE.writer();
         }
 
         @Override
         public String readText(String prompt) {
-            return console.readLine("%s", prompt);
+            return CONSOLE.readLine("%s", prompt);
         }
 
         @Override
         public char[] readSecret(String prompt) {
-            return console.readPassword("%s", prompt);
+            return CONSOLE.readPassword("%s", prompt);
         }
     }
 
     private static class SystemTerminal extends Terminal {
 
-        private static final PrintWriter writer = newWriter();
+        private static final PrintWriter WRITER = newWriter();
 
         SystemTerminal() {
             super(System.lineSeparator());
@@ -130,7 +130,7 @@ public abstract class Terminal {
 
         @Override
         public PrintWriter getWriter() {
-            return writer;
+            return WRITER;
         }
 
         @Override
diff --git a/modules/lang-groovy/build.gradle b/modules/lang-groovy/build.gradle
index 005a7d4be18..2160210ba73 100644
--- a/modules/lang-groovy/build.gradle
+++ b/modules/lang-groovy/build.gradle
@@ -38,6 +38,8 @@ thirdPartyAudit.excludes = [
   // for example we do not need ivy, scripts arent allowed to download code
   'com.thoughtworks.xstream.XStream', 
   'groovyjarjarasm.asm.util.Textifiable', 
+  // commons-cli is referenced by groovy, even though they supposedly
+  // jarjar it. Since we don't use the cli, we don't need the dep.
   'org.apache.commons.cli.CommandLine',
   'org.apache.commons.cli.CommandLineParser',
   'org.apache.commons.cli.GnuParser',
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
index 2fc08f23a06..fc7504fc97f 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java
@@ -133,7 +133,7 @@ public class BootstrapCliParserTests extends CommandTestCase {
     public void testConfig() throws Exception {
         registerProperties("es.foo", "es.spam");
 
-        execute("-Efoo=bar", "-Espam=eggs");
+        execute("-Dfoo=bar", "-Dspam=eggs");
         assertSystemProperty("es.foo", "bar");
         assertSystemProperty("es.spam", "eggs");
         assertShouldRun(true);
@@ -141,11 +141,18 @@ public class BootstrapCliParserTests extends CommandTestCase {
 
     public void testConfigMalformed() throws Exception {
         UserError e = expectThrows(UserError.class, () -> {
-            execute("-Efoo");
+            execute("-Dfoo");
         });
         assertTrue(e.getMessage(), e.getMessage().contains("Malformed elasticsearch setting"));
     }
 
+    public void testUnknownOption() throws Exception {
+        OptionException e = expectThrows(OptionException.class, () -> {
+            execute("--network.host");
+        });
+        assertTrue(e.getMessage(), e.getMessage().contains("network.host is not a recognized option"));
+    }
+
     private void registerProperties(String ... systemProperties) {
         propertiesToClear.addAll(Arrays.asList(systemProperties));
     }

From 3f44e1d429cb9b84f9ff15479ebe232ffdfcfb8b Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Fri, 11 Mar 2016 11:52:59 -0800
Subject: [PATCH 34/49] Remove old reference to site plugins example in docs

---
 docs/plugins/authors.asciidoc | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/docs/plugins/authors.asciidoc b/docs/plugins/authors.asciidoc
index d0a606987ae..af3710f7e2d 100644
--- a/docs/plugins/authors.asciidoc
+++ b/docs/plugins/authors.asciidoc
@@ -26,9 +26,7 @@ https://github.com/elastic/elasticsearch/blob/master/buildSrc/src/main/resources
 Either fill in this template yourself (see
 https://github.com/lmenezes/elasticsearch-kopf/blob/master/plugin-descriptor.properties[elasticsearch-kopf]
 as an example) or, if you are using Elasticsearch's Gradle build system, you
-can fill in the necessary values in the `build.gradle` file for your plugin. For
-instance, see
-https://github.com/elastic/elasticsearch/blob/master/plugins/site-example/build.gradle[`/plugins/site-example/build.gradle`].
+can fill in the necessary values in the `build.gradle` file for your plugin.
 
 [float]
 ==== Mandatory elements for plugins

From 8b26c260d15107a16fc090e18da5190884b57bd6 Mon Sep 17 00:00:00 2001
From: Ryan Ernst 
Date: Fri, 11 Mar 2016 14:53:14 -0800
Subject: [PATCH 35/49] Plugins: Enforce plugin zip does not contain zip
 entries outside of the unzip dir

When unzipping a plugin zip, the zip entries are resolved relative to
the directory being unzipped into. However, there are currently no
checks that the entry name was not absolute, or relatively points
outside of the plugin dir. This change adds a check for those two cases.
---
 .../elasticsearch/plugins/InstallPluginCommand.java  |  9 ++++++++-
 .../plugins/InstallPluginCommandTests.java           | 12 ++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
index 32c4bf18507..e72eb2100f6 100644
--- a/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
+++ b/core/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java
@@ -250,7 +250,14 @@ class InstallPluginCommand extends Command {
                 }
                 hasEsDir = true;
                 Path targetFile = target.resolve(entry.getName().substring("elasticsearch/".length()));
-                // TODO: handle name being an absolute path
+
+                // Using the entry name as a path can result in an entry outside of the plugin dir, either if the
+                // name starts with the root of the filesystem, or it is a relative entry like ../whatever.
+                // This check attempts to identify both cases by first normalizing the path (which removes foo/..)
+                // and ensuring the normalized entry is still rooted with the target plugin directory.
+                if (targetFile.normalize().startsWith(target) == false) {
+                    throw new IOException("Zip contains entry name '" + entry.getName() + "' resolving outside of plugin directory");
+                }
 
                 // be on the safe side: do not rely on that directories are always extracted
                 // before their children (although this makes sense, but is it guaranteed?)
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
index 514090d9869..fb69c817f3a 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
@@ -466,6 +466,18 @@ public class InstallPluginCommandTests extends ESTestCase {
         assertInstallCleaned(env);
     }
 
+    public void testZipRelativeOutsideEntryName() throws Exception {
+        Path zip = createTempDir().resolve("broken.zip");
+        try (ZipOutputStream stream = new ZipOutputStream(Files.newOutputStream(zip))) {
+            stream.putNextEntry(new ZipEntry("elasticsearch/../blah"));
+        }
+        String pluginZip = zip.toUri().toURL().toString();
+        IOException e = expectThrows(IOException.class, () -> {
+            installPlugin(pluginZip, createEnv());
+        });
+        assertTrue(e.getMessage(), e.getMessage().contains("resolving outside of plugin directory"));
+    }
+
     // TODO: test batch flag?
     // TODO: test checksum (need maven/official below)
     // TODO: test maven, official, and staging install...need tests with fixtures...

From b1cf2b2cb3a4df4fb81683f3c3e9c6c8ec38b8da Mon Sep 17 00:00:00 2001
From: Clinton Gormley 
Date: Sat, 12 Mar 2016 14:58:30 +0100
Subject: [PATCH 36/49] Moved CONTRIBUTING.md back to the root directory

The CONTRIBUTING.md file can be in the root directory or
in the .github directory and will still be used for
the contributing guidelines on Github.

Moved back to the root directory so that it is more
visible outside Github
---
 .github/CONTRIBUTING.md => CONTRIBUTING.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename .github/CONTRIBUTING.md => CONTRIBUTING.md (100%)

diff --git a/.github/CONTRIBUTING.md b/CONTRIBUTING.md
similarity index 100%
rename from .github/CONTRIBUTING.md
rename to CONTRIBUTING.md

From 625695a92a3fc4c2850cd5d11ac5e739591beffc Mon Sep 17 00:00:00 2001
From: Yannick Welsch 
Date: Sun, 13 Mar 2016 14:06:46 +0100
Subject: [PATCH 37/49] [TEST] MockRepository should also unblock repositories
 that are not blocked yet

---
 .../snapshots/AbstractSnapshotIntegTestCase.java   |  8 ++++----
 .../snapshots/SharedClusterSnapshotRestoreIT.java  |  4 ++--
 .../snapshots/mockstore/MockRepository.java        | 14 ++++++--------
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
index 5ab6b5855c4..dc803a46412 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java
@@ -149,15 +149,15 @@ public abstract class AbstractSnapshotIntegTestCase extends ESIntegTestCase {
         }
     }
 
-    public void waitForBlockOnAllDataNodes(String repository, TimeValue timeout) throws InterruptedException {
+    public void waitForBlockOnAnyDataNode(String repository, TimeValue timeout) throws InterruptedException {
         if (false == awaitBusy(() -> {
             for(RepositoriesService repositoriesService : internalCluster().getDataNodeInstances(RepositoriesService.class)) {
                 MockRepository mockRepository = (MockRepository) repositoriesService.repository(repository);
-                if (mockRepository.blocked() == false) {
-                    return false;
+                if (mockRepository.blocked()) {
+                    return true;
                 }
             }
-            return true;
+            return false;
         }, timeout.millis(), TimeUnit.MILLISECONDS)) {
             fail("Timeout waiting for repository block on any data node!!!");
         }
diff --git a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
index 00e4d590991..5dc6d59692b 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java
@@ -1860,7 +1860,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
         if (initBlocking) {
             waitForBlock(internalCluster().getMasterName(), "test-repo", TimeValue.timeValueMinutes(1));
         } else {
-            waitForBlockOnAllDataNodes("test-repo", TimeValue.timeValueMinutes(1));
+            waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueMinutes(1));
         }
         try {
             if (allowPartial) {
@@ -1957,7 +1957,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
                 .execute();
 
             logger.info("--> waiting for block to kick in");
-            waitForBlockOnAllDataNodes("test-repo", TimeValue.timeValueMinutes(1));
+            waitForBlockOnAnyDataNode("test-repo", TimeValue.timeValueMinutes(1));
 
             logger.info("--> close index while restore is running");
             try {
diff --git a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java
index 7a6b327ff89..3b5bde99f55 100644
--- a/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java
+++ b/core/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java
@@ -176,14 +176,12 @@ public class MockRepository extends FsRepository {
     }
 
     public synchronized void unblockExecution() {
-        if (blocked) {
-            blocked = false;
-            // Clean blocking flags, so we wouldn't try to block again
-            blockOnDataFiles = false;
-            blockOnControlFiles = false;
-            blockOnInitialization = false;
-            this.notifyAll();
-        }
+        blocked = false;
+        // Clean blocking flags, so we wouldn't try to block again
+        blockOnDataFiles = false;
+        blockOnControlFiles = false;
+        blockOnInitialization = false;
+        this.notifyAll();
     }
 
     public boolean blocked() {

From e9e1e2599845e7ebfa13d73e510890c97d704858 Mon Sep 17 00:00:00 2001
From: David Pilato 
Date: Sun, 13 Mar 2016 15:01:09 +0100
Subject: [PATCH 38/49] Fix after merge with master

---
 .../org/elasticsearch/cluster/NodeConnectionsService.java   | 6 +++++-
 .../elasticsearch/cluster/node/DiscoveryNodeService.java    | 3 ++-
 .../elasticsearch/common/settings/IndexScopedSettings.java  | 4 ++--
 .../java/org/elasticsearch/common/settings/Setting.java     | 6 +++---
 4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java b/core/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
index cce25652ed7..698f9d1090c 100644
--- a/core/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
+++ b/core/src/main/java/org/elasticsearch/cluster/NodeConnectionsService.java
@@ -35,6 +35,10 @@ import org.elasticsearch.transport.TransportService;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ScheduledFuture;
 
+import static org.elasticsearch.common.settings.Setting.Property;
+import static org.elasticsearch.common.settings.Setting.positiveTimeSetting;
+
+
 /**
  * This component is responsible for connecting to nodes once they are added to the cluster state, and disconnect when they are
  * removed. Also, it periodically checks that all connections are still open and if needed restores them.
@@ -45,7 +49,7 @@ import java.util.concurrent.ScheduledFuture;
 public class NodeConnectionsService extends AbstractLifecycleComponent {
 
     public static final Setting CLUSTER_NODE_RECONNECT_INTERVAL_SETTING =
-            Setting.positiveTimeSetting("cluster.nodes.reconnect_interval", TimeValue.timeValueSeconds(10), false, Setting.Scope.CLUSTER);
+            positiveTimeSetting("cluster.nodes.reconnect_interval", TimeValue.timeValueSeconds(10), Property.NodeScope);
     private final ThreadPool threadPool;
     private final TransportService transportService;
 
diff --git a/core/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeService.java b/core/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeService.java
index 47c0e0052d3..ccd30a99e9c 100644
--- a/core/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeService.java
+++ b/core/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeService.java
@@ -25,6 +25,7 @@ import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.component.AbstractComponent;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.Setting;
+import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.transport.TransportAddress;
 
@@ -40,7 +41,7 @@ public class DiscoveryNodeService extends AbstractComponent {
 
     public static final Setting NODE_ID_SEED_SETTING =
             // don't use node.id.seed so it won't be seen as an attribute
-            Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, false, Setting.Scope.CLUSTER);
+            Setting.longSetting("node_id.seed", 0L, Long.MIN_VALUE, Property.NodeScope);
     private final List customAttributesProviders = new CopyOnWriteArrayList<>();
     private final Version version;
 
diff --git a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
index 983bb27f590..da6c34bdf4a 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
@@ -137,14 +137,14 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
         EngineConfig.INDEX_CODEC_SETTING,
         IndexWarmer.INDEX_NORMS_LOADING_SETTING,
         // validate that built-in similarities don't get redefined
-        Setting.groupSetting("index.similarity.", Property.IndexScope, (s) -> {
+        Setting.groupSetting("index.similarity.", (s) -> {
             Map groups = s.getAsGroups();
             for (String key : SimilarityService.BUILT_IN.keySet()) {
                 if (groups.containsKey(key)) {
                     throw new IllegalArgumentException("illegal value for [index.similarity."+ key + "] cannot redefine built-in similarity");
                 }
             }
-        }), // this allows similarity settings to be passed
+        }, Property.IndexScope), // this allows similarity settings to be passed
         Setting.groupSetting("index.analysis.", Property.IndexScope) // this allows analysis settings to be passed
 
     )));
diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
index 6c97091fb6f..f6f2d28b921 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
@@ -586,10 +586,10 @@ public class Setting extends ToXContentToBytes {
             throw new ElasticsearchException(ex);
         }
     }
-    public static Setting groupSetting(String key, boolean dynamic, Scope scope) {
-        return groupSetting(key, dynamic, scope, (s) -> {});
-    }
     public static Setting groupSetting(String key, Property... properties) {
+        return groupSetting(key, (s) -> {}, properties);
+    }
+    public static Setting groupSetting(String key, Consumer validator, Property... properties) {
         return new Setting(new GroupKey(key), (s) -> "", (s) -> null, properties) {
             @Override
             public boolean isGroupSetting() {

From 25531b7299ff19b56ed939478332b75a4c574dd9 Mon Sep 17 00:00:00 2001
From: David Pilato 
Date: Sun, 13 Mar 2016 15:27:54 +0100
Subject: [PATCH 39/49] Update after last review

We check for null. Test added as well.
---
 .../org/elasticsearch/common/settings/Setting.java   |  7 ++++++-
 .../elasticsearch/common/settings/SettingTests.java  | 12 ++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/elasticsearch/common/settings/Setting.java b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
index f6f2d28b921..f0e1b2e64ea 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/Setting.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/Setting.java
@@ -113,6 +113,8 @@ public class Setting extends ToXContentToBytes {
     private final Function parser;
     private final EnumSet properties;
 
+    private static final EnumSet EMPTY_PROPERTIES = EnumSet.noneOf(Property.class);
+
     /**
      * Creates a new Setting instance. When no scope is provided, we default to {@link Property#NodeScope}.
      * @param key the settings key for this setting.
@@ -125,8 +127,11 @@ public class Setting extends ToXContentToBytes {
         this.key = key;
         this.defaultValue = defaultValue;
         this.parser = parser;
+        if (properties == null) {
+            throw new IllegalArgumentException("properties can not be null for setting [" + key + "]");
+        }
         if (properties.length == 0) {
-            this.properties = EnumSet.noneOf(Property.class);
+            this.properties = EMPTY_PROPERTIES;
         } else {
             this.properties = EnumSet.copyOf(Arrays.asList(properties));
         }
diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
index 1c1f06f5914..14fdcb1e0ac 100644
--- a/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
+++ b/core/src/test/java/org/elasticsearch/common/settings/SettingTests.java
@@ -445,4 +445,16 @@ public class SettingTests extends ESTestCase {
         assertThat(setting.hasIndexScope(), is(true));
         assertThat(setting.hasNodeScope(), is(true));
     }
+
+    /**
+     * We can't have Null properties
+     */
+    public void testRejectNullProperties() {
+        try {
+            Setting.simpleString("foo.bar", (Property[]) null);
+            fail();
+        } catch (IllegalArgumentException ex) {
+            assertThat(ex.getMessage(), containsString("properties can not be null for setting"));
+        }
+    }
 }

From 5c845f8bb557db280086fe016b5b141b0ae34f2c Mon Sep 17 00:00:00 2001
From: Clinton Gormley 
Date: Sun, 13 Mar 2016 21:17:48 +0100
Subject: [PATCH 40/49] Reworked 5.0 breaking changes docs

---
 docs/reference/migration/migrate_5_0.asciidoc | 887 +-----------------
 .../migration/migrate_5_0/allocation.asciidoc |  54 ++
 .../migration/migrate_5_0/cat.asciidoc        |  33 +
 .../migration/migrate_5_0/index-apis.asciidoc |  48 +
 .../migration/migrate_5_0/java.asciidoc       | 213 +++++
 .../migration/migrate_5_0/mapping.asciidoc    |  82 ++
 .../migration/migrate_5_0/packaging.asciidoc  |  24 +
 .../migration/migrate_5_0/percolator.asciidoc |  41 +
 .../migration/migrate_5_0/plugins.asciidoc    |  99 ++
 .../migration/migrate_5_0/rest.asciidoc       |  17 +
 .../migration/migrate_5_0/search.asciidoc     | 141 +++
 .../migration/migrate_5_0/settings.asciidoc   | 174 ++++
 12 files changed, 957 insertions(+), 856 deletions(-)
 create mode 100644 docs/reference/migration/migrate_5_0/allocation.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/cat.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/index-apis.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/java.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/mapping.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/packaging.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/percolator.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/plugins.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/rest.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/search.asciidoc
 create mode 100644 docs/reference/migration/migrate_5_0/settings.asciidoc

diff --git a/docs/reference/migration/migrate_5_0.asciidoc b/docs/reference/migration/migrate_5_0.asciidoc
index 8e082a1e426..23cadbbd9ed 100644
--- a/docs/reference/migration/migrate_5_0.asciidoc
+++ b/docs/reference/migration/migrate_5_0.asciidoc
@@ -4,877 +4,52 @@
 This section discusses the changes that you need to be aware of when migrating
 your application to Elasticsearch 5.0.
 
+[IMPORTANT]
+.Reindex indices from Elasticseach 1.x or before
+=========================================
+
+Indices created in Elasticsearch 1.x or before will need to be reindexed with
+Elasticsearch 2.x in order to be readable by Elasticsearch 5.x. The easiest
+way to do this is to upgrade to Elasticsearch 2.3 or later and to use the
+`reindex` API.
+
+=========================================
+
+[float]
+=== Also see:
+
 * <>
+* <>
+* <>
+* <>
+* <>
+* <>
 * <>
 * <>
-* <>
-* <>
-* <>
-* <>
 * <>
-* <>
-* <>
-* <>
-* <>
-* <>
 * <>
-* <>
-* <>
-* <>
-* <>
+* <>
 
-[[breaking_50_search_changes]]
-=== Warmers
+include::migrate_5_0/search.asciidoc[]
 
-Thanks to several changes like doc values by default or disk-based norms,
-warmers have become quite useless. As a consequence, warmers and the warmer
-API have been removed: it is not possible anymore to register queries that
-will run before a new IndexSearcher is published.
+include::migrate_5_0/mapping.asciidoc[]
 
-Don't worry if you have warmers defined on your indices, they will simply be
-ignored when upgrading to 5.0.
+include::migrate_5_0/percolator.asciidoc[]
 
-=== Search changes
+include::migrate_5_0/index-apis.asciidoc[]
 
-==== `search_type=count` removed
+include::migrate_5_0/settings.asciidoc[]
 
-The `count` search type was deprecated since version 2.0.0 and is now removed.
-In order to get the same benefits, you just need to set the value of the `size`
-parameter to `0`.
+include::migrate_5_0/allocation.asciidoc[]
 
-For instance, the following request:
+include::migrate_5_0/rest.asciidoc[]
 
-[source,sh]
----------------
-GET /my_index/_search?search_type=count
-{
-  "aggs": {
-    "my_terms": {
-       "terms": {
-         "field": "foo"
-       }
-     }
-  }
-}
----------------
+include::migrate_5_0/cat.asciidoc[]
 
-can be replaced with:
+include::migrate_5_0/java.asciidoc[]
 
-[source,sh]
----------------
-GET /my_index/_search
-{
-  "size": 0,
-  "aggs": {
-    "my_terms": {
-       "terms": {
-         "field": "foo"
-       }
-     }
-  }
-}
----------------
+include::migrate_5_0/packaging.asciidoc[]
 
-==== `search_type=scan` removed
+include::migrate_5_0/plugins.asciidoc[]
 
-The `scan` search type was deprecated since version 2.1.0 and is now removed.
-All benefits from this search type can now be achieved by doing a scroll
-request that sorts documents in `_doc` order, for instance:
 
-[source,sh]
----------------
-GET /my_index/_search?scroll=2m
-{
-  "sort": [
-    "_doc"
-  ]
-}
----------------
-
-Scroll requests sorted by `_doc` have been optimized to more efficiently resume
-from where the previous request stopped, so this will have the same performance
-characteristics as the former `scan` search type.
-
-==== Boost accuracy for queries on `_all`
-
-Per-field boosts on the `_all` are now compressed on a single byte instead of
-4 bytes previously. While this will make the index more space-efficient, this
-also means that the boosts will be less accurately encoded.
-
-[[breaking_50_rest_api_changes]]
-=== REST API changes
-
-==== id values longer than 512 bytes are rejected
-
-When specifying an `_id` value longer than 512 bytes, the request will be
-rejected.
-
-==== search exists api removed
-
-The search exists api has been removed in favour of using the search api with
-`size` set to `0` and `terminate_after` set to `1`.
-
-==== `/_optimize` endpoint removed
-
-The deprecated `/_optimize` endpoint has been removed. The `/_forcemerge`
-endpoint should be used in lieu of optimize.
-
-The `GET` HTTP verb for `/_forcemerge` is no longer supported, please use the
-`POST` HTTP verb.
-
-==== Deprecated queries removed
-
-The following deprecated queries have been removed:
-
-* `filtered`: use `bool` query instead, which supports `filter` clauses too
-* `and`: use `must` clauses in a `bool` query instead
-* `or`: use should clauses in a `bool` query instead
-* `limit`: use `terminate_after` parameter instead
-* `fquery`: obsolete after filters and queries have been merged
-* `query`: obsolete after filters and queries have been merged
-
-==== Unified fuzziness parameter
-
-* Removed support for the deprecated `min_similarity` parameter in `fuzzy query`, in favour of `similarity`.
-* Removed support for the deprecated `fuzzy_min_sim` parameter in `query_string` query, in favour of `similarity`.
-* Removed support for the deprecated `edit_distance` parameter in completion suggester, in favour of `similarity`.
-
-==== indices query
-
-Removed support for the deprecated `filter` and `no_match_filter` fields in `indices` query,
-in favour of `query` and `no_match_query`.
-
-==== nested query
-
-Removed support for the deprecated `filter` fields in `nested` query, in favour of `query`.
-
-==== terms query
-
-Removed support for the deprecated `minimum_should_match` and `disable_coord` in `terms` query, use `bool` query instead.
-Removed also support for the deprecated `execution` parameter.
-
-==== function_score query
-
-Removed support for the top level `filter` element in `function_score` query, replaced by `query`.
-
-==== highlighters
-
-Removed support for multiple highlighter names, the only supported ones are: `plain`, `fvh` and `postings`.
-
-==== top level filter
-
-Removed support for the deprecated top level `filter` in the search api, replaced by `post_filter`.
-
-==== `query_binary` and `filter_binary` removed
-
-Removed support for the undocumented `query_binary` and `filter_binary` sections of a search request.
-
-==== `span_near`'s' `collect_payloads` deprecated
-
-Payloads are now loaded when needed.
-
-[[breaking_50_cat_api]]
-=== CAT API changes
-
-==== Use Accept header for specifying response media type
-
-Previous versions of Elasticsearch accepted the Content-type header
-field for controlling the media type of the response in the cat API.
-This is in opposition to the HTTP spec which specifies the Accept
-header field for this purpose. Elasticsearch now uses the Accept header
-field and support for using the Content-Type header field for this
-purpose has been removed.
-
-==== Host field removed from the cat nodes API
-
-The `host` field has been removed from the cat nodes API as its value
-is always equal to the `ip` field. The `name` field is available in the
-cat nodes API and should be used instead of the `host` field.
-
-==== Changes to cat recovery API
-
-The fields `bytes_recovered` and `files_recovered` have been added to
-the cat recovery API. These fields, respectively, indicate the total
-number of bytes and files that have been recovered.
-
-The fields `total_files` and `total_bytes` have been renamed to
-`files_total` and `bytes_total`, respectively.
-
-Additionally, the field `translog` has been renamed to
-`translog_ops_recovered`, the field `translog_total` to
-`translog_ops` and the field `translog_percent` to
-`translog_ops_percent`. The short aliases for these fields are `tor`,
-`to`, and `top`, respectively.
-
-[[breaking_50_parent_child_changes]]
-=== Parent/Child changes
-
-The `children` aggregation, parent child inner hits and `has_child` and `has_parent` queries will not work on indices
-with `_parent` field mapping created before version `2.0.0`. The data of these indices need to be re-indexed into a new index.
-
-The format of the join between parent and child documents have changed with the `2.0.0` release. The old
-format can't read from version `5.0.0` and onwards. The new format allows for a much more efficient and
-scalable join between parent and child documents and the join data structures are stored on disk
-data structures as opposed as before the join data structures were stored in the jvm heap space.
-
-==== `score_type` has been removed
-
-The `score_type` option has been removed from the `has_child` and `has_parent` queries in favour of the `score_mode` option
-which does the exact same thing.
-
-==== `sum` score mode removed
-
-The `sum` score mode has been removed in favour of the `total` mode which does the same and is already available in
-previous versions.
-
-==== `max_children` option
-
-When `max_children` was set to `0` on the `has_child` query then there was no upper limit on how many children documents
-are allowed to match. This has changed and `0` now really means to zero child documents are allowed. If no upper limit
-is needed then the `max_children` option shouldn't be defined at all on the `has_child` query.
-
-==== `_parent` field no longer indexed
-
-The join between parent and child documents no longer relies on indexed fields and therefor from `5.0.0` onwards
-the `_parent` indexed field won't be indexed. In order to find documents that referrer to a specific parent id
-the new `parent_id` query can be used. The get response and hits inside the search response remain to include
-the parent id under the `_parent` key.
-
-[[breaking_50_settings_changes]]
-=== Settings changes
-
-From Elasticsearch 5.0 on all settings are validated before they are applied. Node level and default index
-level settings are validated on node startup, dynamic cluster and index setting are validated before they are updated/added
-to the cluster state. Every setting must be a _known_ setting or in other words all settings must be registered with the
-node or transport client they are used with. This implies that plugins that define custom settings must register all of their
-settings during pluging loading using the `SettingsModule#registerSettings(Setting)` method.
-
-==== Node settings
-
-The `name` setting has been removed and is replaced by `node.name`. Usage of `-Dname=some_node_name` is not supported
-anymore.
-
-==== Transport Settings
-
-All settings with a `netty` infix have been replaced by their already existing `transport` synonyms. For instance `transport.netty.bind_host` is
-no longer supported and should be replaced by the superseding setting `transport.bind_host`.
-
-==== Analysis settings
-
-The `index.analysis.analyzer.default_index` analyzer is not supported anymore.
-If you wish to change the analyzer to use for indexing, change the
-`index.analysis.analyzer.default` analyzer instead.
-
-==== Ping timeout settings
-
-Previously, there were three settings for the ping timeout: `discovery.zen.initial_ping_timeout`,
-`discovery.zen.ping.timeout` and `discovery.zen.ping_timeout`. The former two have been removed and
-the only setting key for the ping timeout is now `discovery.zen.ping_timeout`. The default value for
-ping timeouts remains at three seconds.
-
-==== Recovery settings
-
-Recovery settings deprecated in 1.x have been removed:
-
- * `index.shard.recovery.translog_size` is superseded by `indices.recovery.translog_size`
- * `index.shard.recovery.translog_ops` is superseded by `indices.recovery.translog_ops`
- * `index.shard.recovery.file_chunk_size` is superseded by `indices.recovery.file_chunk_size`
- * `index.shard.recovery.concurrent_streams` is superseded by `indices.recovery.concurrent_streams`
- * `index.shard.recovery.concurrent_small_file_streams` is superseded by `indices.recovery.concurrent_small_file_streams`
- * `indices.recovery.max_size_per_sec` is superseded by `indices.recovery.max_bytes_per_sec`
-
-If you are using any of these settings please take the time and review their purpose. All of the settings above are considered
-_expert settings_ and should only be used if absolutely necessary. If you have set any of the above setting as persistent
-cluster settings please use the settings update API and set their superseded keys accordingly.
-
-The following settings have been removed without replacement
-
- * `indices.recovery.concurrent_small_file_streams` - recoveries are now single threaded. The number of concurrent outgoing recoveries are throttled via allocation deciders
- * `indices.recovery.concurrent_file_streams` - recoveries are now single threaded. The number of concurrent outgoing recoveries are throttled via allocation deciders
-
-==== Translog settings
-
-The `index.translog.flush_threshold_ops` setting is not supported anymore. In order to control flushes based on the transaction log
-growth use `index.translog.flush_threshold_size` instead. Changing the translog type with `index.translog.fs.type` is not supported
-anymore, the `buffered` implementation is now the only available option and uses a fixed `8kb` buffer.
-
-The translog by default is fsynced on a request basis such that the ability to fsync on every operation is not necessary anymore. In-fact it can
-be a performance bottleneck and it's trappy since it enabled by a special value set on `index.translog.sync_interval`. `index.translog.sync_interval`
-now doesn't accept a value less than `100ms` which prevents fsyncing too often if async durability is enabled. The special value `0` is not supported anymore.
-
-==== Request Cache Settings
-
-The deprecated settings `index.cache.query.enable` and `indices.cache.query.size` have been removed and are replaced with
-`index.requests.cache.enable` and `indices.requests.cache.size` respectively.
-
-`indices.requests.cache.clean_interval` has been replaced with `indices.cache.clean_interval` and is no longer supported.
-
-==== Field Data Cache Settings
-
-`indices.fielddata.cache.clean_interval` has been replaced with `indices.cache.clean_interval` and is no longer supported.
-
-==== Allocation settings
-
-Allocation settings deprecated in 1.x have been removed:
-
- * `cluster.routing.allocation.concurrent_recoveries` is superseded by `cluster.routing.allocation.node_concurrent_recoveries`
-
-Please change the setting in your configuration files or in the clusterstate to use the new settings instead.
-
-==== Similarity settings
-
-The 'default' similarity has been renamed to 'classic'.
-
-==== Indexing settings
-
-`indices.memory.min_shard_index_buffer_size` and `indices.memory.max_shard_index_buffer_size` are removed since Elasticsearch now allows any one shard to any
-amount of heap as long as the total indexing buffer heap used across all shards is below the node's `indices.memory.index_buffer_size` (default: 10% of the JVM heap)
-
-==== Removed es.max-open-files
-
-Setting the system property es.max-open-files to true to get
-Elasticsearch to print the number of maximum open files for the
-Elasticsearch process has been removed. This same information can be
-obtained from the <> API, and a warning is logged
-on startup if it is set too low.
-
-==== Removed es.netty.gathering
-
-Disabling Netty from using NIO gathering could be done via the escape
-hatch of setting the system property "es.netty.gathering" to "false".
-Time has proven enabling gathering by default is a non-issue and this
-non-documented setting has been removed.
-
-==== Removed es.useLinkedTransferQueue
-
-The system property `es.useLinkedTransferQueue` could be used to
-control the queue implementation used in the cluster service and the
-handling of ping responses during discovery. This was an undocumented
-setting and has been removed.
-
-[[breaking_50_mapping_changes]]
-=== Mapping changes
-
-==== Default doc values settings
-
-Doc values are now also on by default on numeric and boolean fields that are
-not indexed.
-
-==== Transform removed
-
-The `transform` feature from mappings has been removed. It made issues very hard to debug.
-
-==== Default number mappings
-
-When a floating-point number is encountered, it is now dynamically mapped as a
-float by default instead of a double. The reasoning is that floats should be
-more than enough for most cases but would decrease storage requirements
-significantly.
-
-==== `index` property
-
-On all types but `string`, the `index` property now only accepts `true`/`false`
-instead of `not_analyzed`/`no`. The `string` field still accepts
-`analyzed`/`not_analyzed`/`no`.
-
-==== ++_source++'s `format` option
-
-The `_source` mapping does not support the `format` option anymore. This option
-will still be accepted for indices created before the upgrade to 5.0 for backward
-compatibility, but it will have no effect. Indices created on or after 5.0 will
-reject this option.
-
-==== Object notation
-
-Core types don't support the object notation anymore, which allowed to provide
-values as follows:
-
-[source,json]
----------------
-{
-  "value": "field_value",
-  "boost": 42
-}
----------------
-
-==== `fielddata.format`
-
-Setting `fielddata.format: doc_values` in the mappings used to implicitly
-enable doc values on a field. This no longer works: the only way to enable or
-disable doc values is by using the `doc_values` property of mappings.
-
-
-[[breaking_50_plugins]]
-=== Plugin changes
-
-The command `bin/plugin` has been renamed to `bin/elasticsearch-plugin`.
-The structure of the plugin has changed. All the plugin files must be contained in a directory called `elasticsearch`.
-If you use the gradle build, this structure is automatically generated.
-
-==== Site plugins removed
-
-Site plugins have been removed. It is recommended to migrate site plugins to Kibana plugins.
-
-==== Multicast plugin removed
-
-Multicast has been removed. Use unicast discovery, or one of the cloud discovery plugins.
-
-==== Plugins with custom query implementations
-
-Plugins implementing custom queries need to implement the `fromXContent(QueryParseContext)` method in their
-`QueryParser` subclass rather than `parse`. This method will take care of parsing the query from `XContent` format
-into an intermediate query representation that can be streamed between the nodes in binary format, effectively the
-query object used in the java api. Also, the query parser needs to implement the `getBuilderPrototype` method that
-returns a prototype of the `NamedWriteable` query, which allows to deserialize an incoming query by calling
-`readFrom(StreamInput)` against it, which will create a new object, see usages of `Writeable`. The `QueryParser`
-also needs to declare the generic type of the query that it supports and it's able to parse.
-The query object can then transform itself into a lucene query through the new `toQuery(QueryShardContext)` method,
-which returns a lucene query to be executed on the data node.
-
-Similarly, plugins implementing custom score functions need to implement the `fromXContent(QueryParseContext)`
-method in their `ScoreFunctionParser` subclass rather than `parse`. This method will take care of parsing
-the function from `XContent` format into an intermediate function representation that can be streamed between
-the nodes in binary format, effectively the function object used in the java api. Also, the query parser needs
-to implement the `getBuilderPrototype` method that returns a prototype of the `NamedWriteable` function, which
-allows to deserialize an incoming function by calling `readFrom(StreamInput)` against it, which will create a
-new object, see usages of `Writeable`. The `ScoreFunctionParser` also needs to declare the generic type of the
-function that it supports and it's able to parse. The function object can then transform itself into a lucene
-function through the new `toFunction(QueryShardContext)` method, which returns a lucene function to be executed
-on the data node.
-
-==== Cloud AWS plugin changes
-
-Cloud AWS plugin has been split in two plugins:
-
-* {plugins}/discovery-ec2.html[Discovery EC2 plugin]
-* {plugins}/repository-s3.html[Repository S3 plugin]
-
-Proxy settings for both plugins have been renamed:
-
-* from `cloud.aws.proxy_host` to `cloud.aws.proxy.host`
-* from `cloud.aws.ec2.proxy_host` to `cloud.aws.ec2.proxy.host`
-* from `cloud.aws.s3.proxy_host` to `cloud.aws.s3.proxy.host`
-* from `cloud.aws.proxy_port` to `cloud.aws.proxy.port`
-* from `cloud.aws.ec2.proxy_port` to `cloud.aws.ec2.proxy.port`
-* from `cloud.aws.s3.proxy_port` to `cloud.aws.s3.proxy.port`
-
-==== Cloud Azure plugin changes
-
-Cloud Azure plugin has been split in three plugins:
-
-* {plugins}/discovery-azure.html[Discovery Azure plugin]
-* {plugins}/repository-azure.html[Repository Azure plugin]
-* {plugins}/store-smb.html[Store SMB plugin]
-
-If you were using the `cloud-azure` plugin for snapshot and restore, you had in `elasticsearch.yml`:
-
-[source,yaml]
------
-cloud:
-    azure:
-        storage:
-            account: your_azure_storage_account
-            key: your_azure_storage_key
------
-
-You need to give a unique id to the storage details now as you can define multiple storage accounts:
-
-[source,yaml]
------
-cloud:
-    azure:
-        storage:
-            my_account:
-                account: your_azure_storage_account
-                key: your_azure_storage_key
------
-
-
-==== Cloud GCE plugin changes
-
-Cloud GCE plugin has been renamed to {plugins}/discovery-gce.html[Discovery GCE plugin].
-
-
-==== Mapper Attachments plugin deprecated
-
-Mapper attachments has been deprecated. Users should use now the {plugins}/ingest-attachment.html[`ingest-attachment`]
-plugin.
-
-
-[[breaking_50_java_api_changes]]
-=== Java API changes
-
-==== Count api has been removed
-
-The deprecated count api has been removed from the Java api, use the search api instead and set size to 0.
-
-The following call
-
-[source,java]
------
-client.prepareCount(indices).setQuery(query).get();
------
-
-can be replaced with
-
-[source,java]
------
-client.prepareSearch(indices).setSource(new SearchSourceBuilder().size(0).query(query)).get();
------
-
-==== BoostingQueryBuilder
-
-Removed setters for mandatory positive/negative query. Both arguments now have
-to be supplied at construction time already and have to be non-null.
-
-==== SpanContainingQueryBuilder
-
-Removed setters for mandatory big/little inner span queries. Both arguments now have
-to be supplied at construction time already and have to be non-null. Updated
-static factory methods in QueryBuilders accordingly.
-
-==== SpanOrQueryBuilder
-
-Making sure that query contains at least one clause by making initial clause mandatory
-in constructor.
-
-==== SpanNearQueryBuilder
-
-Removed setter for mandatory slop parameter, needs to be set in constructor now. Also
-making sure that query contains at least one clause by making initial clause mandatory
-in constructor. Updated the static factory methods in QueryBuilders accordingly.
-
-==== SpanNotQueryBuilder
-
-Removed setter for mandatory include/exclude span query clause, needs to be set in constructor now.
-Updated the static factory methods in QueryBuilders and tests accordingly.
-
-==== SpanWithinQueryBuilder
-
-Removed setters for mandatory big/little inner span queries. Both arguments now have
-to be supplied at construction time already and have to be non-null. Updated
-static factory methods in QueryBuilders accordingly.
-
-==== QueryFilterBuilder
-
-Removed the setter `queryName(String queryName)` since this field is not supported
-in this type of query. Use `FQueryFilterBuilder.queryName(String queryName)` instead
-when in need to wrap a named query as a filter.
-
-==== WrapperQueryBuilder
-
-Removed `wrapperQueryBuilder(byte[] source, int offset, int length)`. Instead simply
-use  `wrapperQueryBuilder(byte[] source)`. Updated the static factory methods in
-QueryBuilders accordingly.
-
-==== QueryStringQueryBuilder
-
-Removed ability to pass in boost value using `field(String field)` method in form e.g. `field^2`.
-Use the `field(String, float)` method instead.
-
-==== Operator
-
-Removed the enums called `Operator` from `MatchQueryBuilder`, `QueryStringQueryBuilder`,
-`SimpleQueryStringBuilder`, and `CommonTermsQueryBuilder` in favour of using the enum
-defined in `org.elasticsearch.index.query.Operator` in an effort to consolidate the
-codebase and avoid duplication.
-
-==== queryName and boost support
-
-Support for `queryName` and `boost` has been streamlined to all of the queries. That is
-a breaking change till queries get sent over the network as serialized json rather
-than in `Streamable` format. In fact whenever additional fields are added to the json
-representation of the query, older nodes might throw error when they find unknown fields.
-
-==== InnerHitsBuilder
-
-InnerHitsBuilder now has a dedicated addParentChildInnerHits and addNestedInnerHits methods
-to differentiate between inner hits for nested vs. parent / child documents. This change
-makes the type / path parameter mandatory.
-
-==== MatchQueryBuilder
-
-Moving MatchQueryBuilder.Type and MatchQueryBuilder.ZeroTermsQuery enum to MatchQuery.Type.
-Also reusing new Operator enum.
-
-==== MoreLikeThisQueryBuilder
-
-Removed `MoreLikeThisQueryBuilder.Item#id(String id)`, `Item#doc(BytesReference doc)`,
-`Item#doc(XContentBuilder doc)`. Use provided constructors instead.
-
-Removed `MoreLikeThisQueryBuilder#addLike` in favor of texts and/or items being provided
-at construction time. Using arrays there instead of lists now.
-
-Removed `MoreLikeThisQueryBuilder#addUnlike` in favor to using the `unlike` methods
-which take arrays as arguments now rather than the lists used before.
-
-The deprecated `docs(Item... docs)`, `ignoreLike(Item... docs)`,
-`ignoreLike(String... likeText)`, `addItem(Item... likeItems)` have been removed.
-
-==== GeoDistanceQueryBuilder
-
-Removing individual setters for lon() and lat() values, both values should be set together
- using point(lon, lat).
-
-==== GeoDistanceRangeQueryBuilder
-
-Removing setters for to(Object ...) and from(Object ...) in favour of the only two allowed input
-arguments (String, Number). Removing setter for center point (point(), geohash()) because parameter
-is mandatory and should already be set in constructor.
-Also removing setters for lt(), lte(), gt(), gte() since they can all be replaced by equivalent
-calls to to/from() and inludeLower()/includeUpper().
-
-==== GeoPolygonQueryBuilder
-
-Require shell of polygon already to be specified in constructor instead of adding it pointwise.
-This enables validation, but makes it necessary to remove the addPoint() methods.
-
-==== MultiMatchQueryBuilder
-
-Moving MultiMatchQueryBuilder.ZeroTermsQuery enum to MatchQuery.ZeroTermsQuery.
-Also reusing new Operator enum.
-
-Removed ability to pass in boost value using `field(String field)` method in form e.g. `field^2`.
-Use the `field(String, float)` method instead.
-
-==== MissingQueryBuilder
-
-The MissingQueryBuilder which was deprecated in 2.2.0 is removed. As a replacement use ExistsQueryBuilder
-inside a mustNot() clause. So instead of using `new ExistsQueryBuilder(name)` now use
-`new BoolQueryBuilder().mustNot(new ExistsQueryBuilder(name))`.
-
-==== NotQueryBuilder
-
-The NotQueryBuilder which was deprecated in 2.1.0 is removed. As a replacement use BoolQueryBuilder
-with added mustNot() clause. So instead of using `new NotQueryBuilder(filter)` now use
-`new BoolQueryBuilder().mustNot(filter)`.
-
-==== TermsQueryBuilder
-
-Remove the setter for `termsLookup()`, making it only possible to either use a TermsLookup object or
-individual values at construction time. Also moving individual settings for the TermsLookup (lookupIndex,
-lookupType, lookupId, lookupPath) to the separate TermsLookup class, using constructor only and moving
-checks for validation there. Removed `TermsLookupQueryBuilder` in favour of `TermsQueryBuilder`.
-
-==== FunctionScoreQueryBuilder
-
-`add` methods have been removed, all filters and functions must be provided as constructor arguments by
-creating an array of `FunctionScoreQueryBuilder.FilterFunctionBuilder` objects, containing one element
-for each filter/function pair.
-
-`scoreMode` and `boostMode` can only be provided using corresponding enum members instead
-of string values: see `FilterFunctionScoreQuery.ScoreMode` and `CombineFunction`.
-
-`CombineFunction.MULT` has been renamed to `MULTIPLY`.
-
-==== IdsQueryBuilder
-
-For simplicity, only one way of adding the ids to the existing list (empty by default)  is left: `addIds(String...)`
-
-==== DocumentAlreadyExistsException removed
-
-`DocumentAlreadyExistsException` is removed and a `VersionConflictException` is thrown instead (with a better
-error description). This will influence code that use the `IndexRequest.opType()` or `IndexRequest.create()`
-to index a document only if it doesn't already exist.
-
-==== ShapeBuilders
-
-`InternalLineStringBuilder` is removed in favour of `LineStringBuilder`, `InternalPolygonBuilder` in favour of PolygonBuilder` and `Ring` has been replaced with `LineStringBuilder`. Also the abstract base classes `BaseLineStringBuilder` and `BasePolygonBuilder` haven been merged with their corresponding implementations.
-
-==== RescoreBuilder
-
-`RecoreBuilder.Rescorer` was merged with `RescoreBuilder`, which now is an abstract superclass. QueryRescoreBuilder currently is its only implementation.
-
-==== PhraseSuggestionBuilder
-
-The inner DirectCandidateGenerator class has been moved out to its own class called DirectCandidateGeneratorBuilder.
-
-==== Elasticsearch will no longer detect logging implementations
-
-Elasticsearch now logs only to log4j 1.2. Previously if log4j wasn't on the classpath it made some effort to degrade to
-slf4j or java.util.logging. Now it'll fail to work without the log4j 1.2 api. The log4j-over-slf4j bridge ought to work
-when using the java client. As should log4j 2's log4j-1.2-api. The Elasticsearch server now only supports log4j as
-configured by logging.yml and it no longer makes any effort to work if log4j isn't present.
-
-[[breaking_50_cache_concurrency]]
-=== Cache concurrency level settings removed
-
-Two cache concurrency level settings `indices.requests.cache.concurrency_level` and
-`indices.fielddata.cache.concurrency_level` because they no longer apply to the cache implementation used for the
-request cache and the field data cache.
-
-[[breaking_50_non_loopback]]
-=== Remove bind option of `non_loopback`
-
-This setting would arbitrarily pick the first interface not marked as loopback. Instead, specify by address
-scope (e.g. `_local_,_site_` for all loopback and private network addresses) or by explicit interface names,
-hostnames, or addresses.
-
-[[breaking_50_thread_pool]]
-=== Forbid changing of thread pool types
-
-Previously, <> could be dynamically adjusted. The thread pool type effectively
-controls the backing queue for the thread pool and modifying this is an expert setting with minimal practical benefits
-and high risk of being misused. The ability to change the thread pool type for any thread pool has been removed; do note
-that it is still possible to adjust relevant thread pool parameters for each of the thread pools (e.g., depending on
-the thread pool type, `keep_alive`, `queue_size`, etc.).
-
-[[breaking_50_cpu_stats]]
-=== System CPU stats
-
-The recent CPU usage (as a percent) has been added to the OS stats
-reported under the node stats API and the cat nodes API. The breaking
-change here is that there is a new object in the `os` object in the node
-stats response. This object is called `cpu` and includes "percent" and
-`load_average` as fields. This moves the `load_average` field that was
-previously a top-level field in the `os` object to the `cpu` object. The
-format of the `load_average` field has changed to an object with fields
-`1m`, `5m`, and `15m` representing the one-minute, five-minute and
-fifteen-minute loads respectively. If any of these fields are not present,
-it indicates that the corresponding value is not available.
-
-In the cat nodes API response, the `cpu` field is output by default. The
-previous `load` field has been removed and is replaced by `load_1m`,
-`load_5m`, and `load_15m` which represent the one-minute, five-minute
-and fifteen-minute loads respectively. The field will be null if the
-corresponding value is not available.
-
-Finally, the API for `org.elasticsearch.monitor.os.OsStats` has
-changed. The `getLoadAverage` method has been removed. The value for
-this can now be obtained from `OsStats.Cpu#getLoadAverage` but it is no
-longer a double and is instead an object encapsulating the one-minute,
-five-minute and fifteen-minute load averages. Additionally, the recent
-CPU usage can be obtained from `OsStats.Cpu#getPercent`.
-
-=== Fields option
-Only stored fields are retrievable with this option.
-The fields option won't be able to load non stored fields from _source anymore.
-
-[[breaking_50_allocation]]
-=== Primary shard allocation
-
-Previously, primary shards were only assigned if a quorum of shard copies were found (configurable using
-`index.recovery.initial_shards`, now deprecated). In case where a primary had only a single replica, quorum was defined
-to be a single shard. This meant that any shard copy of an index with replication factor 1 could become primary, even it
-was a stale copy of the data on disk. This is now fixed by using allocation IDs.
-
-Allocation IDs assign unique identifiers to shard copies. This allows the cluster to differentiate between multiple
-copies of the same data and track which shards have been active, so that after a cluster restart, shard copies
-containing only the most recent data can become primaries.
-
-=== Indices Shard Stores command
-
-By using allocation IDs instead of version numbers to identify shard copies for primary shard allocation, the former versioning scheme
-has become obsolete. This is reflected in the indices-shards-stores.html[Indices Shard Stores API]. A new field `allocation_id` replaces the
-former `version` field in the result of the Indices Shard Stores command. This field is available for all shard copies that have been either
-created with the current version of Elasticsearch or have been active in a cluster running a current version of Elasticsearch. For legacy
-shard copies that have not been active in a current version of Elasticsearch, a `legacy_version` field is available instead (equivalent to
-the former `version` field).
-
-=== Reroute commands
-
-The reroute command `allocate` has been split into two distinct commands `allocate_replica` and `allocate_empty_primary`.
-This was done as we introduced a new `allocate_stale_primary` command. The new `allocate_replica` command corresponds to the
-old `allocate` command  with `allow_primary` set to false. The new `allocate_empty_primary` command corresponds to the old
-`allocate` command with `allow_primary` set to true.
-
-==== `index.shared_filesystem.recover_on_any_node` changes
-
-The behavior of `index.shared_filesystem.recover_on_any_node = true` has been changed. Previously, in the case where no
-shard copies could be found, an arbitrary node was chosen by potentially ignoring allocation deciders. Now, we take
-balancing into account but don't assign the shard if the allocation deciders are not satisfied. The behavior has also changed
-in the case where shard copies can be found. Previously, a node not holding the shard copy was chosen if none of the nodes
-holding shard copies were satisfying the allocation deciders. Now, the shard will be assigned to a node having a shard copy,
-even if none of the nodes holding a shard copy satisfy the allocation deciders.
-
-[[breaking_50_percolator]]
-=== Percolator
-
-Adding percolator queries and modifications to existing percolator queries are no longer visible in immediately
-to the percolator. A refresh is required to run before the changes are visible to the percolator.
-
-The reason that this has changed is that on newly created indices the percolator automatically indexes the query terms
-and these query terms are used at percolate time to reduce the amount of queries the percolate API needs evaluate.
-This optimization didn't work in the percolate API mode where modifications to queries are immediately visible.
-
-The percolator by defaults sets the `size` option to `10` whereas before this was set to unlimited.
-
-The percolate api can no longer accept documents that have fields that don't exist in the mapping.
-
-When percolating an existing document then specifying a document in the source of the percolate request is not allowed
-any more.
-
-The percolate api no longer modifies the mappings. Before the percolate api could be used to dynamically introduce new
-fields to the mappings based on the fields in the document being percolated. This no longer works, because these
-unmapped fields are not persisted in the mapping.
-
-Percolator documents are no longer excluded from the search response.
-
-[[breaking_50_packaging]]
-=== Packaging
-
-==== Default logging using systemd (since Elasticsearch 2.2.0)
-
-In previous versions of Elasticsearch, the default logging
-configuration routed standard output to /dev/null and standard error to
-the journal. However, there are often critical error messages at
-startup that are logged to standard output rather than standard error
-and these error messages would be lost to the nether. The default has
-changed to now route standard output to the journal and standard error
-to inherit this setting (these are the defaults for systemd). These
-settings can be modified by editing the elasticsearch.service file.
-
-==== Longer startup times
-
-In Elasticsearch 5.0.0 the `-XX:+AlwaysPreTouch` flag has been added to the JVM
-startup options. This option touches all memory pages used by the JVM heap
-during initialization of the HotSpot VM to reduce the chance of having to commit
-a memory page during GC time. This will increase the startup time of
-Elasticsearch as well as increasing the initial resident memory usage of the
-Java process.
-
-[[breaking_50_scripting]]
-=== Scripting
-
-==== Script mode settings
-
-Previously script mode settings (e.g., "script.inline: true",
-"script.engine.groovy.inline.aggs: false", etc.) accepted the values
-`on`, `true`, `1`, and `yes` for enabling a scripting mode, and the
-values `off`, `false`, `0`, and `no` for disabling a scripting mode.
-The variants `on`, `1`, and `yes ` for enabling and `off`, `0`,
-and `no` for disabling are no longer supported.
-
-==== Groovy dependencies
-
-In previous versions of Elasticsearch, the Groovy scripting capabilities
-depended on the `org.codehaus.groovy:groovy-all` artifact.  In addition
-to pulling in the Groovy language, this pulls in a very large set of
-functionality, none of which is needed for scripting within
-Elasticsearch. Aside from the inherent difficulties in managing such a
-large set of dependencies, this also increases the surface area for
-security issues. This dependency has been reduced to the core Groovy
-language `org.codehaus.groovy:groovy` artifact.
-
-[[breaking_50_term_vectors]]
-=== Term vectors
-
-The term vectors APIs no longer persist unmapped fields in the mappings.
-
-The `dfs` parameter has been removed completely, term vectors don't support
-distributed document frequencies anymore.
-
-[[breaking_50_security]]
-=== Security
-
-The option to disable the security manager `--security.manager.enabled` has been removed. In order to grant special
-permissions to elasticsearch users must tweak the local Java Security Policy.
-
-[[breaking_50_snapshot_restore]]
-=== Snapshot/Restore
-
-==== Closing / deleting indices while running snapshot
-
-In previous versions of Elasticsearch, closing or deleting an index during a full snapshot would make the snapshot fail. This is now changed
-by failing the close/delete index request instead. The behavior for partial snapshots remains unchanged: Closing or deleting an index during
-a partial snapshot is still possible. The snapshot result is then marked as partial.
diff --git a/docs/reference/migration/migrate_5_0/allocation.asciidoc b/docs/reference/migration/migrate_5_0/allocation.asciidoc
new file mode 100644
index 00000000000..1e095831381
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/allocation.asciidoc
@@ -0,0 +1,54 @@
+[[breaking_50_allocation]]
+=== Allocation changes
+
+==== Primary shard allocation
+
+Previously, primary shards were only assigned if a quorum of shard copies were
+found (configurable using `index.recovery.initial_shards`, now deprecated). In
+case where a primary had only a single replica, quorum was defined to be a
+single shard. This meant that any shard copy of an index with replication
+factor 1 could become primary, even it was a stale copy of the data on disk.
+This is now fixed thanks to shard allocation IDs.
+
+Allocation IDs assign unique identifiers to shard copies. This allows the
+cluster to differentiate between multiple copies of the same data and track
+which shards have been active so that, after a cluster restart, only shard
+copies containing the most recent data can become primaries.
+
+==== Indices Shard Stores command
+
+By using allocation IDs instead of version numbers to identify shard copies
+for primary shard allocation, the former versioning scheme has become
+obsolete. This is reflected in the
+<>.
+
+A new `allocation_id` field replaces the former `version` field in the result
+of the Indices Shard Stores command. This field is available for all shard
+copies that have been either created with the current version of Elasticsearch
+or have been active in a cluster running a current version of Elasticsearch.
+For legacy shard copies that have not been active in a current version of
+Elasticsearch, a `legacy_version` field is available instead (equivalent to
+the former `version` field).
+
+==== Reroute commands
+
+The reroute command `allocate` has been split into two distinct commands
+`allocate_replica` and `allocate_empty_primary`. This was done as we
+introduced a new `allocate_stale_primary` command. The new `allocate_replica`
+command corresponds to the old `allocate` command  with `allow_primary` set to
+false. The new `allocate_empty_primary` command corresponds to the old
+`allocate` command with `allow_primary` set to true.
+
+==== `index.shared_filesystem.recover_on_any_node` changes
+
+The behavior of `index.shared_filesystem.recover_on_any_node: true` has been
+changed. Previously, in the case where no shard copies could be found, an
+arbitrary node was chosen by potentially ignoring allocation deciders. Now, we
+take balancing into account but don't assign the shard if the allocation
+deciders are not satisfied.
+
+The behavior has also changed in the case where shard copies can be found.
+Previously, a node not holding the shard copy was chosen if none of the nodes
+holding shard copies were satisfying the allocation deciders. Now, the shard
+will be assigned to a node having a shard copy, even if none of the nodes
+holding a shard copy satisfy the allocation deciders.
diff --git a/docs/reference/migration/migrate_5_0/cat.asciidoc b/docs/reference/migration/migrate_5_0/cat.asciidoc
new file mode 100644
index 00000000000..c3b1c84ee8d
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/cat.asciidoc
@@ -0,0 +1,33 @@
+[[breaking_50_cat_api]]
+=== CAT API changes
+
+==== Use Accept header for specifying response media type
+
+Previous versions of Elasticsearch accepted the Content-type header
+field for controlling the media type of the response in the cat API.
+This is in opposition to the HTTP spec which specifies the Accept
+header field for this purpose. Elasticsearch now uses the Accept header
+field and support for using the Content-Type header field for this
+purpose has been removed.
+
+==== Host field removed from the cat nodes API
+
+The `host` field has been removed from the cat nodes API as its value
+is always equal to the `ip` field. The `name` field is available in the
+cat nodes API and should be used instead of the `host` field.
+
+==== Changes to cat recovery API
+
+The fields `bytes_recovered` and `files_recovered` have been added to
+the cat recovery API. These fields, respectively, indicate the total
+number of bytes and files that have been recovered.
+
+The fields `total_files` and `total_bytes` have been renamed to
+`files_total` and `bytes_total`, respectively.
+
+Additionally, the field `translog` has been renamed to
+`translog_ops_recovered`, the field `translog_total` to
+`translog_ops` and the field `translog_percent` to
+`translog_ops_percent`. The short aliases for these fields are `tor`,
+`to`, and `top`, respectively.
+
diff --git a/docs/reference/migration/migrate_5_0/index-apis.asciidoc b/docs/reference/migration/migrate_5_0/index-apis.asciidoc
new file mode 100644
index 00000000000..72651295bbc
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/index-apis.asciidoc
@@ -0,0 +1,48 @@
+[[breaking_50_index_apis]]
+=== Index APIs changes
+
+==== Closing / deleting indices while running snapshot
+
+In previous versions of Elasticsearch, closing or deleting an index during a
+full snapshot would make the snapshot fail. In 5.0, the close/delete index
+request will fail instead. The behavior for partial snapshots remains
+unchanged: Closing or deleting an index during a partial snapshot is still
+possible. The snapshot result is then marked as partial.
+
+==== Warmers
+
+Thanks to several changes like doc values by default and disk-based norms,
+warmers are no longer useful. As a consequence, warmers and the warmer API
+have been removed: it is no longer possible to register queries that will run
+before a new IndexSearcher is published.
+
+Don't worry if you have warmers defined on your indices, they will simply be
+ignored when upgrading to 5.0.
+
+==== System CPU stats
+
+The recent CPU usage (as a percent) has been added to the OS stats
+reported under the node stats API and the cat nodes API. The breaking
+change here is that there is a new object in the `os` object in the node
+stats response. This object is called `cpu` and includes percent` and
+`load_average` as fields. This moves the `load_average` field that was
+previously a top-level field in the `os` object to the `cpu` object. The
+format of the `load_average` field has changed to an object with fields
+`1m`, `5m`, and `15m` representing the one-minute, five-minute and
+fifteen-minute loads respectively. If any of these fields are not present,
+it indicates that the corresponding value is not available.
+
+In the cat nodes API response, the `cpu` field is output by default. The
+previous `load` field has been removed and is replaced by `load_1m`,
+`load_5m`, and `load_15m` which represent the one-minute, five-minute
+and fifteen-minute loads respectively. The field will be null if the
+corresponding value is not available.
+
+Finally, the API for `org.elasticsearch.monitor.os.OsStats` has
+changed. The `getLoadAverage` method has been removed. The value for
+this can now be obtained from `OsStats.Cpu#getLoadAverage` but it is no
+longer a double and is instead an object encapsulating the one-minute,
+five-minute and fifteen-minute load averages. Additionally, the recent
+CPU usage can be obtained from `OsStats.Cpu#getPercent`.
+
+
diff --git a/docs/reference/migration/migrate_5_0/java.asciidoc b/docs/reference/migration/migrate_5_0/java.asciidoc
new file mode 100644
index 00000000000..d1b96eb9446
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/java.asciidoc
@@ -0,0 +1,213 @@
+
+
+
+[[breaking_50_java_api_changes]]
+=== Java API changes
+
+==== Count api has been removed
+
+The deprecated count api has been removed from the Java api, use the search api instead and set size to 0.
+
+The following call
+
+[source,java]
+-----
+client.prepareCount(indices).setQuery(query).get();
+-----
+
+can be replaced with
+
+[source,java]
+-----
+client.prepareSearch(indices).setSource(new SearchSourceBuilder().size(0).query(query)).get();
+-----
+
+==== Elasticsearch will no longer detect logging implementations
+
+Elasticsearch now logs only to log4j 1.2. Previously if log4j wasn't on the
+classpath it made some effort to degrade to slf4j or java.util.logging. Now it
+will fail to work without the log4j 1.2 api. The log4j-over-slf4j bridge ought
+to work when using the java client, as should log4j 2's log4j-1.2-api. The
+Elasticsearch server now only supports log4j as configured by `logging.yml`
+and will fail if log4j isn't present.
+
+==== Groovy dependencies
+
+In previous versions of Elasticsearch, the Groovy scripting capabilities
+depended on the `org.codehaus.groovy:groovy-all` artifact.  In addition
+to pulling in the Groovy language, this pulls in a very large set of
+functionality, none of which is needed for scripting within
+Elasticsearch. Aside from the inherent difficulties in managing such a
+large set of dependencies, this also increases the surface area for
+security issues. This dependency has been reduced to the core Groovy
+language `org.codehaus.groovy:groovy` artifact.
+
+==== DocumentAlreadyExistsException removed
+
+`DocumentAlreadyExistsException` is removed and a `VersionConflictException` is thrown instead (with a better
+error description). This will influence code that use the `IndexRequest.opType()` or `IndexRequest.create()`
+to index a document only if it doesn't already exist.
+
+==== Changes to Query Builders
+
+===== BoostingQueryBuilder
+
+Removed setters for mandatory positive/negative query. Both arguments now have
+to be supplied at construction time already and have to be non-null.
+
+===== SpanContainingQueryBuilder
+
+Removed setters for mandatory big/little inner span queries. Both arguments now have
+to be supplied at construction time already and have to be non-null. Updated
+static factory methods in QueryBuilders accordingly.
+
+===== SpanOrQueryBuilder
+
+Making sure that query contains at least one clause by making initial clause mandatory
+in constructor.
+
+===== SpanNearQueryBuilder
+
+Removed setter for mandatory slop parameter, needs to be set in constructor now. Also
+making sure that query contains at least one clause by making initial clause mandatory
+in constructor. Updated the static factory methods in QueryBuilders accordingly.
+
+===== SpanNotQueryBuilder
+
+Removed setter for mandatory include/exclude span query clause, needs to be set in constructor now.
+Updated the static factory methods in QueryBuilders and tests accordingly.
+
+===== SpanWithinQueryBuilder
+
+Removed setters for mandatory big/little inner span queries. Both arguments now have
+to be supplied at construction time already and have to be non-null. Updated
+static factory methods in QueryBuilders accordingly.
+
+===== QueryFilterBuilder
+
+Removed the setter `queryName(String queryName)` since this field is not supported
+in this type of query. Use `FQueryFilterBuilder.queryName(String queryName)` instead
+when in need to wrap a named query as a filter.
+
+===== WrapperQueryBuilder
+
+Removed `wrapperQueryBuilder(byte[] source, int offset, int length)`. Instead simply
+use  `wrapperQueryBuilder(byte[] source)`. Updated the static factory methods in
+QueryBuilders accordingly.
+
+===== QueryStringQueryBuilder
+
+Removed ability to pass in boost value using `field(String field)` method in form e.g. `field^2`.
+Use the `field(String, float)` method instead.
+
+===== Operator
+
+Removed the enums called `Operator` from `MatchQueryBuilder`, `QueryStringQueryBuilder`,
+`SimpleQueryStringBuilder`, and `CommonTermsQueryBuilder` in favour of using the enum
+defined in `org.elasticsearch.index.query.Operator` in an effort to consolidate the
+codebase and avoid duplication.
+
+===== queryName and boost support
+
+Support for `queryName` and `boost` has been streamlined to all of the queries. That is
+a breaking change till queries get sent over the network as serialized json rather
+than in `Streamable` format. In fact whenever additional fields are added to the json
+representation of the query, older nodes might throw error when they find unknown fields.
+
+===== InnerHitsBuilder
+
+InnerHitsBuilder now has a dedicated addParentChildInnerHits and addNestedInnerHits methods
+to differentiate between inner hits for nested vs. parent / child documents. This change
+makes the type / path parameter mandatory.
+
+===== MatchQueryBuilder
+
+Moving MatchQueryBuilder.Type and MatchQueryBuilder.ZeroTermsQuery enum to MatchQuery.Type.
+Also reusing new Operator enum.
+
+===== MoreLikeThisQueryBuilder
+
+Removed `MoreLikeThisQueryBuilder.Item#id(String id)`, `Item#doc(BytesReference doc)`,
+`Item#doc(XContentBuilder doc)`. Use provided constructors instead.
+
+Removed `MoreLikeThisQueryBuilder#addLike` in favor of texts and/or items being provided
+at construction time. Using arrays there instead of lists now.
+
+Removed `MoreLikeThisQueryBuilder#addUnlike` in favor to using the `unlike` methods
+which take arrays as arguments now rather than the lists used before.
+
+The deprecated `docs(Item... docs)`, `ignoreLike(Item... docs)`,
+`ignoreLike(String... likeText)`, `addItem(Item... likeItems)` have been removed.
+
+===== GeoDistanceQueryBuilder
+
+Removing individual setters for lon() and lat() values, both values should be set together
+ using point(lon, lat).
+
+===== GeoDistanceRangeQueryBuilder
+
+Removing setters for to(Object ...) and from(Object ...) in favour of the only two allowed input
+arguments (String, Number). Removing setter for center point (point(), geohash()) because parameter
+is mandatory and should already be set in constructor.
+Also removing setters for lt(), lte(), gt(), gte() since they can all be replaced by equivalent
+calls to to/from() and inludeLower()/includeUpper().
+
+===== GeoPolygonQueryBuilder
+
+Require shell of polygon already to be specified in constructor instead of adding it pointwise.
+This enables validation, but makes it necessary to remove the addPoint() methods.
+
+===== MultiMatchQueryBuilder
+
+Moving MultiMatchQueryBuilder.ZeroTermsQuery enum to MatchQuery.ZeroTermsQuery.
+Also reusing new Operator enum.
+
+Removed ability to pass in boost value using `field(String field)` method in form e.g. `field^2`.
+Use the `field(String, float)` method instead.
+
+===== MissingQueryBuilder
+
+The MissingQueryBuilder which was deprecated in 2.2.0 is removed. As a replacement use ExistsQueryBuilder
+inside a mustNot() clause. So instead of using `new ExistsQueryBuilder(name)` now use
+`new BoolQueryBuilder().mustNot(new ExistsQueryBuilder(name))`.
+
+===== NotQueryBuilder
+
+The NotQueryBuilder which was deprecated in 2.1.0 is removed. As a replacement use BoolQueryBuilder
+with added mustNot() clause. So instead of using `new NotQueryBuilder(filter)` now use
+`new BoolQueryBuilder().mustNot(filter)`.
+
+===== TermsQueryBuilder
+
+Remove the setter for `termsLookup()`, making it only possible to either use a TermsLookup object or
+individual values at construction time. Also moving individual settings for the TermsLookup (lookupIndex,
+lookupType, lookupId, lookupPath) to the separate TermsLookup class, using constructor only and moving
+checks for validation there. Removed `TermsLookupQueryBuilder` in favour of `TermsQueryBuilder`.
+
+===== FunctionScoreQueryBuilder
+
+`add` methods have been removed, all filters and functions must be provided as constructor arguments by
+creating an array of `FunctionScoreQueryBuilder.FilterFunctionBuilder` objects, containing one element
+for each filter/function pair.
+
+`scoreMode` and `boostMode` can only be provided using corresponding enum members instead
+of string values: see `FilterFunctionScoreQuery.ScoreMode` and `CombineFunction`.
+
+`CombineFunction.MULT` has been renamed to `MULTIPLY`.
+
+===== IdsQueryBuilder
+
+For simplicity, only one way of adding the ids to the existing list (empty by default)  is left: `addIds(String...)`
+
+===== ShapeBuilders
+
+`InternalLineStringBuilder` is removed in favour of `LineStringBuilder`, `InternalPolygonBuilder` in favour of PolygonBuilder` and `Ring` has been replaced with `LineStringBuilder`. Also the abstract base classes `BaseLineStringBuilder` and `BasePolygonBuilder` haven been merged with their corresponding implementations.
+
+===== RescoreBuilder
+
+`RecoreBuilder.Rescorer` was merged with `RescoreBuilder`, which now is an abstract superclass. QueryRescoreBuilder currently is its only implementation.
+
+===== PhraseSuggestionBuilder
+
+The inner DirectCandidateGenerator class has been moved out to its own class called DirectCandidateGeneratorBuilder.
+
diff --git a/docs/reference/migration/migrate_5_0/mapping.asciidoc b/docs/reference/migration/migrate_5_0/mapping.asciidoc
new file mode 100644
index 00000000000..768a2438d3e
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/mapping.asciidoc
@@ -0,0 +1,82 @@
+[[breaking_50_mapping_changes]]
+=== Mapping changes
+
+==== `string` fields replaced by `text`/`keyword` fields
+
+The `string` field datatype has been replaced by the `text` field for full
+text analyzed content, and the `keyword` field for not-analyzed exact string
+values.  For backwards compatibility purposes, during the 5.x series:
+
+* `string` fields on pre-5.0 indices will function as before.
+* New `string` fields can be added to pre-5.0 indices as before.
+* `text` and `keyword` fields can also be added to pre-5.0 indices.
+* When adding a `string` field to a new index, the field mapping will be
+  rewritten as a `text` or `keyword` field if possible, otherwise
+  an exception will be thrown.  Certain configurations that were possible
+  with `string` fields are no longer possible with `text`/`keyword` fields
+  such as enabling `term_vectors` on a not-analyzed `keyword` field.
+
+==== `index` property
+
+On all field datatypes (except for the deprecated `string` field), the `index`
+property now only accepts `true`/`false` instead of `not_analyzed`/`no`. The
+`string` field still accepts `analyzed`/`not_analyzed`/`no`.
+
+==== Doc values on unindexed fields
+
+Previously, setting a field to `index:no` would also disable doc-values.  Now,
+doc-values are always enabled on numeric and boolean fields unless
+`doc_values` is set to `false`.
+
+==== Floating points use `float` instead of `double`
+
+When dynamically mapping a field containing a floating point number, the field
+now defaults to using `float` instead of `double`. The reasoning is that
+floats should be more than enough for most cases but would decrease storage
+requirements significantly.
+
+==== `fielddata.format`
+
+Setting `fielddata.format: doc_values` in the mappings used to implicitly
+enable doc-values on a field. This no longer works: the only way to enable or
+disable doc-values is by using the `doc_values` property of mappings.
+
+==== Source-transform removed
+
+The source `transform` feature has been removed. Instead, use an ingest pipeline
+
+==== `_parent` field no longer indexed
+
+The join between parent and child documents no longer relies on indexed fields
+and therefore from 5.0.0 onwards the `_parent` field is no longer indexed. In
+order to find documents that referrer to a specific parent id the new
+`parent_id` query can be used. The GET response and hits inside the search
+response still include the parent id under the `_parent` key.
+
+==== Source `format` option
+
+The `_source` mapping no longer supports the `format` option. It will still be
+accepted for indices created before the upgrade to 5.0 for backwards
+compatibility, but it will have no effect. Indices created on or after 5.0
+will reject this option.
+
+==== Object notation
+
+Core types no longer support the object notation, which was used to provide
+per document boosts as follows:
+
+[source,json]
+---------------
+{
+  "value": "field_value",
+  "boost": 42
+}
+---------------
+
+==== Boost accuracy for queries on `_all`
+
+Per-field boosts on the `_all` are now compressed into a single byte instead
+of the 4 bytes used previously. While this will make the index much more
+space-efficient, it also means that index time boosts will be less accurately
+encoded.
+
diff --git a/docs/reference/migration/migrate_5_0/packaging.asciidoc b/docs/reference/migration/migrate_5_0/packaging.asciidoc
new file mode 100644
index 00000000000..9be2d4accac
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/packaging.asciidoc
@@ -0,0 +1,24 @@
+[[breaking_50_packaging]]
+=== Packaging
+
+==== Default logging using systemd (since Elasticsearch 2.2.0)
+
+In previous versions of Elasticsearch, the default logging
+configuration routed standard output to /dev/null and standard error to
+the journal. However, there are often critical error messages at
+startup that are logged to standard output rather than standard error
+and these error messages would be lost to the nether. The default has
+changed to now route standard output to the journal and standard error
+to inherit this setting (these are the defaults for systemd). These
+settings can be modified by editing the elasticsearch.service file.
+
+==== Longer startup times
+
+In Elasticsearch 5.0.0 the `-XX:+AlwaysPreTouch` flag has been added to the JVM
+startup options. This option touches all memory pages used by the JVM heap
+during initialization of the HotSpot VM to reduce the chance of having to commit
+a memory page during GC time. This will increase the startup time of
+Elasticsearch as well as increasing the initial resident memory usage of the
+Java process.
+
+
diff --git a/docs/reference/migration/migrate_5_0/percolator.asciidoc b/docs/reference/migration/migrate_5_0/percolator.asciidoc
new file mode 100644
index 00000000000..3c560182c87
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/percolator.asciidoc
@@ -0,0 +1,41 @@
+[[breaking_50_percolator]]
+=== Percolator changes
+
+==== Percolator is near-real time
+
+Previously percolators were activated in real-time, i.e. as soon as they were
+indexed.  Now, changes to the percolator query are visible in near-real time,
+as soon as the index has been refreshed. This change was required because, in
+indices created from 5.0 onwards, the terms used in a percolator query are
+automatically indexed to allow for more efficient query selection during
+percolation.
+
+==== Percolator mapping
+
+The percolate API can no longer accept documents that reference fields that
+don't already exist in the mapping.
+
+The percolate API no longer modifies the mappings. Before the percolate API
+could be used to dynamically introduce new fields to the mappings based on the
+fields in the document being percolated. This no longer works, because these
+unmapped fields are not persisted in the mapping.
+
+==== Percolator documents returned by search
+
+Documents with the `.percolate` type were previously excluded from the search
+response, unless the `.percolate` type was specified explicitly in the search
+request.  Now, percolator documents are treated in the same way as any other
+document and are returned by search requests.
+
+==== Percolator `size` default
+
+The percolator by default sets the `size` option to `10` whereas before this
+was unlimited.
+
+==== Percolate API
+
+When percolating an existing document then specifying a document in the source
+of the percolate request is not allowed any more.
+
+
+
diff --git a/docs/reference/migration/migrate_5_0/plugins.asciidoc b/docs/reference/migration/migrate_5_0/plugins.asciidoc
new file mode 100644
index 00000000000..10268887417
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/plugins.asciidoc
@@ -0,0 +1,99 @@
+[[breaking_50_plugins]]
+=== Plugin changes
+
+The command `bin/plugin` has been renamed to `bin/elasticsearch-plugin`. The
+structure of the plugin ZIP archive has changed. All the plugin files must be
+contained in a top-level directory called `elasticsearch`. If you use the
+gradle build, this structure is automatically generated.
+
+==== Site plugins removed
+
+Site plugins have been removed. Site plugins should be reimplemented as Kibana
+plugins.
+
+==== Multicast plugin removed
+
+Multicast has been removed. Use unicast discovery, or one of the cloud
+discovery plugins.
+
+==== Plugins with custom query implementations
+
+Plugins implementing custom queries need to implement the `fromXContent(QueryParseContext)` method in their
+`QueryParser` subclass rather than `parse`. This method will take care of parsing the query from `XContent` format
+into an intermediate query representation that can be streamed between the nodes in binary format, effectively the
+query object used in the java api. Also, the query parser needs to implement the `getBuilderPrototype` method that
+returns a prototype of the `NamedWriteable` query, which allows to deserialize an incoming query by calling
+`readFrom(StreamInput)` against it, which will create a new object, see usages of `Writeable`. The `QueryParser`
+also needs to declare the generic type of the query that it supports and it's able to parse.
+The query object can then transform itself into a lucene query through the new `toQuery(QueryShardContext)` method,
+which returns a lucene query to be executed on the data node.
+
+Similarly, plugins implementing custom score functions need to implement the `fromXContent(QueryParseContext)`
+method in their `ScoreFunctionParser` subclass rather than `parse`. This method will take care of parsing
+the function from `XContent` format into an intermediate function representation that can be streamed between
+the nodes in binary format, effectively the function object used in the java api. Also, the query parser needs
+to implement the `getBuilderPrototype` method that returns a prototype of the `NamedWriteable` function, which
+allows to deserialize an incoming function by calling `readFrom(StreamInput)` against it, which will create a
+new object, see usages of `Writeable`. The `ScoreFunctionParser` also needs to declare the generic type of the
+function that it supports and it's able to parse. The function object can then transform itself into a lucene
+function through the new `toFunction(QueryShardContext)` method, which returns a lucene function to be executed
+on the data node.
+
+==== Cloud AWS plugin changes
+
+Cloud AWS plugin has been split in two plugins:
+
+* {plugins}/discovery-ec2.html[Discovery EC2 plugin]
+* {plugins}/repository-s3.html[Repository S3 plugin]
+
+Proxy settings for both plugins have been renamed:
+
+* from `cloud.aws.proxy_host` to `cloud.aws.proxy.host`
+* from `cloud.aws.ec2.proxy_host` to `cloud.aws.ec2.proxy.host`
+* from `cloud.aws.s3.proxy_host` to `cloud.aws.s3.proxy.host`
+* from `cloud.aws.proxy_port` to `cloud.aws.proxy.port`
+* from `cloud.aws.ec2.proxy_port` to `cloud.aws.ec2.proxy.port`
+* from `cloud.aws.s3.proxy_port` to `cloud.aws.s3.proxy.port`
+
+==== Cloud Azure plugin changes
+
+Cloud Azure plugin has been split in three plugins:
+
+* {plugins}/discovery-azure.html[Discovery Azure plugin]
+* {plugins}/repository-azure.html[Repository Azure plugin]
+* {plugins}/store-smb.html[Store SMB plugin]
+
+If you were using the `cloud-azure` plugin for snapshot and restore, you had in `elasticsearch.yml`:
+
+[source,yaml]
+-----
+cloud:
+    azure:
+        storage:
+            account: your_azure_storage_account
+            key: your_azure_storage_key
+-----
+
+You need to give a unique id to the storage details now as you can define multiple storage accounts:
+
+[source,yaml]
+-----
+cloud:
+    azure:
+        storage:
+            my_account:
+                account: your_azure_storage_account
+                key: your_azure_storage_key
+-----
+
+
+==== Cloud GCE plugin changes
+
+Cloud GCE plugin has been renamed to {plugins}/discovery-gce.html[Discovery GCE plugin].
+
+
+==== Mapper Attachments plugin deprecated
+
+Mapper attachments has been deprecated. Users should use now the {plugins}/ingest-attachment.html[`ingest-attachment`]
+plugin.
+
diff --git a/docs/reference/migration/migrate_5_0/rest.asciidoc b/docs/reference/migration/migrate_5_0/rest.asciidoc
new file mode 100644
index 00000000000..590a097f021
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/rest.asciidoc
@@ -0,0 +1,17 @@
+
+[[breaking_50_rest_api_changes]]
+=== REST API changes
+
+==== id values longer than 512 bytes are rejected
+
+When specifying an `_id` value longer than 512 bytes, the request will be
+rejected.
+
+==== `/_optimize` endpoint removed
+
+The deprecated `/_optimize` endpoint has been removed. The `/_forcemerge`
+endpoint should be used in lieu of optimize.
+
+The `GET` HTTP verb for `/_forcemerge` is no longer supported, please use the
+`POST` HTTP verb.
+
diff --git a/docs/reference/migration/migrate_5_0/search.asciidoc b/docs/reference/migration/migrate_5_0/search.asciidoc
new file mode 100644
index 00000000000..48807bf187a
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/search.asciidoc
@@ -0,0 +1,141 @@
+[[breaking_50_search_changes]]
+=== Search and Query DSL changes
+
+==== `search_type`
+
+===== `search_type=count` removed
+
+The `count` search type was deprecated since version 2.0.0 and is now removed.
+In order to get the same benefits, you just need to set the value of the `size`
+parameter to `0`.
+
+For instance, the following request:
+
+[source,sh]
+---------------
+GET /my_index/_search?search_type=count
+{
+  "aggs": {
+    "my_terms": {
+       "terms": {
+         "field": "foo"
+       }
+     }
+  }
+}
+---------------
+
+can be replaced with:
+
+[source,sh]
+---------------
+GET /my_index/_search
+{
+  "size": 0,
+  "aggs": {
+    "my_terms": {
+       "terms": {
+         "field": "foo"
+       }
+     }
+  }
+}
+---------------
+
+===== `search_type=scan` removed
+
+The `scan` search type was deprecated since version 2.1.0 and is now removed.
+All benefits from this search type can now be achieved by doing a scroll
+request that sorts documents in `_doc` order, for instance:
+
+[source,sh]
+---------------
+GET /my_index/_search?scroll=2m
+{
+  "sort": [
+    "_doc"
+  ]
+}
+---------------
+
+Scroll requests sorted by `_doc` have been optimized to more efficiently resume
+from where the previous request stopped, so this will have the same performance
+characteristics as the former `scan` search type.
+
+==== `fields` parameter
+
+The `fields` parameter used to try to retrieve field values from stored
+fields, and fall back to extracting from the `_source` if a field is not
+marked as stored.  Now, the `fields` parameter will only return stored fields
+-- it will no longer extract values from the `_source`.
+
+==== search-exists API removed
+
+The search exists api has been removed in favour of using the search api with
+`size` set to `0` and `terminate_after` set to `1`.
+
+
+==== Deprecated queries removed
+
+The following deprecated queries have been removed:
+
+`filtered`::      Use `bool` query instead, which supports `filter` clauses too.
+`and`::           Use `must` clauses in a `bool` query instead.
+`or`::            Use `should` clauses in a `bool` query instead.
+`limit`::         Use the `terminate_after` parameter instead.
+`fquery`::        Is obsolete after filters and queries have been merged.
+`query`::         Is obsolete after filters and queries have been merged.
+`query_binary`::  Was undocumented and has been removed.
+`filter_binary`:: Was undocumented and has been removed.
+
+
+==== Changes to queries
+
+* Removed support for the deprecated `min_similarity` parameter in `fuzzy
+  query`, in favour of `fuzziness`.
+
+* Removed support for the deprecated `fuzzy_min_sim` parameter in
+  `query_string` query, in favour of `fuzziness`.
+
+* Removed support for the deprecated `edit_distance` parameter in completion
+  suggester, in favour of `fuzziness`.
+
+* Removed support for the deprecated `filter` and `no_match_filter` fields in `indices` query,
+in favour of `query` and `no_match_query`.
+
+* Removed support for the deprecated `filter` fields in `nested` query, in favour of `query`.
+
+* Removed support for the deprecated `minimum_should_match` and
+  `disable_coord` in `terms` query, use `bool` query instead. Also removed
+  support for the deprecated `execution` parameter.
+
+* Removed support for the top level `filter` element in `function_score` query, replaced by `query`.
+
+* The `collect_payloads` parameter of the `span_near` query has been deprecated.  Payloads will be loaded when needed.
+
+* The `score_type` parameter to the `has_child` and `has_parent` queries has been removed in favour of `score_mode`.
+  Also, the `sum` score mode has been removed in favour of the `total` mode.
+
+*  When the `max_children` parameter was set to `0` on the `has_child` query
+   then there was no upper limit on how many child documents were allowed to
+   match. Now, `0` really means that zero child documents are allowed. If no
+   upper limit is needed then the `max_children` parameter shouldn't be specified
+   at all.
+
+
+==== Top level `filter` parameter
+
+Removed support for the deprecated top level `filter` in the search api,
+replaced by `post_filter`.
+
+==== Highlighters
+
+Removed support for multiple highlighter names, the only supported ones are:
+`plain`, `fvh` and `postings`.
+
+==== Term vectors API
+
+The term vectors APIs no longer persist unmapped fields in the mappings.
+
+The `dfs` parameter to the term vectors API has been removed completely. Term
+vectors don't support distributed document frequencies anymore.
diff --git a/docs/reference/migration/migrate_5_0/settings.asciidoc b/docs/reference/migration/migrate_5_0/settings.asciidoc
new file mode 100644
index 00000000000..002d6cf05df
--- /dev/null
+++ b/docs/reference/migration/migrate_5_0/settings.asciidoc
@@ -0,0 +1,174 @@
+[[breaking_50_settings_changes]]
+=== Settings changes
+
+From Elasticsearch 5.0 on all settings are validated before they are applied.
+Node level and default index level settings are validated on node startup,
+dynamic cluster and index setting are validated before they are updated/added
+to the cluster state.
+
+Every setting must be a *known* setting. All settings must have been
+registered with the node or transport client they are used with. This implies
+that plugins that define custom settings must register all of their settings
+during plugin loading using the `SettingsModule#registerSettings(Setting)`
+method.
+
+==== Node settings
+
+The `name` setting has been removed and is replaced by `node.name`. Usage of
+`-Dname=some_node_name` is not supported anymore.
+
+==== Transport Settings
+
+All settings with a `netty` infix have been replaced by their already existing
+`transport` synonyms. For instance `transport.netty.bind_host` is no longer
+supported and should be replaced by the superseding setting
+`transport.bind_host`.
+
+==== Script mode settings
+
+Previously script mode settings (e.g., "script.inline: true",
+"script.engine.groovy.inline.aggs: false", etc.) accepted the values
+`on`, `true`, `1`, and `yes` for enabling a scripting mode, and the
+values `off`, `false`, `0`, and `no` for disabling a scripting mode.
+The variants `on`, `1`, and `yes ` for enabling and `off`, `0`,
+and `no` for disabling are no longer supported.
+
+
+==== Security manager settings
+
+The option to disable the security manager `security.manager.enabled` has been
+removed. In order to grant special permissions to elasticsearch users must
+edit the local Java Security Policy.
+
+==== Network settings
+
+The `_non_loopback_` value for settings like `network.host` would arbitrarily
+pick the first interface not marked as loopback. Instead, specify by address
+scope (e.g. `_local_,_site_` for all loopback and private network addresses)
+or by explicit interface names, hostnames, or addresses.
+
+==== Forbid changing of thread pool types
+
+Previously, <> could be dynamically
+adjusted. The thread pool type effectively controls the backing queue for the
+thread pool and modifying this is an expert setting with minimal practical
+benefits and high risk of being misused. The ability to change the thread pool
+type for any thread pool has been removed. It is still possible to adjust
+relevant thread pool parameters for each of the thread pools (e.g., depending
+on the thread pool type, `keep_alive`, `queue_size`, etc.).
+
+
+==== Analysis settings
+
+The `index.analysis.analyzer.default_index` analyzer is not supported anymore.
+If you wish to change the analyzer to use for indexing, change the
+`index.analysis.analyzer.default` analyzer instead.
+
+==== Ping timeout settings
+
+Previously, there were three settings for the ping timeout:
+`discovery.zen.initial_ping_timeout`, `discovery.zen.ping.timeout` and
+`discovery.zen.ping_timeout`. The former two have been removed and the only
+setting key for the ping timeout is now `discovery.zen.ping_timeout`. The
+default value for ping timeouts remains at three seconds.
+
+==== Recovery settings
+
+Recovery settings deprecated in 1.x have been removed:
+
+ * `index.shard.recovery.translog_size` is superseded by `indices.recovery.translog_size`
+ * `index.shard.recovery.translog_ops` is superseded by `indices.recovery.translog_ops`
+ * `index.shard.recovery.file_chunk_size` is superseded by `indices.recovery.file_chunk_size`
+ * `index.shard.recovery.concurrent_streams` is superseded by `indices.recovery.concurrent_streams`
+ * `index.shard.recovery.concurrent_small_file_streams` is superseded by `indices.recovery.concurrent_small_file_streams`
+ * `indices.recovery.max_size_per_sec` is superseded by `indices.recovery.max_bytes_per_sec`
+
+If you are using any of these settings please take the time to review their
+purpose. All of the settings above are considered _expert settings_ and should
+only be used if absolutely necessary. If you have set any of the above setting
+as persistent cluster settings please use the settings update API and set
+their superseded keys accordingly.
+
+The following settings have been removed without replacement
+
+ * `indices.recovery.concurrent_small_file_streams` - recoveries are now single threaded. The number of concurrent outgoing recoveries are throttled via allocation deciders
+ * `indices.recovery.concurrent_file_streams` - recoveries are now single threaded. The number of concurrent outgoing recoveries are throttled via allocation deciders
+
+==== Translog settings
+
+The `index.translog.flush_threshold_ops` setting is not supported anymore. In
+order to control flushes based on the transaction log growth use
+`index.translog.flush_threshold_size` instead.
+
+Changing the translog type with `index.translog.fs.type` is not supported
+anymore, the `buffered` implementation is now the only available option and
+uses a fixed `8kb` buffer.
+
+The translog by default is fsynced after every `index`, `create`, `update`,
+`delete`, or `bulk` request.  The ability to fsync on every operation is not
+necessary anymore. In fact, it can be a performance bottleneck and it's trappy
+since it enabled by a special value set on `index.translog.sync_interval`.
+Now, `index.translog.sync_interval`  doesn't accept a value less than `100ms`
+which prevents fsyncing too often if async durability is enabled. The special
+value `0` is no longer supported.
+
+==== Request Cache Settings
+
+The deprecated settings `index.cache.query.enable` and
+`indices.cache.query.size` have been removed and are replaced with
+`index.requests.cache.enable` and `indices.requests.cache.size` respectively.
+
+`indices.requests.cache.clean_interval has been replaced with
+`indices.cache.clean_interval and is no longer supported.
+
+==== Field Data Cache Settings
+
+The `indices.fielddata.cache.clean_interval` setting has been replaced with
+`indices.cache.clean_interval`.
+
+==== Allocation settings
+
+The `cluster.routing.allocation.concurrent_recoveries` setting has been
+replaced with `cluster.routing.allocation.node_concurrent_recoveries`.
+
+==== Similarity settings
+
+The 'default' similarity has been renamed to 'classic'.
+
+==== Indexing settings
+
+The `indices.memory.min_shard_index_buffer_size` and
+`indices.memory.max_shard_index_buffer_size` have been removed as
+Elasticsearch now allows any one shard to use  amount of heap as long as the
+total indexing buffer heap used across all shards is below the node's
+`indices.memory.index_buffer_size` (defaults to 10% of the JVM heap).
+
+==== Removed es.max-open-files
+
+Setting the system property es.max-open-files to true to get
+Elasticsearch to print the number of maximum open files for the
+Elasticsearch process has been removed. This same information can be
+obtained from the <> API, and a warning is logged
+on startup if it is set too low.
+
+==== Removed es.netty.gathering
+
+Disabling Netty from using NIO gathering could be done via the escape
+hatch of setting the system property "es.netty.gathering" to "false".
+Time has proven enabling gathering by default is a non-issue and this
+non-documented setting has been removed.
+
+==== Removed es.useLinkedTransferQueue
+
+The system property `es.useLinkedTransferQueue` could be used to
+control the queue implementation used in the cluster service and the
+handling of ping responses during discovery. This was an undocumented
+setting and has been removed.
+
+==== Cache concurrency level settings removed
+
+Two cache concurrency level settings
+`indices.requests.cache.concurrency_level` and
+`indices.fielddata.cache.concurrency_level` because they no longer apply to
+the cache implementation used for the request cache and the field data cache.
+

From 5f48b9c86a988ac37b7170e6075d0b4d6ee18a84 Mon Sep 17 00:00:00 2001
From: Clinton Gormley 
Date: Sun, 13 Mar 2016 21:18:44 +0100
Subject: [PATCH 41/49] Removed breaking changes docs for < 5.0

---
 docs/reference/migration/migrate_1_0.asciidoc | 372 ---------------
 docs/reference/migration/migrate_1_4.asciidoc |  92 ----
 docs/reference/migration/migrate_1_6.asciidoc |  17 -
 docs/reference/migration/migrate_2_0.asciidoc |  73 ---
 .../migration/migrate_2_0/aggs.asciidoc       |  70 ---
 .../migration/migrate_2_0/crud.asciidoc       | 130 ------
 .../migration/migrate_2_0/index_apis.asciidoc |  43 --
 .../migration/migrate_2_0/java.asciidoc       | 147 ------
 .../migration/migrate_2_0/mapping.asciidoc    | 439 ------------------
 .../migration/migrate_2_0/network.asciidoc    |  39 --
 .../migration/migrate_2_0/packaging.asciidoc  |  84 ----
 .../migrate_2_0/parent_child.asciidoc         |  43 --
 .../migration/migrate_2_0/query_dsl.asciidoc  | 189 --------
 .../migration/migrate_2_0/removals.asciidoc   | 100 ----
 .../migration/migrate_2_0/scripting.asciidoc  | 103 ----
 .../migration/migrate_2_0/search.asciidoc     | 122 -----
 .../migration/migrate_2_0/settings.asciidoc   | 204 --------
 .../migrate_2_0/snapshot_restore.asciidoc     |  38 --
 .../migration/migrate_2_0/stats.asciidoc      |  52 ---
 .../migration/migrate_2_0/striping.asciidoc   |  21 -
 docs/reference/migration/migrate_2_1.asciidoc |  87 ----
 docs/reference/migration/migrate_2_2.asciidoc |  80 ----
 docs/reference/migration/migrate_2_3.asciidoc |  19 -
 23 files changed, 2564 deletions(-)
 delete mode 100644 docs/reference/migration/migrate_1_0.asciidoc
 delete mode 100644 docs/reference/migration/migrate_1_4.asciidoc
 delete mode 100644 docs/reference/migration/migrate_1_6.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/aggs.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/crud.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/index_apis.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/java.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/mapping.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/network.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/packaging.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/parent_child.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/query_dsl.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/removals.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/scripting.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/search.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/settings.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/snapshot_restore.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/stats.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_0/striping.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_1.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_2.asciidoc
 delete mode 100644 docs/reference/migration/migrate_2_3.asciidoc

diff --git a/docs/reference/migration/migrate_1_0.asciidoc b/docs/reference/migration/migrate_1_0.asciidoc
deleted file mode 100644
index 1e917c4a0d9..00000000000
--- a/docs/reference/migration/migrate_1_0.asciidoc
+++ /dev/null
@@ -1,372 +0,0 @@
-[[breaking-changes-1.0]]
-== Breaking changes in 1.0
-
-This section discusses the changes that you need to be aware of when migrating
-your application to Elasticsearch 1.0.
-
-=== System and settings
-
-* Elasticsearch now runs in the foreground by default.  There is no more `-f`
-  flag on the command line.  Instead, to run elasticsearch as a daemon, use
-  the `-d` flag:
-
-[source,sh]
----------------
-./bin/elasticsearch -d
----------------
-
-* Command line settings can now be passed without the `-Des.` prefix, for
-  instance:
-
-[source,sh]
----------------
-./bin/elasticsearch --node.name=search_1 --cluster.name=production
----------------
-
-* Elasticsearch on 64 bit Linux now uses <> by default.  Make
-  sure that you set <> to a sufficiently high
-  number.  The RPM and Debian packages default this value to `262144`.
-
-* The RPM and Debian packages no longer start Elasticsearch by default.
-
-* The `cluster.routing.allocation` settings (`disable_allocation`,
-  `disable_new_allocation` and `disable_replica_location`) have been
-  <>:
-+
-[source,yaml]
----------------
-cluster.routing.allocation.enable: all|primaries|new_primaries|none
----------------
-
-=== Stats and Info APIs
-
-The <>, <>,
-<> and <>
-APIs have all been changed to make their format more RESTful and less clumsy.
-
-For instance, if you just want the `nodes` section of the `cluster_state`,
-instead of:
-
-[source,sh]
----------------
-GET /_cluster/state?filter_metadata&filter_routing_table&filter_blocks
----------------
-
-you now use:
-
-[source,sh]
----------------
-GET /_cluster/state/nodes
----------------
-
-Similarly for the `nodes_stats` API, if you want the `transport` and `http`
-metrics only, instead of:
-
-[source,sh]
----------------
-GET /_nodes/stats?clear&transport&http
----------------
-
-you now use:
-
-[source,sh]
----------------
-GET /_nodes/stats/transport,http
----------------
-
-See the links above for full details.
-
-
-=== Indices APIs
-
-The `mapping`, `alias`, `settings`, and `warmer` index APIs are all similar
-but there are subtle differences in the order of the URL and the response
-body.  For instance, adding a mapping and a warmer look slightly different:
-
-[source,sh]
----------------
-PUT /{index}/{type}/_mapping
-PUT /{index}/_warmer/{name}
----------------
-
-These URLs have been unified as:
-
-[source,sh]
----------------
-PUT /{indices}/_mapping/{type}
-PUT /{indices}/_alias/{name}
-PUT /{indices}/_warmer/{name}
-
-GET /{indices}/_mapping/{types}
-GET /{indices}/_alias/{names}
-GET /{indices}/_settings/{names}
-GET /{indices}/_warmer/{names}
-
-DELETE /{indices}/_mapping/{types}
-DELETE /{indices}/_alias/{names}
-DELETE /{indices}/_warmer/{names}
----------------
-
-All of the `{indices}`, `{types}` and `{names}` parameters can be replaced by:
-
-  * `_all`, `*` or blank (ie left out altogether), all of which mean ``all''
-  * wildcards like `test*`
-  * comma-separated lists: `index_1,test_*`
-
-The only exception is `DELETE` which doesn't accept blank (missing)
-parameters. If you want to delete something, you should be specific.
-
-Similarly, the return values for `GET` have been unified with the following
-rules:
-
-* Only return values that exist.  If you try to `GET` a mapping which doesn't
-  exist, then the result will be an empty object: `{}`. We no longer throw a
-  `404` if the requested mapping/warmer/alias/setting doesn't exist.
-
-* The response format always has the index name, then the section, then the
-  element name, for instance:
-+
-[source,js]
----------------
-{
-    "my_index": {
-        "mappings": {
-            "my_type": {...}
-        }
-    }
-}
----------------
-+
-This is a breaking change for the `get_mapping` API.
-
-In the future we will also provide plural versions to allow putting multiple mappings etc in a single request.
-
-See <>, <>, <>,
-<>, <>,
-`warmers`, and <> for more details.
-
-=== Index request
-
-Previously a document could be indexed as itself, or wrapped in an outer
-object which specified the `type` name:
-
-[source,js]
----------------
-PUT /my_index/my_type/1
-{
-  "my_type": {
-     ... doc fields ...
-  }
-}
----------------
-
-This led to some ambiguity when a document also included a field with the same
-name as the `type`.  We no longer accept the outer `type` wrapper, but this
-behaviour can be reenabled on an index-by-index basis with the setting:
-`index.mapping.allow_type_wrapper`.
-
-=== Search requests
-
-While the `search` API takes a top-level `query` parameter, the
-<>, `delete-by-query` and
-<> requests expected the whole body to be a
-query. These now _require_ a top-level `query` parameter:
-
-[source,js]
----------------
-GET /_count
-{
-    "query": {
-        "match": {
-            "title": "Interesting stuff"
-        }
-    }
-}
----------------
-
-Also, the top-level `filter` parameter in search has been renamed to
-<>, to indicate that it should not
-be used as the primary way to filter search results (use a
-<> instead), but only to filter
-results AFTER aggregations have been calculated.
-
-This example counts the top colors in all matching docs, but only returns docs
-with color `red`:
-
-[source,js]
----------------
-GET /_search
-{
-    "query": {
-        "match_all": {}
-    },
-    "aggs": {
-        "colors": {
-            "terms": { "field": "color" }
-        }
-    },
-    "post_filter": {
-        "term": {
-            "color": "red"
-        }
-    }
-}
----------------
-
-=== Multi-fields
-
-Multi-fields are dead! Long live multi-fields!  Well, the field type
-`multi_field` has been removed.  Instead, any of the core field types
-(excluding `object` and `nested`) now accept a `fields` parameter.  It's the
-same thing, but nicer. Instead of:
-
-[source,js]
----------------
-"title": {
-    "type": "multi_field",
-    "fields": {
-        "title": { "type": "string" },
-        "raw":   { "type": "string", "index": "not_analyzed" }
-    }
-}
----------------
-
-you can now write:
-
-[source,js]
----------------
-"title": {
-    "type": "string",
-    "fields": {
-        "raw":   { "type": "string", "index": "not_analyzed" }
-    }
-}
----------------
-
-Existing multi-fields will be upgraded to the new format automatically.
-
-Also, instead of having to use the arcane `path` and `index_name` parameters
-in order to index multiple fields into a single ``custom +_all+ field'', you
-can now use the <>.
-
-=== Stopwords
-
-Previously, the <> and
-<> analyzers used the list of English stopwords
-by default, which caused some hard to debug indexing issues.  Now they are set to
-use the empty stopwords list (ie `_none_`) instead.
-
-=== Dates without years
-
-When dates are specified without a year, for example: `Dec 15 10:00:00` they
-are treated as dates in 2000 during indexing and range searches... except for
-the upper included bound `lte` where they were treated as dates in 1970!  Now,
-all https://github.com/elastic/elasticsearch/issues/4451[dates without years]
-use `1970` as the default.
-
-=== Parameters
-
-* Geo queries used to use `miles` as the default unit.  And we
-  http://en.wikipedia.org/wiki/Mars_Climate_Orbiter[all know what
-  happened at NASA] because of that decision.  The new default unit is
-  https://github.com/elastic/elasticsearch/issues/4515[`meters`].
-
-* For all queries that support _fuzziness_, the `min_similarity`, `fuzziness`
-  and `edit_distance` parameters have been unified as the single parameter
-  `fuzziness`.  See <> for details of accepted values.
-
-* The `ignore_missing` parameter has been replaced by the `expand_wildcards`,
-  `ignore_unavailable` and `allow_no_indices` parameters, all of which have
-  sensible defaults.  See <> for more.
-
-* An index name (or pattern) is now required for destructive operations like
-  deleting indices:
-+
-[source,sh]
----------------
-# v0.90 - delete all indices:
-DELETE /
-
-# v1.0 - delete all indices:
-DELETE /_all
-DELETE /*
----------------
-+
-Setting `action.destructive_requires_name` to `true` provides further safety
-by disabling wildcard expansion on destructive actions.
-
-=== Return values
-
-* The `ok` return value has been removed from all response bodies as it added
-  no useful information.
-
-* The `found`, `not_found` and `exists` return values have been unified as
-  `found` on all relevant APIs.
-
-* Field values, in response to the <>
-  parameter, are now always returned as arrays.  A field could have single or
-  multiple values, which meant that sometimes they were returned as scalars
-  and sometimes as arrays.  By always returning arrays, this simplifies user
-  code.  The only exception to this rule is when `fields` is used to retrieve
-  metadata like the `routing` value, which are always singular.  Metadata
-  fields are always returned as scalars.
-+
-The `fields` parameter is intended to be used for retrieving stored fields,
-rather than for fields extracted from the `_source`. That means that it can no
-longer be used to return whole objects and it no longer accepts the
-`_source.fieldname` format. For these you should use the
-<>
-parameters instead.
-
-* Settings, like `index.analysis.analyzer.default` are now returned as proper
-  nested JSON objects, which makes them easier to work with programmatically:
-+
-[source,js]
----------------
-{
-    "index": {
-        "analysis": {
-            "analyzer": {
-                "default": xxx
-            }
-        }
-    }
-}
----------------
-+
-You can choose to return them in flattened format by passing `?flat_settings`
-in the query string.
-
-* The <> API no longer supports the text response
-  format, but does support JSON and YAML.
-
-=== Deprecations
-
-* The `text` query has been removed.  Use the
-  <> query instead.
-
-* The `field` query has been removed.  Use the
-  <> query instead.
-
-* Per-document boosting with the `_boost` field has
-  been removed.  You can use the
-  <> instead.
-
-* The `path` parameter in mappings has been deprecated. Use the
-  <> parameter instead.
-
-* The `custom_score` and `custom_boost_score` is no longer supported. You can
-  use <> instead.
-
-=== Percolator
-
-The percolator has been redesigned and because of this the dedicated `_percolator` index is no longer used by the percolator,
-but instead the percolator works with a dedicated `.percolator` type. Read the http://www.elastic.co/blog/percolator-redesign-blog-post[redesigned percolator]
-blog post for the reasons why the percolator has been redesigned.
-
-Elasticsearch will *not* delete the `_percolator` index when upgrading, only the percolate api will not use the queries
-stored in the `_percolator` index. In order to use the already stored queries, you can just re-index the queries from the
-`_percolator` index into any index under the reserved `.percolator` type. The format in which the percolate queries
-were stored has *not* been changed. So a simple script that does a scan search to retrieve all the percolator queries
-and then does a bulk request into another index should be sufficient.
diff --git a/docs/reference/migration/migrate_1_4.asciidoc b/docs/reference/migration/migrate_1_4.asciidoc
deleted file mode 100644
index c20504bbddf..00000000000
--- a/docs/reference/migration/migrate_1_4.asciidoc
+++ /dev/null
@@ -1,92 +0,0 @@
-[[breaking-changes-1.4]]
-== Breaking changes in 1.4
-
-This section discusses the changes that you need to be aware of when migrating
-your application from Elasticsearch 1.x to Elasticsearch 1.4.
-
-[float]
-=== Percolator
-
-In indices created with version `1.4.0` or later, percolation queries can only
-refer to fields that already exist in the mappings in that index. There are
-two ways to make sure that a field mapping exist:
-
-* Add or update a mapping via the <> or
-  <> apis.
-* Percolate a document before registering a query. Percolating a document can
-  add field mappings dynamically, in the same way as happens when indexing a
-  document.
-
-[float]
-=== Aliases
-
-<> can include <> which
-are automatically applied to any search performed via the alias.
-<> created with version `1.4.0` or later can only
-refer to field names which exist in the mappings of the index (or indices)
-pointed to by the alias.
-
-Add or update a mapping via the <> or
-<> apis.
-
-[float]
-=== Indices APIs
-
-The get warmer api will return a section for `warmers` even if there are
-no warmers.  This ensures that the following two examples are equivalent:
-
-[source,js]
---------------------------------------------------
-curl -XGET 'http://localhost:9200/_all/_warmers'
-
-curl -XGET 'http://localhost:9200/_warmers'
---------------------------------------------------
-
-The <> will return a section for `aliases` even if there are
-no aliases.  This ensures that the following two examples are equivalent:
-
-[source,js]
---------------------------------------------------
-curl -XGET 'http://localhost:9200/_all/_aliases'
-
-curl -XGET 'http://localhost:9200/_aliases'
---------------------------------------------------
-
-The <> will return a section for `mappings` even if there are
-no mappings.  This ensures that the following two examples are equivalent:
-
-[source,js]
---------------------------------------------------
-curl -XGET 'http://localhost:9200/_all/_mappings'
-
-curl -XGET 'http://localhost:9200/_mappings'
---------------------------------------------------
-
-[float]
-=== Bulk UDP
-
-Bulk UDP has been deprecated and will be removed in 2.0.
-You should use <> instead.
-Each cluster must have an elected master node in order to be fully operational. Once a node loses its elected master
-node it will reject some or all operations.
-
-[float]
-=== Zen discovery
-
-On versions before `1.4.0.Beta1` all operations are rejected when a node loses its elected master. From `1.4.0.Beta1`
-only write operations will be rejected by default. Read operations will still be served based on the information available
-to the node, which may result in being partial and possibly also stale. If the default is undesired then the
-pre `1.4.0.Beta1` behaviour can be enabled, see: <>
-
-[float]
-=== More Like This Field
-
-The More Like This Field query has been deprecated in favor of the <>
-restrained set to a specific `field`. It will be removed in 2.0.
-
-[float]
-=== MVEL is deprecated
-
-Groovy is the new default scripting language in Elasticsearch, and is enabled in `sandbox` mode
-by default.  MVEL has been removed from core, but is available as a plugin:
-https://github.com/elastic/elasticsearch-lang-mvel
diff --git a/docs/reference/migration/migrate_1_6.asciidoc b/docs/reference/migration/migrate_1_6.asciidoc
deleted file mode 100644
index 9540d3b6759..00000000000
--- a/docs/reference/migration/migrate_1_6.asciidoc
+++ /dev/null
@@ -1,17 +0,0 @@
-[[breaking-changes-1.6]]
-== Breaking changes in 1.6
-
-This section discusses the changes that you need to be aware of when migrating
-your application from Elasticsearch 1.x to Elasticsearch 1.6.
-
-[float]
-=== More Like This API
-
-The More Like This API query has been deprecated and will be removed in 2.0. Instead use the <>.
-
-[float]
-=== `top_children` query
-
-The `top_children` query has been deprecated and will be removed in 2.0. Instead the `has_child` query should be used.
-The `top_children` query isn't always faster than the `has_child` query and the `top_children` query is often inaccurate.
-The total hits and any aggregations in the same search request will likely be off.
diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc
deleted file mode 100644
index adf12e7da5c..00000000000
--- a/docs/reference/migration/migrate_2_0.asciidoc
+++ /dev/null
@@ -1,73 +0,0 @@
-[[breaking-changes-2.0]]
-== Breaking changes in 2.0
-
-This section discusses the changes that you need to be aware of when migrating
-your application to Elasticsearch 2.0.
-
-[float]
-=== Indices created before 0.90
-
-Elasticsearch 2.0 can read indices created in version 0.90 and above.  If any
-of your indices were created before 0.90 you will need to upgrade to the
-latest 1.x version of Elasticsearch first, in order to upgrade your indices or
-to delete the old indices. Elasticsearch will not start in the presence of old
-indices.
-
-[float]
-=== Elasticsearch migration plugin
-
-We have provided the https://github.com/elastic/elasticsearch-migration[Elasticsearch migration plugin]
-to help you detect any issues that you may have when upgrading to
-Elasticsearch 2.0. Please install and run the plugin *before* upgrading.
-
-[float]
-=== Also see
-
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-
-include::migrate_2_0/removals.asciidoc[]
-
-include::migrate_2_0/network.asciidoc[]
-
-include::migrate_2_0/striping.asciidoc[]
-
-include::migrate_2_0/mapping.asciidoc[]
-
-include::migrate_2_0/crud.asciidoc[]
-
-include::migrate_2_0/query_dsl.asciidoc[]
-
-include::migrate_2_0/search.asciidoc[]
-
-include::migrate_2_0/aggs.asciidoc[]
-
-include::migrate_2_0/parent_child.asciidoc[]
-
-include::migrate_2_0/scripting.asciidoc[]
-
-include::migrate_2_0/index_apis.asciidoc[]
-
-include::migrate_2_0/snapshot_restore.asciidoc[]
-
-include::migrate_2_0/packaging.asciidoc[]
-
-include::migrate_2_0/settings.asciidoc[]
-
-include::migrate_2_0/stats.asciidoc[]
-
-include::migrate_2_0/java.asciidoc[]
diff --git a/docs/reference/migration/migrate_2_0/aggs.asciidoc b/docs/reference/migration/migrate_2_0/aggs.asciidoc
deleted file mode 100644
index 1351b4cb4a3..00000000000
--- a/docs/reference/migration/migrate_2_0/aggs.asciidoc
+++ /dev/null
@@ -1,70 +0,0 @@
-[[breaking_20_aggregation_changes]]
-=== Aggregation changes
-
-==== Min doc count defaults to zero
-
-Both the `histogram` and `date_histogram` aggregations now have a default
-`min_doc_count` of `0` instead of `1`.
-
-==== Timezone for date field
-
-Specifying the `time_zone` parameter in queries or aggregations on fields of
-type `date` must now be either an ISO 8601 UTC offset, or a timezone id. For
-example, the value `+1:00` must now be written as `+01:00`.
-
-==== Time zones and offsets
-
-The `histogram` and the `date_histogram` aggregation now support a simplified
-`offset` option that replaces the previous `pre_offset` and `post_offset`
-rounding options. Instead of having to specify two separate offset shifts of
-the underlying buckets, the `offset` option moves the bucket boundaries in
-positive or negative direction depending on its argument.
-
-The `date_histogram` options for `pre_zone` and `post_zone` are replaced by
-the `time_zone` option. The behavior of `time_zone` is equivalent to the
-former `pre_zone` option. Setting `time_zone` to a value like "+01:00" now
-will lead to the bucket calculations being applied in the specified time zone.
-The `key` is returned as the timestamp in UTC, but the `key_as_string` is
-returned in the time zone specified.
-
-In addition to this, the `pre_zone_adjust_large_interval` is removed because
-we now always return dates and bucket keys in UTC.
-
-==== Including/excluding terms
-
-`include`/`exclude` filtering on the `terms` aggregation now uses the same
-syntax as <> instead of the Java regular
-expression syntax. While simple regexps should still work, more complex ones
-might need some rewriting. Also, the `flags` parameter is no longer supported.
-
-==== Boolean fields
-
-Aggregations on `boolean` fields will now return `0` and `1` as keys, and
-`"true"` and `"false"` as string keys.  See <> for more
-information.
-
-
-==== Java aggregation classes
-
-The `date_histogram` aggregation now returns a `Histogram` object in the
-response, and the `DateHistogram` class has been removed.  Similarly the
-`date_range`, `ipv4_range`, and `geo_distance` aggregations all return a
-`Range` object in the response, and the `IPV4Range`, `DateRange`, and
-`GeoDistance` classes have been removed.
-
-The motivation for this is to have a single response API for the Range and
-Histogram aggregations regardless of the type of data being queried.  To
-support this some changes were made in the `MultiBucketAggregation` interface
-which applies to all bucket aggregations:
-
-* The `getKey()` method now returns `Object` instead of `String`. The actual
-  object type returned depends on the type of aggregation requested (e.g. the
-  `date_histogram` will return a `DateTime` object for this method whereas a
-  `histogram` will return a `Number`).
-* A `getKeyAsString()` method has been added to return the String
-  representation of the key.
-* All other `getKeyAsX()` methods have been removed.
-* The `getBucketAsKey(String)` methods have been removed on all aggregations
-  except the `filters` and `terms` aggregations.
-
-
diff --git a/docs/reference/migration/migrate_2_0/crud.asciidoc b/docs/reference/migration/migrate_2_0/crud.asciidoc
deleted file mode 100644
index ef3ba93e67e..00000000000
--- a/docs/reference/migration/migrate_2_0/crud.asciidoc
+++ /dev/null
@@ -1,130 +0,0 @@
-[[breaking_20_crud_and_routing_changes]]
-=== CRUD and routing changes
-
-==== Explicit custom routing
-
-Custom `routing` values can no longer be extracted from the document body, but
-must be specified explicitly as part of the query string, or in the metadata
-line in the <> API.  See <> for an
-example.
-
-==== Routing hash function
-
-The default hash function that is used for routing has been changed from
-`djb2` to `murmur3`. This change should be transparent unless you relied on
-very specific properties of `djb2`. This will help ensure a better balance of
-the document counts between shards.
-
-In addition, the following routing-related node settings have been deprecated:
-
-`cluster.routing.operation.hash.type`::
-
-  This was an undocumented setting that allowed to configure which hash function
-  to use for routing. `murmur3` is now enforced on new indices.
-
-`cluster.routing.operation.use_type`::
-
-  This was an undocumented setting that allowed to take the `_type` of the
-  document into account when computing its shard (default: `false`). `false` is
-  now enforced on new indices.
-
-==== Delete API with custom routing
-
-The delete API used to be broadcast to all shards in the index which meant
-that, when using custom routing, the `routing` parameter was optional. Now,
-the delete request is forwarded only to the shard holding the document. If you
-are using custom routing then you should specify the `routing` value when
-deleting a document, just as is already required for the `index`, `create`,
-and `update` APIs.
-
-To make sure that you never forget a routing value, make routing required with
-the following mapping:
-
-[source,js]
----------------------------
-PUT my_index
-{
-  "mappings": {
-    "my_type": {
-      "_routing": {
-        "required": true
-      }
-    }
-  }
-}
----------------------------
-
-==== All stored meta-fields returned by default
-
-Previously, meta-fields like `_routing`, `_timestamp`, etc would only be
-included in a GET request if specifically requested with the `fields`
-parameter.  Now, all meta-fields which have stored values will be returned by
-default.  Additionally, they are now returned at the top level (along with
-`_index`, `_type`, and `_id`) instead of in the `fields` element.
-
-For instance, the following request:
-
-[source,sh]
----------------
-GET /my_index/my_type/1
----------------
-
-might return:
-
-[source,js]
----------------
-{
-  "_index":     "my_index",
-  "_type":      "my_type",
-  "_id":        "1",
-  "_timestamp": 10000000, <1>
-  "_source": {
-    "foo" : [ "bar" ]
-  }
-}
----------------
-<1> The `_timestamp` is returned by default, and at the top level.
-
-
-==== Async replication
-
-The `replication` parameter has been removed from all CRUD operations
-(`index`, `create`,  `update`, `delete`, `bulk`) as it interfered with the
-<> feature.  These operations are now
-synchronous only and a request will only return once the changes have been
-replicated to all active shards in the shard group.
-
-Instead, use more client processes to send more requests in parallel.
-
-==== Documents must be specified without a type wrapper
-
-Previously, the document body could be wrapped in another object with the name
-of the `type`:
-
-[source,js]
---------------------------
-PUT my_index/my_type/1
-{
-  "my_type": { <1>
-    "text": "quick brown fox"
-  }
-}
---------------------------
-<1> This `my_type` wrapper is not part of the document itself, but represents the document type.
-
-This feature was deprecated before but could be reenabled with the
-`mapping.allow_type_wrapper` index setting.  This setting is no longer
-supported.  The above document should be indexed as follows:
-
-[source,js]
---------------------------
-PUT my_index/my_type/1
-{
-  "text": "quick brown fox"
-}
---------------------------
-
-==== Term Vectors API
-
-Usage of `/_termvector` is deprecated in favor of `/_termvectors`.
-
diff --git a/docs/reference/migration/migrate_2_0/index_apis.asciidoc b/docs/reference/migration/migrate_2_0/index_apis.asciidoc
deleted file mode 100644
index c177a887866..00000000000
--- a/docs/reference/migration/migrate_2_0/index_apis.asciidoc
+++ /dev/null
@@ -1,43 +0,0 @@
-[[breaking_20_index_api_changes]]
-=== Index API changes
-
-==== Index aliases
-
-
-Fields used in alias filters no longer have to exist in the mapping at alias
-creation time. Previously, alias filters were parsed at alias creation time
-and the parsed form was cached in memory. Now, alias filters are  parsed at
-request time and the fields in filters are resolved from the current mapping.
-
-This also means that index aliases now support `has_parent` and `has_child`
-queries.
-
-The <> will now throw an exception if no
-matching aliases are found. This change brings the defaults for this API in
-line with the other Indices APIs. The <> options can be used on a
-request to change this behavior.
-
-==== File based index templates
-
-Index templates can no longer be configured on disk. Use the
-<> API instead.
-
-==== Analyze API changes
-
-
-The Analyze API now returns the `position` of the first token as `0`
-instead of `1`.
-
-The `prefer_local` parameter has been removed. The `_analyze` API is a light
-operation and the caller shouldn't be concerned about whether it executes on
-the node that receives the request or another node.
-
-The `text()` method on `AnalyzeRequest` now returns `String[]` instead of
-`String`.
-
-==== Removed `id_cache` from clear cache api
-
-The <> API no longer supports the `id_cache`
-option.  Instead, use the `fielddata` option to clear the cache for the
-`_parent` field.
-
diff --git a/docs/reference/migration/migrate_2_0/java.asciidoc b/docs/reference/migration/migrate_2_0/java.asciidoc
deleted file mode 100644
index b2f5ee63e0d..00000000000
--- a/docs/reference/migration/migrate_2_0/java.asciidoc
+++ /dev/null
@@ -1,147 +0,0 @@
-[[breaking_20_java_api_changes]]
-=== Java API changes
-
-==== Transport API construction
-
-The `TransportClient` construction code has changed, it now uses the builder
-pattern. Instead of:
-
-[source,java]
---------------------------------------------------
-Settings settings = Settings.settingsBuilder()
-        .put("cluster.name", "myClusterName").build();
-Client client = new TransportClient(settings);
---------------------------------------------------
-
-Use the following:
-
-[source,java]
---------------------------------------------------
-Settings settings = Settings.settingsBuilder()
-        .put("cluster.name", "myClusterName").build();
-Client client = TransportClient.builder().settings(settings).build();
---------------------------------------------------
-
-The transport client also no longer supports loading settings from config files.
-If you have a config file, you can load it into settings yourself before
-constructing the transport client:
-
-[source,java]
---------------------------------------------------
-Settings settings = Settings.settingsBuilder()
-        .loadFromPath(pathToYourSettingsFile).build();
-Client client = TransportClient.builder().settings(settings).build();
---------------------------------------------------
-
-==== Exception are only thrown on total failure
-
-Previously, many APIs would throw an exception if any shard failed to execute
-the request. Now the exception is only thrown if all shards fail the request.
-The responses for these APIs will always have a `getShardFailures` method that
-you can and should check for failures.
-
-
-==== IndexMissingException removed.
-
-Use `IndexNotFoundException` instead.
-
-
-==== Automatically thread client listeners
-
-Previously, the user had to set request listener threads to `true` when on the
-client side in order not to block IO threads on heavy operations. This proved
-to be very trappy for users, and ended up creating problems that are very hard
-to debug.
-
-In 2.0, Elasticsearch automatically threads listeners that are used from the
-client when the client is a node client or a transport client. Threading can
-no longer be manually set.
-
-
-==== Query/filter refactoring
-
-`org.elasticsearch.index.queries.FilterBuilders` has been removed as part of the merge of
-queries and filters. These filters are now available in `QueryBuilders` with the same name.
-All methods that used to accept a `FilterBuilder` now accept a `QueryBuilder` instead.
-
-In addition some query builders have been removed or renamed:
-
-* `commonTerms(...)` renamed with `commonTermsQuery(...)`
-* `queryString(...)` renamed with `queryStringQuery(...)`
-* `simpleQueryString(...)` renamed with `simpleQueryStringQuery(...)`
-* `textPhrase(...)` removed
-* `textPhrasePrefix(...)` removed
-* `textPhrasePrefixQuery(...)` removed
-* `filtered(...)` removed. Use `filteredQuery(...)` instead.
-* `inQuery(...)` removed.
-
-==== GetIndexRequest
-
-`GetIndexRequest.features()` now returns an array of Feature Enums instead of an array of String values.
-
-The following deprecated methods have been removed:
-
-* `GetIndexRequest.addFeatures(String[])` - Use
-  `GetIndexRequest.addFeatures(Feature[])` instead
-
-* `GetIndexRequest.features(String[])` - Use
-  `GetIndexRequest.features(Feature[])` instead.
-
-* `GetIndexRequestBuilder.addFeatures(String[])` - Use
-  `GetIndexRequestBuilder.addFeatures(Feature[])` instead.
-
-* `GetIndexRequestBuilder.setFeatures(String[])` - Use
-  `GetIndexRequestBuilder.setFeatures(Feature[])` instead.
-
-
-==== BytesQueryBuilder removed
-
-The redundant BytesQueryBuilder has been removed in favour of the
-WrapperQueryBuilder internally.
-
-==== TermsQueryBuilder execution removed
-
-The `TermsQueryBuilder#execution` method has been removed as it has no effect, it is ignored by the
- corresponding parser.
-
-==== ImmutableSettings removed
-
-Use `Settings.builder()` instead of `ImmutableSettings.builder()`.
-
-==== InetSocketTransportAddress removed
-
-Use `InetSocketTransportAddress(InetSocketAddress address)` instead of `InetSocketTransportAddress(String, int)`.
-You can create an InetSocketAddress instance with `InetSocketAddress(String, int)`. For example:
-
-[source,java]
------------------------------
-new InetSocketTransportAddress(new InetSocketAddress("127.0.0.1", 0));
------------------------------
-
-==== Request Builders refactoring
-
-An `action` parameter has been added to various request builders:
-
-* Instead of `new SnapshotsStatusRequestBuilder(elasticSearchClient)` use `new SnapshotsStatusRequestBuilder(elasticSearchClient, SnapshotsStatusAction.INSTANCE)`.
-
-* Instead of `new CreateSnapshotRequestBuilder(elasticSearchClient)` use `new CreateSnapshotRequestBuilder(elasticSearchClient, CreateSnapshotAction.INSTANCE)`.
-
-* Instead of `new CreateIndexRequestBuilder(elasticSearchClient, index)` use `new CreateIndexRequestBuilder(elasticSearchClient, CreateIndexAction.INSTANCE, index)`.
-
-==== Shading and package relocation removed
-
-Elasticsearch used to shade its dependencies and to relocate packages. We no longer use shading or relocation.
-You might need to change your imports to the original package names:
-
-* `com.google.common` was `org.elasticsearch.common`
-* `com.carrotsearch.hppc` was `org.elasticsearch.common.hppc`
-* `jsr166e` was `org.elasticsearch.common.util.concurrent.jsr166e`
-* `com.fasterxml.jackson` was `org.elasticsearch.common.jackson`
-* `org.joda.time` was `org.elasticsearch.common.joda.time`
-* `org.joda.convert` was `org.elasticsearch.common.joda.convert`
-* `org.jboss.netty` was `org.elasticsearch.common.netty`
-* `com.ning.compress` was `org.elasticsearch.common.compress`
-* `com.github.mustachejava` was `org.elasticsearch.common.mustache`
-* `com.tdunning.math.stats` was `org.elasticsearch.common.stats`
-* `org.apache.commons.lang` was `org.elasticsearch.common.lang`
-* `org.apache.commons.cli` was `org.elasticsearch.common.cli.commons`
diff --git a/docs/reference/migration/migrate_2_0/mapping.asciidoc b/docs/reference/migration/migrate_2_0/mapping.asciidoc
deleted file mode 100644
index b4ee0d54412..00000000000
--- a/docs/reference/migration/migrate_2_0/mapping.asciidoc
+++ /dev/null
@@ -1,439 +0,0 @@
-[[breaking_20_mapping_changes]]
-=== Mapping changes
-
-A number of changes have been made to mappings to remove ambiguity and to
-ensure that conflicting mappings cannot be created.
-
-One major change is that dynamically added fields must have their mapping
-confirmed by the master node before indexing continues.  This is to avoid a
-problem where different shards in the same index dynamically add different
-mappings for the same field.  These conflicting mappings can silently return
-incorrect results and can lead to index corruption.
-
-This change can make indexing slower when frequently adding many new fields.
-We are looking at ways of optimising this process but we chose safety over
-performance for this extreme use case.
-
-==== Conflicting field mappings
-
-Fields with the same name, in the same index, in different types, must have
-the same mapping, with the exception of the <>, <>,
-<>, <>, <>, and <>
-parameters, which may have different settings per field.
-
-[source,js]
----------------
-PUT my_index
-{
-  "mappings": {
-    "type_one": {
-      "properties": {
-        "name": { <1>
-          "type": "string"
-        }
-      }
-    },
-    "type_two": {
-      "properties": {
-        "name": { <1>
-          "type":     "string",
-          "analyzer": "english"
-        }
-      }
-    }
-  }
-}
----------------
-<1> The two `name` fields have conflicting mappings and will prevent Elasticsearch
-    from starting.
-
-Elasticsearch will not start in the presence of conflicting field mappings.
-These indices must be deleted or reindexed using a new mapping.
-
-The `ignore_conflicts` option of the put mappings API has been removed.
-Conflicts can't be ignored anymore.
-
-==== Fields cannot be referenced by short name
-
-A field can no longer be referenced using its short name.  Instead, the full
-path to the field is required.  For instance:
-
-[source,js]
----------------
-PUT my_index
-{
-  "mappings": {
-    "my_type": {
-      "properties": {
-        "title":     { "type": "string" }, <1>
-        "name": {
-          "properties": {
-            "title": { "type": "string" }, <2>
-            "first": { "type": "string" },
-            "last":  { "type": "string" }
-          }
-        }
-      }
-    }
-  }
-}
----------------
-<1> This field is referred to as `title`.
-<2> This field is referred to as `name.title`.
-
-Previously, the two `title` fields in the example above could have been
-confused with each other when using the short name `title`.
-
-==== Type name prefix removed
-
-Previously, two fields with the same name in two different types could
-sometimes be disambiguated by prepending the type name.  As a side effect, it
-would add a filter on the type name to the relevant query.  This feature was
-ambiguous -- a type name could be confused with a field name -- and didn't
-work everywhere e.g. aggregations.
-
-Instead, fields should be specified with the full path, but without a type
-name prefix.  If you wish to filter by the `_type` field, either specify the
-type in the URL or add an explicit filter.
-
-The following example query in 1.x:
-
-[source,js]
-----------------------------
-GET my_index/_search
-{
-  "query": {
-    "match": {
-      "my_type.some_field": "quick brown fox"
-    }
-  }
-}
-----------------------------
-
-would be rewritten in 2.0 as:
-
-[source,js]
-----------------------------
-GET my_index/my_type/_search <1>
-{
-  "query": {
-    "match": {
-      "some_field": "quick brown fox" <2>
-    }
-  }
-}
-----------------------------
-<1> The type name can be specified in the URL to act as a filter.
-<2> The field name should be specified without the type prefix.
-
-==== Field names may not contain dots
-
-In 1.x, it was possible to create fields with dots in their name, for
-instance:
-
-[source,js]
-----------------------------
-PUT my_index
-{
-  "mappings": {
-    "my_type": {
-      "properties": {
-        "foo.bar": { <1>
-          "type": "string"
-        },
-        "foo": {
-          "properties": {
-            "bar": { <1>
-              "type": "string"
-            }
-          }
-        }
-      }
-    }
-  }
-}
-----------------------------
-<1> These two fields cannot be distinguished as both are referred to as `foo.bar`.
-
-You can no longer create fields with dots in the name.
-
-==== Type names may not start with a dot
-
-In 1.x, Elasticsearch would issue a warning if a type name included a dot,
-e.g. `my.type`.  Now that type names are no longer used to distinguish between
-fields in different types, this warning has been relaxed: type names may now
-contain dots, but they may not *begin* with a dot.  The only exception to this
-is the special `.percolator` type.
-
-==== Type names may not be longer than 255 characters
-
-Mapping type names may not be longer than 255 characters.  Long type names
-will continue to function on indices created before upgrade, but it will not
-be possible create types with long names in new indices.
-
-==== Types may no longer be deleted
-
-In 1.x it was possible to delete a type mapping, along with all of the
-documents of that type, using the delete mapping API.  This is no longer
-supported, because remnants of the fields in the type could remain in the
-index, causing corruption later on.
-
-Instead, if you need to delete a type mapping, you should reindex to a new
-index which does not contain the mapping.  If you just need to delete the
-documents that belong to that type, then use the delete-by-query plugin
-instead.
-
-[[migration-meta-fields]]
-==== Type meta-fields
-
-The <> associated with had configuration options
-removed, to make them more reliable:
-
-* `_id` configuration can no longer be changed.  If you need to sort, use the <> field instead.
-* `_type` configuration can no longer be changed.
-* `_index` configuration can no longer be changed.
-* `_routing` configuration is limited to marking routing as required.
-* `_field_names` configuration is limited to disabling the field.
-* `_size` configuration is limited to enabling the field.
-* `_timestamp` configuration is limited to enabling the field, setting format and default value.
-* `_boost` has been removed.
-* `_analyzer` has been removed.
-
-Importantly, *meta-fields can no longer be specified as part of the document
-body.*  Instead, they must be specified in the query string parameters.  For
-instance, in 1.x, the `routing` could be specified as follows:
-
-[source,json]
------------------------------
-PUT my_index
-{
-  "mappings": {
-    "my_type": {
-      "_routing": {
-        "path": "group" <1>
-      },
-      "properties": {
-        "group": { <1>
-          "type": "string"
-        }
-      }
-    }
-  }
-}
-
-PUT my_index/my_type/1 <2>
-{
-  "group": "foo"
-}
------------------------------
-<1> This 1.x mapping tells Elasticsearch to extract the `routing` value from the `group` field in the document body.
-<2> This indexing request uses a `routing` value of `foo`.
-
-In 2.0, the routing must be specified explicitly:
-
-[source,json]
------------------------------
-PUT my_index
-{
-  "mappings": {
-    "my_type": {
-      "_routing": {
-        "required": true <1>
-      },
-      "properties": {
-        "group": {
-          "type": "string"
-        }
-      }
-    }
-  }
-}
-
-PUT my_index/my_type/1?routing=bar <2>
-{
-  "group": "foo"
-}
------------------------------
-<1> Routing can be marked as required to ensure it is not forgotten during indexing.
-<2> This indexing request uses a `routing` value of `bar`.
-
-==== `_timestamp` and `_ttl` deprecated
-
-The `_timestamp` and `_ttl` fields are deprecated, but will remain functional
-for the remainder of the 2.x series.
-
-Instead of the `_timestamp` field, use a normal <> field and set
-the value explicitly.
-
-The current `_ttl` functionality will be replaced in a future version with a
-new implementation of TTL, possibly with different semantics, and will not
-depend on the `_timestamp` field.
-
-==== Analyzer mappings
-
-Previously, `index_analyzer` and `search_analyzer` could be set separately,
-while the `analyzer` setting would set both.  The `index_analyzer` setting has
-been removed in favour of just using the `analyzer` setting.
-
-If just the `analyzer` is set, it will be used at index time and at search time.  To use a different analyzer at search time, specify both the `analyzer` and a `search_analyzer`.
-
-The `index_analyzer`, `search_analyzer`,  and `analyzer` type-level settings
-have also been removed, as it is no longer possible to select fields based on
-the type name.
-
-The `_analyzer` meta-field, which allowed setting an analyzer per document has
-also been removed.  It will be ignored on older indices.
-
-==== Date fields and Unix timestamps
-
-Previously, `date` fields would first try to parse values as a Unix timestamp
--- milliseconds-since-the-epoch -- before trying to use their defined date
-`format`.  This meant that formats like `yyyyMMdd` could never work, as values
-would be interpreted as timestamps.
-
-In 2.0, we have added two formats: `epoch_millis` and `epoch_second`.  Only
-date fields that use these formats will be able to parse timestamps.
-
-These formats cannot be used in dynamic templates, because they are
-indistinguishable from long values.
-
-==== Default date format
-
-The default date format has changed from `date_optional_time` to
-`strict_date_optional_time`, which expects a 4 digit year, and a 2 digit month
-and day, (and optionally, 2 digit hour, minute, and second).
-
-A dynamically added date field, by default, includes the `epoch_millis`
-format to support timestamp parsing.  For instance:
-
-[source,js]
--------------------------
-PUT my_index/my_type/1
-{
-  "date_one": "2015-01-01" <1>
-}
--------------------------
-<1> Has `format`: `"strict_date_optional_time||epoch_millis"`.
-
-==== `mapping.date.round_ceil` setting
-
-The `mapping.date.round_ceil` setting for date math parsing has been removed.
-
-[[migration-bool-fields]]
-==== Boolean fields
-
-Boolean fields used to have a string fielddata with `F` meaning `false` and `T`
-meaning `true`. They have been refactored to use numeric fielddata, with `0`
-for `false` and `1` for `true`. As a consequence, the format of the responses of
-the following APIs changed when applied to boolean fields: `0`/`1` is returned
-instead of `F`/`T`:
-
-* <>
-* <>
-* <>
-
-In addition, terms aggregations use a custom formatter for boolean (like for
-dates and ip addresses, which are also backed by numbers) in order to return
-the user-friendly representation of boolean fields: `false`/`true`:
-
-[source,js]
----------------
-"buckets": [
-  {
-     "key": 0,
-     "key_as_string": "false",
-     "doc_count": 42
-  },
-  {
-     "key": 1,
-     "key_as_string": "true",
-     "doc_count": 12
-  }
-]
----------------
-
-==== `index_name` and `path` removed
-
-The `index_name` setting was used to change the name of the Lucene field,
-and the `path` setting was used on `object` fields to determine whether the
-Lucene field should use the full path (including parent object fields), or
-just the final `name`.
-
-These setting have been removed as their purpose is better served with the
-<> parameter.
-
-==== Murmur3 Fields
-
-Fields of type `murmur3` can no longer change `doc_values` or `index` setting.
-They are always mapped as follows:
-
-[source,js]
----------------------
-{
-  "type":       "murmur3",
-  "index":      "no",
-  "doc_values": true
-}
----------------------
-
-==== Mappings in config files not supported
-
-The ability to specify mappings in configuration files has been removed. To
-specify default mappings that apply to multiple indexes, use
-<> instead.
-
-Along with this change, the following settings have been removed:
-
-* `index.mapper.default_mapping_location`
-* `index.mapper.default_percolator_mapping_location`
-
-==== Fielddata formats
-
-Now that doc values are the default for fielddata, specialized in-memory
-formats have become an esoteric option. These fielddata formats have been removed:
-
-* `fst` on string fields
-* `compressed` on geo points
-
-The default fielddata format will be used instead.
-
-==== Posting and doc-values codecs
-
-It is no longer possible to specify per-field postings and doc values formats
-in the mappings. This setting will be ignored on indices created before 2.0
-and will cause mapping parsing to fail on indices created on or after 2.0. For
-old indices, this means that new segments will be written with the default
-postings and doc values formats of the current codec.
-
-It is still possible to change the whole codec by using the `index.codec`
-setting. Please however note that using a non-default codec is discouraged as
-it could prevent future versions of Elasticsearch from being able to read the
-index.
-
-==== Compress and compress threshold
-
-The `compress` and `compress_threshold` options have been removed from the
-`_source` field and fields of type `binary`.  These fields are compressed by
-default.  If you would like to increase compression levels, use the new
-<> setting instead.
-
-==== position_offset_gap
-
-The `position_offset_gap` option is renamed to 'position_increment_gap'. This was
-done to clear away the confusion. Elasticsearch's 'position_increment_gap' now is
-mapped directly to Lucene's 'position_increment_gap'
-
-The default `position_increment_gap` is now 100. Indexes created in Elasticsearch
-2.0.0 will default to using 100 and indexes created before that will continue
-to use the old default of 0. This was done to prevent phrase queries from
-matching across different values of the same term unexpectedly. Specifically,
-100 was chosen to cause phrase queries with slops up to 99 to match only within
-a single value of a field.
-
-==== copy_to and multi fields
-
-A <> within a <> is ignored from version 2.0 on. With any version after
-2.1 or 2.0.1 creating a mapping that has a copy_to within a multi field will result 
-in an exception.
-
-
diff --git a/docs/reference/migration/migrate_2_0/network.asciidoc b/docs/reference/migration/migrate_2_0/network.asciidoc
deleted file mode 100644
index d493bff5688..00000000000
--- a/docs/reference/migration/migrate_2_0/network.asciidoc
+++ /dev/null
@@ -1,39 +0,0 @@
-[[breaking_20_network_changes]]
-=== Network changes
-
-==== Bind to localhost
-
-Elasticsearch 2.x will only bind to localhost by default. It will try to bind
-to both 127.0.0.1 (IPv4) and [::1] (IPv6), but will work happily in
-environments where only IPv4 or IPv6 is available. This change prevents
-Elasticsearch from trying to connect to other nodes on your network unless you
-specifically tell it to do so. When moving to production you should configure
-the `network.host` parameter, either in the `elasticsearch.yml` config file or
-on the command line:
-
-[source,sh]
---------------------
-bin/elasticsearch --network.host 192.168.1.5
-bin/elasticsearch --network.host _non_loopback_
---------------------
-
-The full list of options that network.host accepts can be found in the <>.
-
-==== Unicast discovery
-
-When bound to localhost, Elasticsearch will use unicast to contact
-the first 5 ports in the `transport.tcp.port` range, which defaults to
-`9300-9400`. This preserves the zero-config auto-clustering experience for the developer,
-but it means that you will have to provide a list of <>
-when moving to production, for instance:
-
-[source,yaml]
----------------------
-discovery.zen.ping.unicast.hosts: [ 192.168.1.2,  192.168.1.3 ]
----------------------
-
-You don’t need to list all of the nodes in your cluster as unicast hosts, but
-you should specify at least a quorum (majority) of master-eligible nodes. A
-big cluster will typically have three dedicated master nodes, in which case we
-recommend listing all three of them as unicast hosts.
-
diff --git a/docs/reference/migration/migrate_2_0/packaging.asciidoc b/docs/reference/migration/migrate_2_0/packaging.asciidoc
deleted file mode 100644
index dae87187ba4..00000000000
--- a/docs/reference/migration/migrate_2_0/packaging.asciidoc
+++ /dev/null
@@ -1,84 +0,0 @@
-[[breaking_20_plugin_and_packaging_changes]]
-=== Plugin and packaging changes
-
-==== Symbolic links and paths
-
-Elasticsearch 2.0 runs with the Java security manager enabled and is much more
-restrictive about which paths it is allowed to access.  Various paths can be
-configured, e.g. `path.data`, `path.scripts`, `path.repo`.  A configured path
-may itself be a symbolic link, but no symlinks under that path will be
-followed.
-
-==== Running `bin/elasticsearch`
-
-The command line parameter parsing has been rewritten to deal properly with
-spaces in parameters. All config settings can still be specified on the
-command line when starting Elasticsearch, but they must appear after the
-built-in "static parameters", such as `-d` (to daemonize) and `-p` (the PID path).
-
-For instance:
-
-[source,sh]
------------
-bin/elasticsearch -d -p /tmp/foo.pid --http.cors.enabled=true --http.cors.allow-origin='*'
------------
-
-For a list of static parameters, run `bin/elasticsearch -h`
-
-==== `-f` removed
-
-The `-f` parameter, which used to indicate that Elasticsearch should be run in
-the foreground, was deprecated in 1.0 and removed in 2.0.
-
-==== `V` for version
-
-The `-v` parameter now means `--verbose` for both `bin/elasticsearch-plugin` and
-`bin/elasticsearch` (although it has no effect on the latter).  To output the
-version, use `-V` or `--version` instead.
-
-==== Plugin manager should run as root
-
-The permissions of the `config`, `bin`, and `plugins` directories in the RPM
-and deb packages have been made more restrictive.  The plugin manager should
-be run as root otherwise it will not be able to install plugins.
-
-==== Support for official plugins
-
-Almost all of the official Elasticsearch plugins have been moved to the main
-`elasticsearch` repository. They will be released at the same time as
-Elasticsearch and have the same version number as Elasticsearch.
-
-Official plugins can be installed as follows:
-
-[source,sh]
----------------
-sudo bin/elasticsearch-plugin install analysis-icu
----------------
-
-Community-provided plugins can be installed as before.
-
-==== Plugins require descriptor file
-
-All plugins are now required to have a https://github.com/elastic/elasticsearch/blob/2.0/dev-tools/src/main/resources/plugin-metadata/plugin-descriptor.properties[plugin-descriptor.properties]  file.  If a node has a plugin installed which lacks this file, it will be unable to start.
-
-==== Repository naming structure changes
-
-Elasticsearch 2.0 changes the way the repository URLs are referenced. Instead
-of specific repositories for both major and minor versions, the repositories will
-use a major version reference only.
-
-The URL for apt packages now uses the following structure;
-
-[source,sh]
----------------
-deb http://packages.elastic.co/elasticsearch/2.x/debian stable main
----------------
-
-And for yum packages it is;
-
-[source,sh]
----------------
-baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
----------------
-
-The <> page details this change.
diff --git a/docs/reference/migration/migrate_2_0/parent_child.asciidoc b/docs/reference/migration/migrate_2_0/parent_child.asciidoc
deleted file mode 100644
index 1addf883973..00000000000
--- a/docs/reference/migration/migrate_2_0/parent_child.asciidoc
+++ /dev/null
@@ -1,43 +0,0 @@
-[[breaking_20_parent_child_changes]]
-=== Parent/Child changes
-
-Parent/child has been rewritten completely to reduce memory usage and to
-execute `has_child` and `has_parent` queries faster and more efficient. The
-`_parent` field uses doc values by default. The refactored and improved
-implementation is only active for indices created on or after version 2.0.
-
-In order to benefit from all the performance and memory improvements, we
-recommend reindexing all existing indices that use the `_parent` field.
-
-==== Parent type cannot pre-exist
-
-A mapping type is declared as a child of another mapping type by specifying
-the `_parent` meta field:
-
-[source,js]
---------------------------
-DELETE *
-
-PUT my_index
-{
-  "mappings": {
-    "my_parent": {},
-    "my_child": {
-      "_parent": {
-        "type": "my_parent" <1>
-      }
-    }
-  }
-}
---------------------------
-<1> The `my_parent` type is the parent of the `my_child` type.
-
-The mapping for the parent type can be added at the same time as the mapping
-for the child type, but cannot be added before the child type.
-
-==== `top_children` query removed
-
-The `top_children` query has been removed in favour of the `has_child` query.
-It wasn't always faster than the `has_child` query and the results were usually
-inaccurate. The total hits and any aggregations in the same search request
-would be incorrect if `top_children` was used.
diff --git a/docs/reference/migration/migrate_2_0/query_dsl.asciidoc b/docs/reference/migration/migrate_2_0/query_dsl.asciidoc
deleted file mode 100644
index a85ade8690b..00000000000
--- a/docs/reference/migration/migrate_2_0/query_dsl.asciidoc
+++ /dev/null
@@ -1,189 +0,0 @@
-[[breaking_20_query_dsl_changes]]
-=== Query DSL changes
-
-==== Queries and filters merged
-
-Queries and filters have been merged -- all filter clauses are now query
-clauses. Instead, query clauses can now be used in _query context_ or in
-_filter context_:
-
-Query context::
-
-A query used in query context will calculate relevance scores and will not be
-cacheable.  Query context is used whenever filter context does not apply.
-
-Filter context::
-+
---
-
-A query used in filter context will not calculate relevance scores, and will
-be cacheable. Filter context is introduced by:
-
-* the `constant_score` query
-* the `must_not` and (newly added) `filter` parameter in the `bool` query
-* the `filter` and `filters` parameters in the `function_score` query
-* any API called `filter`, such as the `post_filter` search parameter, or in
-  aggregations or index aliases
---
-
-==== `terms` query and filter
-
-The `execution` option of the `terms` filter is now deprecated and is ignored
-if provided. Similarly, the `terms` query no longer supports the
-`minimum_should_match` parameter.
-
-==== `or` and `and` now implemented via `bool`
-
-The `or` and `and` filters previously had a different execution pattern to the
-`bool` filter. It used to be important to use `and`/`or` with certain filter
-clauses, and `bool` with others.
-
-This distinction has been removed: the `bool` query is now smart enough to
-handle both cases optimally.  As a result of this change, the `or` and `and`
-filters are now sugar syntax which are executed internally as a `bool` query.
-These filters may be removed in the future.
-
-==== `filtered` query and `query` filter deprecated
-
-The `query` filter is deprecated as is it no longer needed -- all queries can
-be used in query or filter context.
-
-The `filtered` query is deprecated in favour of the `bool` query. Instead of
-the following:
-
-[source,js]
--------------------------
-GET _search
-{
-  "query": {
-    "filtered": {
-      "query": {
-        "match": {
-          "text": "quick brown fox"
-        }
-      },
-      "filter": {
-        "term": {
-          "status": "published"
-        }
-      }
-    }
-  }
-}
--------------------------
-
-move the query and filter to the `must` and `filter` parameters in the `bool`
-query:
-
-[source,js]
--------------------------
-GET _search
-{
-  "query": {
-    "bool": {
-      "must": {
-        "match": {
-          "text": "quick brown fox"
-        }
-      },
-      "filter": {
-        "term": {
-          "status": "published"
-        }
-      }
-    }
-  }
-}
--------------------------
-
-==== Filter auto-caching
-
-It used to be possible to control which filters were cached with the `_cache`
-option and to provide a custom `_cache_key`.  These options are deprecated
-and, if present, will be ignored.
-
-Query clauses used in filter context are now auto-cached when it makes sense
-to do so.  The algorithm takes into account the frequency of use, the cost of
-query execution, and the cost of building the filter.
-
-The `terms` filter lookup mechanism no longer caches the values of the
-document containing the terms.  It relies on the filesystem cache instead. If
-the lookup index is not too large, it is recommended to replicate it to all
-nodes by setting `index.auto_expand_replicas: 0-all` in order to remove the
-network overhead as well.
-
-==== Numeric queries use IDF for scoring
-
-Previously, term queries on numeric fields were deliberately prevented from
-using the usual Lucene scoring logic and this behaviour was undocumented and,
-to some, unexpected.
-
-Single `term` queries on numeric fields now score in the same way as string
-fields, using IDF and norms (if enabled).
-
-To query numeric fields without scoring, the query clause should be used in
-filter context, e.g. in the `filter` parameter of the `bool` query, or wrapped
-in a `constant_score` query:
-
-[source,js]
-----------------------------
-GET _search
-{
-  "query": {
-    "bool": {
-      "must": [
-        {
-          "match": { <1>
-            "numeric_tag": 5
-          }
-        }
-      ],
-      "filter": [
-        {
-          "match": { <2>
-            "count": 5
-          }
-        }
-      ]
-    }
-  }
-}
-----------------------------
-<1> This clause would include IDF in the relevance score calculation.
-<2> This clause would have no effect on the relevance score.
-
-==== Fuzziness and fuzzy-like-this
-
-Fuzzy matching used to calculate the score for each fuzzy alternative, meaning
-that rare misspellings would have a higher score than the more common correct
-spellings. Now, fuzzy matching blends the scores of all the fuzzy alternatives
-to use the IDF of the most frequently occurring alternative.
-
-Fuzziness can no longer be specified using a percentage, but should instead
-use the number of allowed edits:
-
-* `0`, `1`, `2`, or
-* `AUTO` (which chooses `0`, `1`, or `2` based on the length of the term)
-
-The `fuzzy_like_this` and `fuzzy_like_this_field` queries used a very
-expensive approach to fuzzy matching and have been removed.
-
-==== More Like This
-
-The More Like This (`mlt`) API and the `more_like_this_field` (`mlt_field`)
-query have been removed in favor of the
-<> query.
-
-The parameter `percent_terms_to_match` has been removed in favor of
-`minimum_should_match`.
-
-==== `limit` filter deprecated
-
-The `limit` filter is deprecated and becomes a no-op. You can achieve similar
-behaviour using the <> parameter.
-
-==== Java plugins registering custom queries
-
-Java plugins that register custom queries can do so by using the
-`IndicesQueriesModule#addQuery(Class)` method. Other
-ways to register custom queries are not supported anymore.
diff --git a/docs/reference/migration/migrate_2_0/removals.asciidoc b/docs/reference/migration/migrate_2_0/removals.asciidoc
deleted file mode 100644
index 31693c3d3ac..00000000000
--- a/docs/reference/migration/migrate_2_0/removals.asciidoc
+++ /dev/null
@@ -1,100 +0,0 @@
-[[breaking_20_removed_features]]
-=== Removed features
-
-==== Rivers have been removed
-
-Elasticsearch does not support rivers anymore. While we had first planned to
-keep them around to ease migration, keeping support for rivers proved to be
-challenging as it conflicted with other important changes that we wanted to
-bring to 2.0 like synchronous dynamic mappings updates, so we eventually
-decided to remove them entirely. See
-link:/blog/deprecating_rivers[Deprecating Rivers] for more background about
-why we took this decision.
-
-==== Facets have been removed
-
-Facets, deprecated since 1.0, have now been removed.  Instead, use the much
-more powerful and flexible <> framework.
-This also means that Kibana 3 will not work with Elasticsearch 2.0.
-
-==== MVEL has been removed
-
-The MVEL scripting language has been removed.  The default scripting language
-is now Groovy.
-
-==== Delete-by-query is now a plugin
-
-The old delete-by-query functionality was fast but unsafe.  It could lead to
-document differences between the primary and replica shards, and could even
-produce out of memory exceptions and cause the cluster to crash.
-
-This feature has been reimplemented using the <> and
-<> APIs, which may be slower for queries which match
-large numbers of documents, but is safe.
-
-Currently, a long running delete-by-query job cannot be cancelled, which is
-one of the reasons that this functionality is only available as a plugin.  You
-can install the plugin with:
-
-[source,sh]
-------------------
-./bin/elasticsearch-plugin install delete-by-query
-------------------
-
-See {plugins}/plugins-delete-by-query.html for more information.
-
-==== Multicast Discovery is now a plugin
-
-Support for multicast is very patchy. Linux doesn’t allow multicast listening on localhost,
-while OS/X sends multicast broadcasts across all interfaces regardless of the configured
-bind address. On top of that, some networks have multicast disabled by default.
-
-This feature has been moved to a plugin. The default discovery mechanism now uses
-unicast, with a default setup which looks for the first 5 ports on localhost. If you
-still need to use multicast discovery, you can install the plugin with:
-
-[source,sh]
-------------------
-./bin/elasticsearch-plugin install discovery-multicast
-------------------
-
-==== `_shutdown` API
-
-The `_shutdown` API has been removed without a replacement. Nodes should be
-managed via the operating system and the provided start/stop scripts.
-
-==== `murmur3` is now a plugin
-
-The `murmur3` field, which indexes hashes of the field values, has been moved
-out of core and is available as a plugin. It can be installed as:
-
-[source,sh]
-------------------
-./bin/elasticsearch-plugin install mapper-murmur3
-------------------
-
-==== `_size` is now a plugin
-
-The `_size` meta-data field, which indexes the size in bytes of the original
-JSON document, has been moved out of core and is available as a plugin.  It
-can be installed as:
-
-[source,sh]
-------------------
-./bin/elasticsearch-plugin install mapper-size
-------------------
-
-==== Thrift and memcached transport
-
-The thrift and memcached transport plugins are no longer supported.  Instead, use
-either the HTTP transport (enabled by default) or the node or transport Java client.
-
-==== Bulk UDP
-
-The bulk UDP API has been removed.  Instead, use the standard
-<> API, or use UDP to send documents to Logstash first.
-
-==== MergeScheduler pluggability
-
-The merge scheduler is no longer pluggable.
-
diff --git a/docs/reference/migration/migrate_2_0/scripting.asciidoc b/docs/reference/migration/migrate_2_0/scripting.asciidoc
deleted file mode 100644
index 495d2daa2c5..00000000000
--- a/docs/reference/migration/migrate_2_0/scripting.asciidoc
+++ /dev/null
@@ -1,103 +0,0 @@
-[[breaking_20_scripting_changes]]
-=== Scripting changes
-
-==== Scripting syntax
-
-The syntax for scripts has been made consistent across all APIs. The accepted
-format is as follows:
-
-Inline/Dynamic scripts::
-+
---
-
-[source,js]
----------------
-"script": {
-  "inline": "doc['foo'].value + val", <1>
-  "lang":   "groovy", <2>
-  "params": { "val": 3 } <3>
-}
----------------
-<1> The inline script to execute.
-<2> The optional language of the script.
-<3> Any named parameters.
---
-
-Indexed scripts::
-+
---
-[source,js]
----------------
-"script": {
-  "id":     "my_script_id", <1>
-  "lang":   "groovy", <2>
-  "params": { "val": 3 } <3>
-}
----------------
-<1> The ID of the indexed script.
-<2> The optional language of the script.
-<3> Any named parameters.
---
-
-File scripts::
-+
---
-[source,js]
----------------
-"script": {
-  "file":   "my_file", <1>
-  "lang":   "groovy", <2>
-  "params": { "val": 3 } <3>
-}
----------------
-<1> The filename of the script, without the `.lang` suffix.
-<2> The optional language of the script.
-<3> Any named parameters.
---
-
-For example, an update request might look like this:
-
-[source,js]
----------------
-POST my_index/my_type/1/_update
-{
-  "script": {
-    "inline": "ctx._source.count += val",
-    "params": { "val": 3 }
-  },
-  "upsert": {
-    "count": 0
-  }
-}
----------------
-
-A short syntax exists for running inline scripts in the default scripting
-language without any parameters:
-
-[source,js]
-----------------
-GET _search
-{
-  "script_fields": {
-    "concat_fields": {
-      "script": "doc['one'].value + ' ' + doc['two'].value"
-    }
-  }
-}
-----------------
-
-==== Scripting settings
-
-The `script.disable_dynamic` node setting has been replaced by fine-grained
-script settings described in <>.
-
-==== Groovy scripts sandbox
-
-The Groovy sandbox and related settings have been removed. Groovy is now a
-non-sandboxed scripting language, without any option to turn the sandbox on.
-
-==== Plugins making use of scripts
-
-Plugins that make use of scripts must register their own script context
-through `ScriptModule`. Script contexts can be used as part of fine-grained
-settings to enable/disable scripts selectively.
diff --git a/docs/reference/migration/migrate_2_0/search.asciidoc b/docs/reference/migration/migrate_2_0/search.asciidoc
deleted file mode 100644
index 036313077ff..00000000000
--- a/docs/reference/migration/migrate_2_0/search.asciidoc
+++ /dev/null
@@ -1,122 +0,0 @@
-[[breaking_20_search_changes]]
-=== Search changes
-
-==== Partial fields
-
-Partial fields have been removed in favor of <>.
-
-==== `search_type=count` deprecated
-
-The `count` search type has been deprecated. All benefits from this search
-type can now be achieved by using the (default) `query_then_fetch` search type
-and setting `size` to `0`.
-
-==== The count api internally uses the search api
-
-The count api is now a shortcut to the search api with `size` set to 0. As a
-result, a total failure will result in an exception being returned rather
-than a normal response with `count` set to `0` and shard failures.
-
-==== All stored meta-fields returned by default
-
-Previously, meta-fields like `_routing`, `_timestamp`, etc would only be
-included in the search results if specifically requested with the `fields`
-parameter.  Now, all meta-fields which have stored values will be returned by
-default.  Additionally, they are now returned at the top level (along with
-`_index`, `_type`, and `_id`) instead of in the `fields` element.
-
-For instance, the following request:
-
-[source,sh]
----------------
-GET /my_index/_search?fields=foo
----------------
-
-might return:
-
-[source,js]
----------------
-{
-   [...]
-   "hits": {
-      "total": 1,
-      "max_score": 1,
-      "hits": [
-         {
-            "_index":     "my_index",
-            "_type":      "my_type",
-            "_id":        "1",
-            "_score":     1,
-            "_timestamp": 10000000, <1>
-            "fields": {
-              "foo" : [ "bar" ]
-            }
-         }
-      ]
-   }
-}
----------------
-<1> The `_timestamp` is returned by default, and at the top level.
-
-
-==== Script fields
-
-Script fields in 1.x were only returned as a single value. Even if the return
-value of a script was a list, it would be returned as an array containing an
-array:
-
-[source,js]
----------------
-"fields": {
-  "my_field": [
-    [
-      "v1",
-      "v2"
-    ]
-  ]
-}
----------------
-
-In elasticsearch 2.0, scripts that return a list of values are treated as
-multivalued fields. The same example would return the following response, with
-values in a single array.
-
-[source,js]
----------------
-"fields": {
-  "my_field": [
-    "v1",
-    "v2"
-  ]
-}
----------------
-
-==== Timezone for date field
-
-Specifying the `time_zone` parameter in queries or aggregations on fields of
-type `date` must now be either an ISO 8601 UTC offset, or a timezone id. For
-example, the value `+1:00` must now be written as `+01:00`.
-
-==== Only highlight queried fields
-
-The default value for the `require_field_match` option has changed from
-`false` to `true`, meaning that the highlighters will, by default, only take
-the fields that were queried into account.
-
-This means that, when querying the `_all` field, trying to highlight on any
-field other than `_all`  will produce no highlighted snippets. Querying the
-same fields that need to be highlighted is the cleaner solution to get
-highlighted snippets back. Otherwise `require_field_match` option can be set
-to `false` to ignore field names completely when highlighting.
-
-The postings highlighter doesn't support the `require_field_match` option
-anymore, it will only highlight fields that were queried.
-
-==== Postings highlighter doesn't support `match_phrase_prefix`
-
-The `match` query with type set to `phrase_prefix` (or the
-`match_phrase_prefix` query) is not supported by the postings highlighter. No
-highlighted snippets will be returned.
-
-
-
diff --git a/docs/reference/migration/migrate_2_0/settings.asciidoc b/docs/reference/migration/migrate_2_0/settings.asciidoc
deleted file mode 100644
index 06aa743a5d8..00000000000
--- a/docs/reference/migration/migrate_2_0/settings.asciidoc
+++ /dev/null
@@ -1,204 +0,0 @@
-[[breaking_20_setting_changes]]
-=== Setting changes
-
-==== Command line flags
-
-Command line flags using single dash notation must be now specified as the first arguments.
-For example if previously using:
-
-[source,sh]
----------------
-./elasticsearch --node.name=test_node -Des.path.conf=/opt/elasticsearch/conf/test_node
----------------
-
-This will now need to be changed to:
-
-[source,sh]
----------------
-./elasticsearch -Des.path.conf=/opt/elasticsearch/conf/test_node --node.name=test_node
----------------
-
-for the flag to take effect.
-
-[[migration-script-settings]]
-==== Scripting settings
-
-The `script.disable_dynamic` node setting has been replaced by fine-grained
-script settings described in the <>.
-The following setting previously used to enable dynamic or inline scripts:
-
-[source,yaml]
----------------
-script.disable_dynamic: false
----------------
-
-It should be replaced with the following two settings in `elasticsearch.yml` that
-achieve the same result:
-
-[source,yaml]
----------------
-script.inline: true
-script.indexed: true
----------------
-
-==== Units required for time and byte-sized settings
-
-Any settings which accept time or byte values must now be specified with
-units.  For instance, it is too easy to set the `refresh_interval` to 1
-*millisecond* instead of 1 second:
-
-[source,js]
----------------
-PUT _settings
-{
-  "index.refresh_interval": 1
-}
----------------
-
-In 2.0, the above request will throw an exception. Instead the refresh
-interval should be set to `"1s"` for one second.
-
-==== Merge and merge throttling settings
-
-The tiered merge policy is now the only supported merge policy. These settings
-have been removed:
-
-* `index.merge.policy.type`
-* `index.merge.policy.min_merge_size`
-* `index.merge.policy.max_merge_size`
-* `index.merge.policy.merge_factor`
-* `index.merge.policy.max_merge_docs`
-* `index.merge.policy.calibrate_size_by_deletes`
-* `index.merge.policy.min_merge_docs`
-* `index.merge.policy.max_merge_docs`
-
-Merge throttling now uses a feedback loop to auto-throttle.  These settings
-have been removed:
-
-* `indices.store.throttle.type`
-* `indices.store.throttle.max_bytes_per_sec`
-* `index.store.throttle.type`
-* `index.store.throttle.max_bytes_per_sec`
-
-==== Shadow replica settings
-
-The `node.enable_custom_paths` setting has been removed and replaced by the
-`path.shared_data` setting to allow shadow replicas with custom paths to work
-with the security manager. For example, if your previous configuration had:
-
-[source,yaml]
-------
-node.enable_custom_paths: true
-------
-
-And you created an index using shadow replicas with `index.data_path` set to
-`/opt/data/my_index` with the following:
-
-[source,js]
---------------------------------------------------
-PUT /my_index
-{
-  "index": {
-    "number_of_shards": 1,
-    "number_of_replicas": 4,
-    "data_path": "/opt/data/my_index",
-    "shadow_replicas": true
-  }
-}
---------------------------------------------------
-
-For 2.0, you will need to set `path.shared_data` to a parent directory of the
-index's data_path, so:
-
-[source,yaml]
------------
-path.shared_data: /opt/data
------------
-
-==== Resource watcher settings renamed
-
-The setting names for configuring the resource watcher have been renamed
-to prevent clashes with the watcher plugin
-
-* `watcher.enabled` is now `resource.reload.enabled`
-* `watcher.interval` is now `resource.reload.interval`
-* `watcher.interval.low` is now `resource.reload.interval.low`
-* `watcher.interval.medium` is now `resource.reload.interval.medium`
-* `watcher.interval.high` is now `resource.reload.interval.high`
-
-==== index.gateway setting renamed
-
-* `index.gateway.local.sync` is now `index.translog.sync_interval`
-
-==== Hunspell dictionary configuration
-
-The parameter `indices.analysis.hunspell.dictionary.location` has been
-removed, and `/hunspell` is always used.
-
-==== CORS allowed origins
-
-The CORS allowed origins setting, `http.cors.allow-origin`, no longer has a default value. Previously, the default value
-was `*`, which would allow CORS requests from any origin and is considered insecure. The `http.cors.allow-origin` setting
-should be specified with only the origins that should be allowed, like so:
-
-[source,yaml]
----------------
-http.cors.allow-origin: /https?:\/\/localhost(:[0-9]+)?/
----------------
-
-==== JSONP support
-
-JSONP callback support has now been removed. CORS should be used to access Elasticsearch
-over AJAX instead:
-
-[source,yaml]
----------------
-http.cors.enabled: true
-http.cors.allow-origin: /https?:\/\/localhost(:[0-9]+)?/
----------------
-
-==== In memory indices
-
-The `memory` / `ram` store (`index.store.type`) option was removed in
-Elasticsearch.  In-memory indices are no longer supported.
-
-==== Log messages truncated
-
-Log messages are now truncated at 10,000 characters. This can be changed in
-the `logging.yml` configuration file with the `file.layout.conversionPattern`
-setting.
-
-==== Custom config file
-
-It is no longer possible to specify a custom config file with the `CONF_FILE`
-environment variable, or the `-Des.config`, `-Des.default.config`, or
-`-Delasticsearch.config` parameters.
-
-Instead, the config file must be named `elasticsearch.yml` and must be located
-in the default `config/` directory, unless a custom config directory is specified.
-
-The location of a custom config directory may be specified as follows:
-
-[source,sh]
---------------
-./bin/elasticsearch --path.conf=/path/to/conf/dir
-./bin/elasticsearch-plugin -Des.path.conf=/path/to/conf/dir install analysis-icu
---------------
-
-When using the RPM or debian packages, the plugin script and the
-init/service scripts will consult the `CONF_DIR` environment variable
-to check for a custom config location.  The value of the `CONF_DIR`
-variable can be set in the environment config file which is located either in
-`/etc/default/elasticsearch` or `/etc/sysconfig/elasticsearch`.
-
-==== Custom analysis file paths
-
-It is no longer possible to set custom file path outside `CONF_DIR` for `*_path` settings
-in <> or <> filters.
-You must specify either relative path to `CONF_DIR` location or absolute path inside `CONF_DIR` location.
-
-==== `ES_CLASSPATH removed`
-
-The `ES_CLASSPATH` environment variable is no longer used to set the class
-path. External libraries should preferably be loaded using the plugin
-mechanism or, if you really must, be copied to the `lib/` directory.
diff --git a/docs/reference/migration/migrate_2_0/snapshot_restore.asciidoc b/docs/reference/migration/migrate_2_0/snapshot_restore.asciidoc
deleted file mode 100644
index c9b222abdc8..00000000000
--- a/docs/reference/migration/migrate_2_0/snapshot_restore.asciidoc
+++ /dev/null
@@ -1,38 +0,0 @@
-[[breaking_20_snapshot_and_restore_changes]]
-=== Snapshot and Restore changes
-
-==== File-system repositories must be whitelisted
-
-Locations of the shared file system repositories and the URL repositories with
-`file:` URLs now have to be registered before starting Elasticsearch using the
-`path.repo` setting. The `path.repo` setting can contain one or more
-repository locations:
-
-[source,yaml]
----------------
-path.repo: ["/mnt/daily", "/mnt/weekly"]
----------------
-
-If the repository location is specified as an absolute path it has to start
-with one of the locations specified in `path.repo`. If the location is
-specified as a relative path, it will be resolved against the first location
-specified in the `path.repo` setting.
-
-==== URL repositories must be whitelisted
-
-URL repositories with `http:`, `https:`, and `ftp:` URLs have to be
-whitelisted before starting Elasticsearch with the
-`repositories.url.allowed_urls` setting. This setting supports wildcards in
-the place of host, path, query, and fragment. For example:
-
-[source,yaml]
------------------------------------
-repositories.url.allowed_urls: ["http://www.example.org/root/*", "https://*.mydomain.com/*?*#*"]
------------------------------------
-
-==== Wildcard expansion
-
-The obsolete parameters `expand_wildcards_open` and `expand_wildcards_close`
-are no longer supported by the snapshot and restore operations. These
-parameters have been replaced by a single `expand_wildcards` parameter. See
-<> for more.
diff --git a/docs/reference/migration/migrate_2_0/stats.asciidoc b/docs/reference/migration/migrate_2_0/stats.asciidoc
deleted file mode 100644
index dc80ecd83ec..00000000000
--- a/docs/reference/migration/migrate_2_0/stats.asciidoc
+++ /dev/null
@@ -1,52 +0,0 @@
-[[breaking_20_stats_info_and_literal_cat_literal_changes]]
-=== Stats, info, and `cat` changes
-
-==== Sigar removed
-
-We no longer ship the Sigar library for operating system dependent statistics,
-as it no longer seems to be maintained.  Instead, we rely on the statistics
-provided by the JVM.  This has resulted in a number of changes to the node
-info, and node stats responses:
-
-* `network.*` has been removed from nodes info and nodes stats.
-* `fs.*.dev` and `fs.*.disk*` have been removed from nodes stats.
-* `os.*` has been removed from nodes stats, except for `os.timestamp`,
-  `os.load_average`, `os.mem.*`, and `os.swap.*`.
-* `os.mem.total` and `os.swap.total` have been removed from nodes info.
-* `process.mem.resident` and `process.mem.share` have been removed from node stats.
-
-==== Removed `id_cache` from stats apis
-
-Removed `id_cache` metric from nodes stats, indices stats and cluster stats
-apis. This metric has also been removed from the shards cat, indices cat and
-nodes cat apis. Parent/child memory is now reported under fielddata, because
-it has internally be using fielddata for a while now.
-
-To just see how much parent/child related field data is taking, the
-`fielddata_fields` option can be used on the stats apis. Indices stats
-example:
-
-[source,js]
---------------------------------------------------
-GET /_stats/fielddata?fielddata_fields=_parent
---------------------------------------------------
-
-==== Percolator stats
-
-The total time spent running percolator queries is now called `percolate.time`
-instead of `percolate.get_time`.
-
-==== Cluster state REST API
-
-The cluster state API doesn't return the `routing_nodes` section anymore when
-`routing_table` is requested. The newly introduced `routing_nodes` flag can be
-used separately to control whether `routing_nodes` should be returned.
-
-==== Index status API
-
-The deprecated index status API has been removed.
-
-==== Nodes Stats API
-
-Queue lengths are now reported as basic numeric so they can easily processed by code. Before we used a human
-readable format. For example, a queue with 1,000 items is now reported as `1000` instead of `1k`.
diff --git a/docs/reference/migration/migrate_2_0/striping.asciidoc b/docs/reference/migration/migrate_2_0/striping.asciidoc
deleted file mode 100644
index 2e80f29c774..00000000000
--- a/docs/reference/migration/migrate_2_0/striping.asciidoc
+++ /dev/null
@@ -1,21 +0,0 @@
-[[breaking_20_multiple_literal_data_path_literal_striping]]
-=== Multiple `path.data` striping
-
-Previously, if the `path.data` setting listed multiple data paths, then a
-shard would be ``striped'' across all paths by writing a whole file to each
-path in turn (in accordance with the `index.store.distributor` setting).  The
-result was that files from a single segment in a shard could be spread across
-multiple disks, and the failure of any one disk could corrupt multiple shards.
-
-This striping is no longer supported.  Instead, different shards may be
-allocated to different paths, but all of the files in a single shard will be
-written to the same path.
-
-If striping is detected while starting Elasticsearch 2.0.0 or later, *all of
-the files belonging to the same shard will be migrated to the same path*. If
-there is not enough disk space to complete this migration, the upgrade will be
-cancelled and can only be resumed once enough disk space is made available.
-
-The `index.store.distributor` setting has also been removed.
-
-
diff --git a/docs/reference/migration/migrate_2_1.asciidoc b/docs/reference/migration/migrate_2_1.asciidoc
deleted file mode 100644
index 454a57f96bc..00000000000
--- a/docs/reference/migration/migrate_2_1.asciidoc
+++ /dev/null
@@ -1,87 +0,0 @@
-[[breaking-changes-2.1]]
-== Breaking changes in 2.1
-
-This section discusses the changes that you need to be aware of when migrating
-your application to Elasticsearch 2.1.
-
-* <>
-* <>
-* <>
-* <>
-* <>
-* <>
-
-[[breaking_21_search_changes]]
-=== Search changes
-
-==== `search_type=scan` deprecated
-
-The `scan` search type has been deprecated. All benefits from this search
-type can now be achieved by doing a scroll request that sorts documents in
-`_doc` order, for instance:
-
-[source,sh]
----------------
-GET /my_index/_search?scroll=2m
-{
-  "sort": [
-    "_doc"
-  ]
-}
----------------
-
-Scroll requests sorted by `_doc` have been optimized to more efficiently resume
-from where the previous request stopped, so this will have the same performance
-characteristics as the former `scan` search type.
-
-==== from + size limits
-
-Elasticsearch will now return an error message if a query's `from` + `size` is
-more than the `index.max_result_window` parameter. This parameter defaults to
-10,000 which is safe for almost all clusters. Values higher than can consume
-significant chunks of heap memory per search and per shard executing the
-search. It's safest to leave this value as it is an use the scroll api for any
-deep scrolling but this setting is dynamic so it can raised or lowered as
-needed.
-
-[[breaking_21_update_changes]]
-=== Update changes
-
-==== Updates now `detect_noop` by default
-
-We've switched the default value of the `detect_noop` option from `false` to
-`true`. This means that Elasticsearch will ignore updates that don't change
-source unless you explicitly set `"detect_noop": false`. `detect_noop` was
-always computationally cheap compared to the expense of the update which can be
-thought of as a delete operation followed by an index operation.
-
-[[breaking_21_removed_features]]
-=== Removed features
-
-==== `indices.fielddata.cache.expire`
-
-The experimental feature `indices.fielddata.cache.expire` has been removed.
-For indices that have this setting configured, this config will be ignored.
-
-[[breaking_21_more_like_this]]
-=== More Like This
-
-The MoreLikeThisQueryBuilder#ignoreLike methods have been deprecated in favor
-of using the unlike methods.
-
-MoreLikeThisBuilder#addItem has been deprecated in favor of using
-MoreLikeThisBuilder#addLikeItem.
-
-[[breaking_21_nested_sorting]]
-=== Nested sorting
-
-If sorting on field inside a nested object then the `nested_path` should be specified.
-Before there was an attempt to resolve the nested path automatically, but that was sometimes incorrect.
-To avoid confusion the `nested_path` should always be specified.
-
-[[breaking_21_index_apis]]
-=== Index APIs
-
-==== Optimize API
-
-The Optimize API has been deprecated, all new optimize actions should use the new Force Merge API.
diff --git a/docs/reference/migration/migrate_2_2.asciidoc b/docs/reference/migration/migrate_2_2.asciidoc
deleted file mode 100644
index d6035c83b8a..00000000000
--- a/docs/reference/migration/migrate_2_2.asciidoc
+++ /dev/null
@@ -1,80 +0,0 @@
-[[breaking-changes-2.2]]
-== Breaking changes in 2.2
-
-This section discusses the changes that you need to be aware of when migrating
-your application to Elasticsearch 2.2.
-
-[[float]]
-=== Mapping APIs
-
-==== Geo Point Type
-
-The `geo_point` format has been changed to reduce index size and the time required to both index and query
-geo point data. To make these performance improvements possible both `doc_values` and `coerce` are required
-and therefore cannot be changed. For this reason the `doc_values` and `coerce` parameters have been removed
-from the <> field mapping.
-
-[float]
-=== Scripting and security
-
-The Java Security Manager is being used to lock down the privileges available
-to the scripting languages and to restrict the classes they are allowed to
-load to a predefined whitelist.  These changes may cause scripts which worked
-in earlier versions to fail.  See <> for more
-details.
-
-[float]
-=== Field stats API
-
-The field stats' response format has been changed for number based and date
-fields. The `min_value` and `max_value` elements now return values as number
-and the new `min_value_as_string` and `max_value_as_string` return the values
-as string.
-
-[float]
-=== Default logging using systemd
-
-In previous versions of Elasticsearch using systemd, the default logging
-configuration routed standard output to `/dev/null` and standard error to
-the journal. However, there are often critical error messages at
-startup that are logged to standard output rather than standard error
-and these error messages would be lost to the ether. The default has
-changed to now route standard output to the journal and standard error
-to inherit this setting (these are the defaults for systemd). These
-settings can be modified by editing the `elasticsearch.service` file.
-
-[float]
-=== Java Client
-
-Previously it was possible to iterate over `ClusterHealthResponse` to get information about `ClusterIndexHealth`.
-While this is still possible, it requires now iterating over the values returned from `getIndices()`:
-
-[source,java]
----------------
-ClusterHealthResponse clusterHealthResponse = client.admin().cluster().prepareHealth().get();
-for (Map.Entry index : clusterHealthResponse.getIndices().entrySet()) {
-    String indexName = index.getKey();
-    ClusterIndexHealth health = index.getValue();
-}
----------------
-
-[float]
-=== Cloud AWS Plugin
-
-Proxy settings have been deprecated and renamed:
-
-* from `cloud.aws.proxy_host` to `cloud.aws.proxy.host`
-* from `cloud.aws.ec2.proxy_host` to `cloud.aws.ec2.proxy.host`
-* from `cloud.aws.s3.proxy_host` to `cloud.aws.s3.proxy.host`
-* from `cloud.aws.proxy_port` to `cloud.aws.proxy.port`
-* from `cloud.aws.ec2.proxy_port` to `cloud.aws.ec2.proxy.port`
-* from `cloud.aws.s3.proxy_port` to `cloud.aws.s3.proxy.port`
-
-If you are using proxy settings, update your settings as deprecated ones will
-be removed in next major version.
-
-[float]
-=== Multicast plugin deprecated
-
-The `discovery-multicast` plugin has been deprecated in 2.2.0 and has
-been removed in 3.0.0.
diff --git a/docs/reference/migration/migrate_2_3.asciidoc b/docs/reference/migration/migrate_2_3.asciidoc
deleted file mode 100644
index 0d741e2adb2..00000000000
--- a/docs/reference/migration/migrate_2_3.asciidoc
+++ /dev/null
@@ -1,19 +0,0 @@
-[[breaking-changes-2.3]]
-== Breaking changes in 2.3
-
-This section discusses the changes that you need to be aware of when migrating
-your application to Elasticsearch 2.3.
-
-* <>
-
-[[breaking_23_index_apis]]
-=== Mappings
-
-==== Limit to the number of `nested` fields
-
-Indexing a document with 100 nested fields actually indexes 101 documents as each nested
-document is indexed as a separate document. To safeguard against ill-defined mappings
-the number of nested fields that can be defined per index has been limited to 50.
-This default limit can be changed with the index setting `index.mapping.nested_fields.limit`.
-Note that the limit is only checked when new indices are created or mappings are updated. It
-will thus only affect existing pre-2.3 indices if their mapping is changed.

From e472d7894bd6b26000b60afa5aeb4b7e8f1a6375 Mon Sep 17 00:00:00 2001
From: Boaz Leskes 
Date: Fri, 12 Feb 2016 10:18:22 +0100
Subject: [PATCH 42/49] Log suppressed stack traces under DEBUG

To make API's output more easy to read we are suppressing stack traces (#12991) unless explicitly requested by setting `error_trace=true` on the request. To compensate we are logging the stacktrace into the logs so people can look it up even the error_trace wasn't enabled. Currently we do so using the `INFO` level which can be verbose if an api is called repeatedly by some automation.  For example, if someone tries to read from an index that doesn't exist we will respond with a 404 exception and log under info every time. We should reduce the level to `DEBUG` as we do with other API driven errors. Internal errors (rest codes >=500) are logged as WARN.

Closes #16627
---
 .../main/java/org/elasticsearch/rest/BytesRestResponse.java | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/elasticsearch/rest/BytesRestResponse.java b/core/src/main/java/org/elasticsearch/rest/BytesRestResponse.java
index ac8eadade0b..52f624849fc 100644
--- a/core/src/main/java/org/elasticsearch/rest/BytesRestResponse.java
+++ b/core/src/main/java/org/elasticsearch/rest/BytesRestResponse.java
@@ -126,7 +126,11 @@ public class BytesRestResponse extends RestResponse {
             if (channel.request().paramAsBoolean("error_trace", !ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT)) {
                 params =  new ToXContent.DelegatingMapParams(Collections.singletonMap(ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE, "false"), channel.request());
             } else {
-                SUPPRESSED_ERROR_LOGGER.info("{} Params: {}", t, channel.request().path(), channel.request().params());
+                if (status.getStatus() < 500) {
+                    SUPPRESSED_ERROR_LOGGER.debug("{} Params: {}", t, channel.request().path(), channel.request().params());
+                } else {
+                    SUPPRESSED_ERROR_LOGGER.warn("{} Params: {}", t, channel.request().path(), channel.request().params());
+                }
                 params = channel.request();
             }
             builder.field("error");

From 4353b2e024fe8523678ed1072f2b92a4ed1e3618 Mon Sep 17 00:00:00 2001
From: Jason Tedor 
Date: Sun, 13 Mar 2016 15:49:49 -0400
Subject: [PATCH 43/49] Do not pass double-dash arguments on startup

This commit addresses an issue in the init scripts which are passing
invalid command line arguments to the startup script.

Closes #17087
---
 distribution/deb/src/main/packaging/init.d/elasticsearch | 2 +-
 distribution/rpm/src/main/packaging/init.d/elasticsearch | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/distribution/deb/src/main/packaging/init.d/elasticsearch b/distribution/deb/src/main/packaging/init.d/elasticsearch
index d0ad04cef7a..078e79a92d1 100755
--- a/distribution/deb/src/main/packaging/init.d/elasticsearch
+++ b/distribution/deb/src/main/packaging/init.d/elasticsearch
@@ -99,7 +99,7 @@ fi
 # Define other required variables
 PID_FILE="$PID_DIR/$NAME.pid"
 DAEMON=$ES_HOME/bin/elasticsearch
-DAEMON_OPTS="-d -p $PID_FILE --default.path.home=$ES_HOME --default.path.logs=$LOG_DIR --default.path.data=$DATA_DIR --default.path.conf=$CONF_DIR"
+DAEMON_OPTS="-d -p $PID_FILE -D es.default.path.home=$ES_HOME -D es.default.path.logs=$LOG_DIR -D es.default.path.data=$DATA_DIR -D es.default.path.conf=$CONF_DIR"
 
 export ES_HEAP_SIZE
 export ES_HEAP_NEWSIZE
diff --git a/distribution/rpm/src/main/packaging/init.d/elasticsearch b/distribution/rpm/src/main/packaging/init.d/elasticsearch
index c56944b7c3c..1132fca4f9e 100644
--- a/distribution/rpm/src/main/packaging/init.d/elasticsearch
+++ b/distribution/rpm/src/main/packaging/init.d/elasticsearch
@@ -117,7 +117,7 @@ start() {
     cd $ES_HOME
     echo -n $"Starting $prog: "
     # if not running, start it up here, usually something like "daemon $exec"
-    daemon --user $ES_USER --pidfile $pidfile $exec -p $pidfile -d -Des.default.path.home=$ES_HOME -Des.default.path.logs=$LOG_DIR -Des.default.path.data=$DATA_DIR -Des.default.path.conf=$CONF_DIR
+    daemon --user $ES_USER --pidfile $pidfile $exec -p $pidfile -d -D es.default.path.home=$ES_HOME -D es.default.path.logs=$LOG_DIR -D es.default.path.data=$DATA_DIR -D es.default.path.conf=$CONF_DIR
     retval=$?
     echo
     [ $retval -eq 0 ] && touch $lockfile

From 8ac5a98b87c377e97174f7a279a2f103f458b67d Mon Sep 17 00:00:00 2001
From: Jason Tedor 
Date: Sun, 13 Mar 2016 19:12:06 -0400
Subject: [PATCH 44/49] Remove links to nonexistent migration docs

---
 docs/reference/migration/index.asciidoc | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/docs/reference/migration/index.asciidoc b/docs/reference/migration/index.asciidoc
index 57401cb01d7..f8d742b3b67 100644
--- a/docs/reference/migration/index.asciidoc
+++ b/docs/reference/migration/index.asciidoc
@@ -17,17 +17,3 @@ As a general rule:
 See <> for more info.
 --
 include::migrate_5_0.asciidoc[]
-
-include::migrate_2_3.asciidoc[]
-
-include::migrate_2_2.asciidoc[]
-
-include::migrate_2_1.asciidoc[]
-
-include::migrate_2_0.asciidoc[]
-
-include::migrate_1_6.asciidoc[]
-
-include::migrate_1_4.asciidoc[]
-
-include::migrate_1_0.asciidoc[]

From 5596e310684c2e540d932c91690cf73a3b083465 Mon Sep 17 00:00:00 2001
From: Adrien Grand 
Date: Fri, 11 Mar 2016 17:21:36 +0100
Subject: [PATCH 45/49] Upgrade to lucene-6.0.0-f0aa4fc. #17075

---
 buildSrc/version.properties                           |  2 +-
 .../lucene/queryparser/classic/MapperQueryParser.java |  5 +++--
 .../search/vectorhighlight/CustomFieldQuery.java      | 11 +++++------
 .../common/lucene/search/MultiPhrasePrefixQuery.java  |  4 ++--
 .../org/elasticsearch/index/search/MatchQuery.java    |  7 +++----
 .../org/elasticsearch/bootstrap/security.policy       |  2 +-
 .../org/elasticsearch/bootstrap/test-framework.policy |  2 +-
 .../fieldcomparator/ReplaceMissingTests.java          |  2 +-
 .../search/child/ChildQuerySearchIT.java              |  6 +++---
 ...e-analyzers-common-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...e-analyzers-common-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...ne-backward-codecs-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...ne-backward-codecs-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 .../lucene-core-6.0.0-snapshot-bea235f.jar.sha1       |  1 -
 .../lucene-core-6.0.0-snapshot-f0aa4fc.jar.sha1       |  1 +
 .../lucene-grouping-6.0.0-snapshot-bea235f.jar.sha1   |  1 -
 .../lucene-grouping-6.0.0-snapshot-f0aa4fc.jar.sha1   |  1 +
 ...lucene-highlighter-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...lucene-highlighter-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 .../lucene-join-6.0.0-snapshot-bea235f.jar.sha1       |  1 -
 .../lucene-join-6.0.0-snapshot-f0aa4fc.jar.sha1       |  1 +
 .../lucene-memory-6.0.0-snapshot-bea235f.jar.sha1     |  1 -
 .../lucene-memory-6.0.0-snapshot-f0aa4fc.jar.sha1     |  1 +
 .../lucene-misc-6.0.0-snapshot-bea235f.jar.sha1       |  1 -
 .../lucene-misc-6.0.0-snapshot-f0aa4fc.jar.sha1       |  1 +
 .../lucene-queries-6.0.0-snapshot-bea235f.jar.sha1    |  1 -
 .../lucene-queries-6.0.0-snapshot-f0aa4fc.jar.sha1    |  1 +
 ...lucene-queryparser-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...lucene-queryparser-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 .../lucene-sandbox-6.0.0-snapshot-bea235f.jar.sha1    |  1 -
 .../lucene-sandbox-6.0.0-snapshot-f0aa4fc.jar.sha1    |  1 +
 .../lucene-spatial-6.0.0-snapshot-bea235f.jar.sha1    |  1 -
 .../lucene-spatial-6.0.0-snapshot-f0aa4fc.jar.sha1    |  1 +
 ...ene-spatial-extras-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...ene-spatial-extras-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 .../lucene-spatial3d-6.0.0-snapshot-bea235f.jar.sha1  |  1 -
 .../lucene-spatial3d-6.0.0-snapshot-f0aa4fc.jar.sha1  |  1 +
 .../lucene-suggest-6.0.0-snapshot-bea235f.jar.sha1    |  1 -
 .../lucene-suggest-6.0.0-snapshot-f0aa4fc.jar.sha1    |  1 +
 ...lucene-expressions-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...lucene-expressions-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...cene-analyzers-icu-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...cene-analyzers-icu-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...analyzers-kuromoji-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...analyzers-kuromoji-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...analyzers-phonetic-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...analyzers-phonetic-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...-analyzers-smartcn-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...-analyzers-smartcn-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 ...-analyzers-stempel-6.0.0-snapshot-bea235f.jar.sha1 |  1 -
 ...-analyzers-stempel-6.0.0-snapshot-f0aa4fc.jar.sha1 |  1 +
 51 files changed, 41 insertions(+), 42 deletions(-)
 delete mode 100644 distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-core-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-core-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-grouping-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-grouping-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-highlighter-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-highlighter-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-join-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-join-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-memory-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-memory-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-misc-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-misc-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-queries-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-queries-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-queryparser-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-queryparser-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-sandbox-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-sandbox-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-spatial-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-spatial-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-spatial3d-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-spatial3d-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 distribution/licenses/lucene-suggest-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 distribution/licenses/lucene-suggest-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-f0aa4fc.jar.sha1
 delete mode 100644 plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-bea235f.jar.sha1
 create mode 100644 plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-f0aa4fc.jar.sha1

diff --git a/buildSrc/version.properties b/buildSrc/version.properties
index f75d5a936bb..39c32192052 100644
--- a/buildSrc/version.properties
+++ b/buildSrc/version.properties
@@ -1,5 +1,5 @@
 elasticsearch     = 5.0.0
-lucene            = 6.0.0-snapshot-bea235f
+lucene            = 6.0.0-snapshot-f0aa4fc
 
 # optional dependencies
 spatial4j         = 0.6
diff --git a/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java b/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java
index a7c53a56bc4..6ddd7591caa 100644
--- a/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java
+++ b/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java
@@ -787,8 +787,9 @@ public class MapperQueryParser extends QueryParser {
             assert q instanceof BoostQuery == false;
             return pq;
         } else if (q instanceof MultiPhraseQuery) {
-            ((MultiPhraseQuery) q).setSlop(slop);
-            return q;
+            MultiPhraseQuery.Builder builder = new MultiPhraseQuery.Builder((MultiPhraseQuery) q);
+            builder.setSlop(slop);
+            return builder.build();
         } else {
             return q;
         }
diff --git a/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java b/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
index 089b649cefe..3c0bda97347 100644
--- a/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
+++ b/core/src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java
@@ -34,7 +34,6 @@ import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
 
 import java.io.IOException;
 import java.util.Collection;
-import java.util.List;
 
 /**
  *
@@ -68,7 +67,7 @@ public class CustomFieldQuery extends FieldQuery {
             flatten(((FiltersFunctionScoreQuery) sourceQuery).getSubQuery(), reader, flatQueries, boost);
         } else if (sourceQuery instanceof MultiPhraseQuery) {
             MultiPhraseQuery q = ((MultiPhraseQuery) sourceQuery);
-            convertMultiPhraseQuery(0, new int[q.getTermArrays().size()], q, q.getTermArrays(), q.getPositions(), reader, flatQueries);
+            convertMultiPhraseQuery(0, new int[q.getTermArrays().length], q, q.getTermArrays(), q.getPositions(), reader, flatQueries);
         } else if (sourceQuery instanceof BlendedTermQuery) {
             final BlendedTermQuery blendedTermQuery = (BlendedTermQuery) sourceQuery;
             flatten(blendedTermQuery.rewrite(reader), reader, flatQueries, boost);
@@ -77,7 +76,7 @@ public class CustomFieldQuery extends FieldQuery {
         }
     }
 
-    private void convertMultiPhraseQuery(int currentPos, int[] termsIdx, MultiPhraseQuery orig, List terms, int[] pos, IndexReader reader, Collection flatQueries) throws IOException {
+    private void convertMultiPhraseQuery(int currentPos, int[] termsIdx, MultiPhraseQuery orig, Term[][] terms, int[] pos, IndexReader reader, Collection flatQueries) throws IOException {
         if (currentPos == 0) {
             // if we have more than 16 terms
             int numTerms = 0;
@@ -97,16 +96,16 @@ public class CustomFieldQuery extends FieldQuery {
          * we walk all possible ways and for each path down the MPQ we create a PhraseQuery this is what FieldQuery supports.
          * It seems expensive but most queries will pretty small.
          */
-        if (currentPos == terms.size()) {
+        if (currentPos == terms.length) {
             PhraseQuery.Builder queryBuilder = new PhraseQuery.Builder();
             queryBuilder.setSlop(orig.getSlop());
             for (int i = 0; i < termsIdx.length; i++) {
-                queryBuilder.add(terms.get(i)[termsIdx[i]], pos[i]);
+                queryBuilder.add(terms[i][termsIdx[i]], pos[i]);
             }
             Query query = queryBuilder.build();
             this.flatten(query, reader, flatQueries, 1F);
         } else {
-            Term[] t = terms.get(currentPos);
+            Term[] t = terms[currentPos];
             for (int i = 0; i < t.length; i++) {
                 termsIdx[currentPos] = i;
                 convertMultiPhraseQuery(currentPos+1, termsIdx, orig, terms, pos, reader, flatQueries);
diff --git a/core/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java b/core/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java
index 754d76fed27..52de9a7e5db 100644
--- a/core/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java
+++ b/core/src/main/java/org/elasticsearch/common/lucene/search/MultiPhrasePrefixQuery.java
@@ -134,7 +134,7 @@ public class MultiPhrasePrefixQuery extends Query {
         if (termArrays.isEmpty()) {
             return new MatchNoDocsQuery();
         }
-        MultiPhraseQuery query = new MultiPhraseQuery();
+        MultiPhraseQuery.Builder query = new MultiPhraseQuery.Builder();
         query.setSlop(slop);
         int sizeMinus1 = termArrays.size() - 1;
         for (int i = 0; i < sizeMinus1; i++) {
@@ -153,7 +153,7 @@ public class MultiPhrasePrefixQuery extends Query {
             return Queries.newMatchNoDocsQuery();
         }
         query.add(terms.toArray(Term.class), position);
-        return query.rewrite(reader);
+        return query.build();
     }
 
     private void getPrefixTerms(ObjectHashSet terms, final Term prefix, final IndexReader reader) throws IOException {
diff --git a/core/src/main/java/org/elasticsearch/index/search/MatchQuery.java b/core/src/main/java/org/elasticsearch/index/search/MatchQuery.java
index 979bfba605f..9cd587704cb 100644
--- a/core/src/main/java/org/elasticsearch/index/search/MatchQuery.java
+++ b/core/src/main/java/org/elasticsearch/index/search/MatchQuery.java
@@ -45,7 +45,6 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.index.query.support.QueryParsers;
 
 import java.io.IOException;
-import java.util.List;
 
 public class MatchQuery {
 
@@ -336,10 +335,10 @@ public class MatchQuery {
                 return prefixQuery;
             } else if (query instanceof MultiPhraseQuery) {
                 MultiPhraseQuery pq = (MultiPhraseQuery)query;
-                List terms = pq.getTermArrays();
+                Term[][] terms = pq.getTermArrays();
                 int[] positions = pq.getPositions();
-                for (int i = 0; i < terms.size(); i++) {
-                    prefixQuery.add(terms.get(i), positions[i]);
+                for (int i = 0; i < terms.length; i++) {
+                    prefixQuery.add(terms[i], positions[i]);
                 }
                 return prefixQuery;
             } else if (query instanceof TermQuery) {
diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/security.policy b/core/src/main/resources/org/elasticsearch/bootstrap/security.policy
index 4909959015b..3e8bdbb0ad4 100644
--- a/core/src/main/resources/org/elasticsearch/bootstrap/security.policy
+++ b/core/src/main/resources/org/elasticsearch/bootstrap/security.policy
@@ -31,7 +31,7 @@ grant codeBase "${codebase.securesm-1.0.jar}" {
 //// Very special jar permissions:
 //// These are dangerous permissions that we don't want to grant to everything.
 
-grant codeBase "${codebase.lucene-core-6.0.0-snapshot-bea235f.jar}" {
+grant codeBase "${codebase.lucene-core-6.0.0-snapshot-f0aa4fc.jar}" {
   // needed to allow MMapDirectory's "unmap hack" (die unmap hack, die)
   // java 8 package
   permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy b/core/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy
index fafa57118c2..8d56bc44b9a 100644
--- a/core/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy
+++ b/core/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy
@@ -31,7 +31,7 @@ grant codeBase "${codebase.securemock-1.2.jar}" {
   permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 };
 
-grant codeBase "${codebase.lucene-test-framework-6.0.0-snapshot-bea235f.jar}" {
+grant codeBase "${codebase.lucene-test-framework-6.0.0-snapshot-f0aa4fc.jar}" {
   // needed by RamUsageTester
   permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 };
diff --git a/core/src/test/java/org/elasticsearch/index/fielddata/fieldcomparator/ReplaceMissingTests.java b/core/src/test/java/org/elasticsearch/index/fielddata/fieldcomparator/ReplaceMissingTests.java
index 63b66f47d1a..a291311c3bc 100644
--- a/core/src/test/java/org/elasticsearch/index/fielddata/fieldcomparator/ReplaceMissingTests.java
+++ b/core/src/test/java/org/elasticsearch/index/fielddata/fieldcomparator/ReplaceMissingTests.java
@@ -52,7 +52,7 @@ public class ReplaceMissingTests extends ESTestCase {
         iw.close();
 
         DirectoryReader reader = DirectoryReader.open(dir);
-        LeafReader ar = getOnlySegmentReader(reader);
+        LeafReader ar = getOnlyLeafReader(reader);
         SortedDocValues raw = ar.getSortedDocValues("field");
         assertEquals(2, raw.getValueCount());
 
diff --git a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java b/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
index 9440a3e91c1..8aa4e017da9 100644
--- a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
+++ b/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
@@ -576,20 +576,20 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
                 .setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode(ScoreMode.Max))
                 .get();
         assertHitCount(searchResponse, 1L);
-        assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), equalTo("Score based on join value p1"));
+        assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), containsString("join value p1"));
 
         searchResponse = client().prepareSearch("test")
                 .setExplain(true)
                 .setQuery(hasParentQuery("parent", termQuery("p_field", "1")).score(true))
                 .get();
         assertHitCount(searchResponse, 1L);
-        assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), equalTo("Score based on join value p1"));
+        assertThat(searchResponse.getHits().getAt(0).explanation().getDescription(), containsString("join value p1"));
 
         ExplainResponse explainResponse = client().prepareExplain("test", "parent", parentId)
                 .setQuery(hasChildQuery("child", termQuery("c_field", "1")).scoreMode(ScoreMode.Max))
                 .get();
         assertThat(explainResponse.isExists(), equalTo(true));
-        assertThat(explainResponse.getExplanation().getDetails()[0].getDescription(), equalTo("Score based on join value p1"));
+        assertThat(explainResponse.getExplanation().getDetails()[0].getDescription(), containsString("join value p1"));
     }
 
     List createDocBuilders() {
diff --git a/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 74d21bae946..00000000000
--- a/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-3510af19947deadd929123aaf14d69b4bdec759a
\ No newline at end of file
diff --git a/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..2ed6eb6ef56
--- /dev/null
+++ b/distribution/licenses/lucene-analyzers-common-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+cd2388adc4b33c7530bbb8cd386e5c8c5c8e6aca
\ No newline at end of file
diff --git a/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index ee6143bec14..00000000000
--- a/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-247ad7c17cb7c742d7a9abd5d9980e4fab815178
\ No newline at end of file
diff --git a/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..28cdb1db9b1
--- /dev/null
+++ b/distribution/licenses/lucene-backward-codecs-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+f5bbdd01b98fab7c18b46e762de3e39221b0c8fc
\ No newline at end of file
diff --git a/distribution/licenses/lucene-core-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-core-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 2d39f84d21e..00000000000
--- a/distribution/licenses/lucene-core-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-c0712dbec58abad545646edab67d58f7373f5329
\ No newline at end of file
diff --git a/distribution/licenses/lucene-core-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-core-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..c304106975b
--- /dev/null
+++ b/distribution/licenses/lucene-core-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+18ad74518b34af7cfbd6c1e3a408920ff7665501
\ No newline at end of file
diff --git a/distribution/licenses/lucene-grouping-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-grouping-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index a3ce82c8a04..00000000000
--- a/distribution/licenses/lucene-grouping-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-7573e3efb12dd16fdc991edaf408877dab20c030
\ No newline at end of file
diff --git a/distribution/licenses/lucene-grouping-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-grouping-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..a95cc29cc7d
--- /dev/null
+++ b/distribution/licenses/lucene-grouping-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+dc0b211e31b8f1e0ee3a9e8f9c71b13fa088dabf
\ No newline at end of file
diff --git a/distribution/licenses/lucene-highlighter-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-highlighter-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 9259a2c66c1..00000000000
--- a/distribution/licenses/lucene-highlighter-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-96ef0a9a43a5fc99d27bb7e7d61517ee4c7e54a4
\ No newline at end of file
diff --git a/distribution/licenses/lucene-highlighter-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-highlighter-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..8f57bb02639
--- /dev/null
+++ b/distribution/licenses/lucene-highlighter-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+bbd503396c08546f1b9e023e77dbf25bbb052d1c
\ No newline at end of file
diff --git a/distribution/licenses/lucene-join-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-join-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 4959f5f163c..00000000000
--- a/distribution/licenses/lucene-join-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d93de34947d37e31a337cdfed400333588c378d8
\ No newline at end of file
diff --git a/distribution/licenses/lucene-join-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-join-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..835bac49233
--- /dev/null
+++ b/distribution/licenses/lucene-join-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+96fd93d4a4192c42b0d56198b73a25440d4db2f7
\ No newline at end of file
diff --git a/distribution/licenses/lucene-memory-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-memory-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 5218d0a019e..00000000000
--- a/distribution/licenses/lucene-memory-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-9c292930b1828e68f06509944a5346c141d56fd4
\ No newline at end of file
diff --git a/distribution/licenses/lucene-memory-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-memory-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..1e392d3e246
--- /dev/null
+++ b/distribution/licenses/lucene-memory-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+ddd44a319d201ff73cd25be139bd3175226ab5a5
\ No newline at end of file
diff --git a/distribution/licenses/lucene-misc-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-misc-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 947722edfd3..00000000000
--- a/distribution/licenses/lucene-misc-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-866ed93f48683e877ffa4d9baa1323dcffbc65d7
\ No newline at end of file
diff --git a/distribution/licenses/lucene-misc-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-misc-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..a21aaef33f5
--- /dev/null
+++ b/distribution/licenses/lucene-misc-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+07d943ecdc552632bdca8f2772fd081a02cbf589
\ No newline at end of file
diff --git a/distribution/licenses/lucene-queries-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-queries-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 6caf86a6b96..00000000000
--- a/distribution/licenses/lucene-queries-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-967d9c2647bdd4d88961747f7436a5a92aa0385b
\ No newline at end of file
diff --git a/distribution/licenses/lucene-queries-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-queries-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..57fb022de53
--- /dev/null
+++ b/distribution/licenses/lucene-queries-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+66c72fd979f54480af75d01719ef25da62c0a8b6
\ No newline at end of file
diff --git a/distribution/licenses/lucene-queryparser-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-queryparser-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index b3e92d3f168..00000000000
--- a/distribution/licenses/lucene-queryparser-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-981030d83a7504267f3141d7365fad9b46d51465
\ No newline at end of file
diff --git a/distribution/licenses/lucene-queryparser-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-queryparser-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..5c311c4bd9b
--- /dev/null
+++ b/distribution/licenses/lucene-queryparser-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+8992204f922fe52af557e691cbfb4c54f92b76bd
\ No newline at end of file
diff --git a/distribution/licenses/lucene-sandbox-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-sandbox-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 7b5176c4963..00000000000
--- a/distribution/licenses/lucene-sandbox-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-707691b1baf22c29020569f5b875d200a4955411
\ No newline at end of file
diff --git a/distribution/licenses/lucene-sandbox-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-sandbox-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..20f0037ea31
--- /dev/null
+++ b/distribution/licenses/lucene-sandbox-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+8565264e00bc43e1226ff0d2e986dbb26d353ce2
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-spatial-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 9df2a16b886..00000000000
--- a/distribution/licenses/lucene-spatial-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-be9e78130a069983f611f484d5b7b87bda0d6370
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-spatial-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..6a909857945
--- /dev/null
+++ b/distribution/licenses/lucene-spatial-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+98fc1bb7e005f33c388be66486341ad8168b72eb
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 6badc36d361..00000000000
--- a/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-edeef6ce8a58d5e6a074bebf545918d04e8579e1
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..b741ccd62a7
--- /dev/null
+++ b/distribution/licenses/lucene-spatial-extras-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+b5b651b0adbc2f404e091817282dabd7b432c677
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 480ae590aed..00000000000
--- a/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d86a7ba859576bdcee1dacd8f407ccf71f982c60
\ No newline at end of file
diff --git a/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..512e4b7b592
--- /dev/null
+++ b/distribution/licenses/lucene-spatial3d-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+334e194bf83c75f0ae165e3e72b6fa35c5d636c5
\ No newline at end of file
diff --git a/distribution/licenses/lucene-suggest-6.0.0-snapshot-bea235f.jar.sha1 b/distribution/licenses/lucene-suggest-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 7835298c4a2..00000000000
--- a/distribution/licenses/lucene-suggest-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-a3860de6502576f142dc948eb2005fa4dc0c27c5
\ No newline at end of file
diff --git a/distribution/licenses/lucene-suggest-6.0.0-snapshot-f0aa4fc.jar.sha1 b/distribution/licenses/lucene-suggest-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..3d2cf156d40
--- /dev/null
+++ b/distribution/licenses/lucene-suggest-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+89c46e9601cf8fb9acf77398838f8710c9e44053
\ No newline at end of file
diff --git a/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-bea235f.jar.sha1 b/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index d9a29f17c50..00000000000
--- a/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8d11bf581b0afc25f87a57c06834cd85930d2ffa
\ No newline at end of file
diff --git a/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-f0aa4fc.jar.sha1 b/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..5237907f224
--- /dev/null
+++ b/modules/lang-expression/licenses/lucene-expressions-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+f36f8010c9fec7342d34bece819c13de5f241135
\ No newline at end of file
diff --git a/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-bea235f.jar.sha1 b/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 538d2ad8216..00000000000
--- a/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-38fda9b86e4f68eb6c9d31fb636a2540da219927
\ No newline at end of file
diff --git a/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-f0aa4fc.jar.sha1 b/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..f2e307d5d98
--- /dev/null
+++ b/plugins/analysis-icu/licenses/lucene-analyzers-icu-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+1378905632ff45a9887b267c4b30f7adef415ca4
\ No newline at end of file
diff --git a/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-bea235f.jar.sha1 b/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index b90115da4ab..00000000000
--- a/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-352fea7a169ada6a7ae18e4ec34559496e09b465
\ No newline at end of file
diff --git a/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-f0aa4fc.jar.sha1 b/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..7bf3eb5333d
--- /dev/null
+++ b/plugins/analysis-kuromoji/licenses/lucene-analyzers-kuromoji-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+49acd38e206d9c2fe28269fcba9b752d3b605e0e
\ No newline at end of file
diff --git a/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-bea235f.jar.sha1 b/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 7cbe648e0bd..00000000000
--- a/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-445f5ea7822d0dd6b91364ec119cd6cb4635d285
\ No newline at end of file
diff --git a/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-f0aa4fc.jar.sha1 b/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..8f08fe26980
--- /dev/null
+++ b/plugins/analysis-phonetic/licenses/lucene-analyzers-phonetic-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+7c11723d7d4dc3b1c9bf80089cfc2de7bc8a2b6e
\ No newline at end of file
diff --git a/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-bea235f.jar.sha1 b/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index 03c96786de2..00000000000
--- a/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-0b216b7b9ff583bc1382edc8adfee4d4acd02859
\ No newline at end of file
diff --git a/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-f0aa4fc.jar.sha1 b/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..bf5e5da8dcf
--- /dev/null
+++ b/plugins/analysis-smartcn/licenses/lucene-analyzers-smartcn-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+654d961bd4975a3cb13388d86d72fefb6994f659
\ No newline at end of file
diff --git a/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-bea235f.jar.sha1 b/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-bea235f.jar.sha1
deleted file mode 100644
index f27a98f63ba..00000000000
--- a/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-bea235f.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8d161a8c7e5b5b82f64dc5df2ca46197a3716672
\ No newline at end of file
diff --git a/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-f0aa4fc.jar.sha1 b/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-f0aa4fc.jar.sha1
new file mode 100644
index 00000000000..ed0dc51b97c
--- /dev/null
+++ b/plugins/analysis-stempel/licenses/lucene-analyzers-stempel-6.0.0-snapshot-f0aa4fc.jar.sha1
@@ -0,0 +1 @@
+0f408ac498782617a0f80d6a295d82f6d3609499
\ No newline at end of file

From c50c5a52d519dc7626de8572da0d00b4644a2ee7 Mon Sep 17 00:00:00 2001
From: Adrien Grand 
Date: Fri, 26 Feb 2016 16:25:05 +0100
Subject: [PATCH 46/49] Rework norms parameters for 5.0. #16987

Changes:
 - no more option to configure eager/lazy loading of the norms (useless now
   that orms are disk-based)
 - only the `string`, `text` and `keyword` fields support the `norms` setting
 - the `norms` setting takes a boolean that decides whether norms should be
   stored in the index but old options are still supported to give users time
   to upgrade
 - setting a `boost` no longer implicitely enables norms (for new indices only,
   this is still needed for old indices)
---
 .../org/elasticsearch/index/IndexWarmer.java  |  64 ------------------
 .../index/mapper/FieldMapper.java             |  19 ++----
 .../index/mapper/MappedFieldType.java         |  19 +-----
 .../index/mapper/core/KeywordFieldMapper.java |  11 +--
 .../index/mapper/core/NumberFieldMapper.java  |   2 +-
 .../index/mapper/core/StringFieldMapper.java  |  21 +++++-
 .../index/mapper/core/TypeParsers.java        |  64 ++++++++++++------
 .../index/mapper/internal/AllFieldMapper.java |   2 +-
 .../index/mapper/FieldTypeTestCase.java       |   7 --
 .../mapper/all/SimpleAllMapperTests.java      |   6 +-
 .../mapper/boost/CustomBoostMappingTests.java |  47 ++++++++++---
 .../mapper/boost/FieldLevelBoostTests.java    |  14 ++--
 .../mapper/core/KeywordFieldMapperTests.java  |  58 ++++++++++++++++
 .../core/StringMappingUpgradeTests.java       |  12 +++-
 .../mapper/core/TextFieldMapperTests.java     |   5 +-
 .../mapper/numeric/SimpleNumericTests.java    |  16 +++++
 .../string/SimpleStringMappingTests.java      |   2 +-
 .../update/UpdateMappingOnClusterIT.java      |   2 +-
 .../mapping/UpdateMappingIntegrationIT.java   |   6 +-
 .../search/child/ChildQuerySearchIT.java      |   1 -
 .../search/query/MultiMatchQueryIT.java       |   4 +-
 .../search/query/SearchQueryIT.java           |   2 +-
 .../resources/indices/bwc/index-2.2.0.zip     | Bin 96001 -> 72250 bytes
 .../test/resources/indices/bwc/repo-2.2.0.zip | Bin 94087 -> 70304 bytes
 .../index/mapper/all/mapping.json             |   2 +-
 .../update/all_mapping_create_index.json      |   2 +-
 .../all_mapping_update_with_conflicts.json    |   2 +-
 dev-tools/create_bwc_index.py                 |  19 ++++++
 28 files changed, 236 insertions(+), 173 deletions(-)

diff --git a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java
index ed1814681ac..332fcdd380e 100644
--- a/core/src/main/java/org/elasticsearch/index/IndexWarmer.java
+++ b/core/src/main/java/org/elasticsearch/index/IndexWarmer.java
@@ -19,12 +19,7 @@
 
 package org.elasticsearch.index;
 
-import com.carrotsearch.hppc.ObjectHashSet;
-import com.carrotsearch.hppc.ObjectSet;
-import com.carrotsearch.hppc.cursors.ObjectCursor;
-import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.NumericDocValues;
 import org.elasticsearch.common.component.AbstractComponent;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting.Property;
@@ -64,7 +59,6 @@ public final class IndexWarmer extends AbstractComponent {
         super(settings);
         ArrayList list = new ArrayList<>();
         final Executor executor = threadPool.executor(ThreadPool.Names.WARMER);
-        list.add(new NormsWarmer(executor));
         list.add(new FieldDataWarmer(executor));
         for (Listener listener : listeners) {
             list.add(listener);
@@ -138,64 +132,6 @@ public final class IndexWarmer extends AbstractComponent {
         TerminationHandle warmTopReader(IndexShard indexShard, Engine.Searcher searcher);
     }
 
-    private static class NormsWarmer implements IndexWarmer.Listener {
-        private final Executor executor;
-        public NormsWarmer(Executor executor) {
-            this.executor = executor;
-        }
-        @Override
-        public TerminationHandle warmNewReaders(final IndexShard indexShard, final Engine.Searcher searcher) {
-            final MappedFieldType.Loading defaultLoading = indexShard.indexSettings().getValue(INDEX_NORMS_LOADING_SETTING);
-            final MapperService mapperService = indexShard.mapperService();
-            final ObjectSet warmUp = new ObjectHashSet<>();
-            for (DocumentMapper docMapper : mapperService.docMappers(false)) {
-                for (FieldMapper fieldMapper : docMapper.mappers()) {
-                    final String indexName = fieldMapper.fieldType().name();
-                    MappedFieldType.Loading normsLoading = fieldMapper.fieldType().normsLoading();
-                    if (normsLoading == null) {
-                        normsLoading = defaultLoading;
-                    }
-                    if (fieldMapper.fieldType().indexOptions() != IndexOptions.NONE && !fieldMapper.fieldType().omitNorms()
-                        && normsLoading == MappedFieldType.Loading.EAGER) {
-                        warmUp.add(indexName);
-                    }
-                }
-            }
-
-            final CountDownLatch latch = new CountDownLatch(1);
-            // Norms loading may be I/O intensive but is not CPU intensive, so we execute it in a single task
-            executor.execute(() -> {
-                try {
-                    for (ObjectCursor stringObjectCursor : warmUp) {
-                        final String indexName = stringObjectCursor.value;
-                        final long start = System.nanoTime();
-                        for (final LeafReaderContext ctx : searcher.reader().leaves()) {
-                            final NumericDocValues values = ctx.reader().getNormValues(indexName);
-                            if (values != null) {
-                                values.get(0);
-                            }
-                        }
-                        if (indexShard.warmerService().logger().isTraceEnabled()) {
-                            indexShard.warmerService().logger().trace("warmed norms for [{}], took [{}]", indexName,
-                                TimeValue.timeValueNanos(System.nanoTime() - start));
-                        }
-                    }
-                } catch (Throwable t) {
-                    indexShard.warmerService().logger().warn("failed to warm-up norms", t);
-                } finally {
-                    latch.countDown();
-                }
-            });
-
-            return () -> latch.await();
-        }
-
-        @Override
-        public TerminationHandle warmTopReader(IndexShard indexShard, final Engine.Searcher searcher) {
-            return TerminationHandle.NO_WAIT;
-        }
-    }
-
     private static class FieldDataWarmer implements IndexWarmer.Listener {
 
         private final Executor executor;
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java
index b8b7f4bb113..20522abfbac 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java
@@ -203,11 +203,6 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
             return builder;
         }
 
-        public T normsLoading(MappedFieldType.Loading normsLoading) {
-            this.fieldType.setNormsLoading(normsLoading);
-            return builder;
-        }
-
         public T fieldDataSettings(Settings settings) {
             this.fieldDataSettings = settings;
             return builder;
@@ -243,6 +238,9 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
 
         protected void setupFieldType(BuilderContext context) {
             fieldType.setName(buildFullName(context));
+            if (context.indexCreatedVersion().before(Version.V_5_0_0)) {
+                fieldType.setOmitNorms(fieldType.omitNorms() && fieldType.boost() == 1.0f);
+            }
             if (fieldType.indexAnalyzer() == null && fieldType.tokenized() == false && fieldType.indexOptions() != IndexOptions.NONE) {
                 fieldType.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
                 fieldType.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
@@ -419,15 +417,8 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
         if (includeDefaults || fieldType().storeTermVectors() != defaultFieldType.storeTermVectors()) {
             builder.field("term_vector", termVectorOptionsToString(fieldType()));
         }
-        if (includeDefaults || fieldType().omitNorms() != defaultFieldType.omitNorms() || fieldType().normsLoading() != null) {
-            builder.startObject("norms");
-            if (includeDefaults || fieldType().omitNorms() != defaultFieldType.omitNorms()) {
-                builder.field("enabled", !fieldType().omitNorms());
-            }
-            if (fieldType().normsLoading() != null) {
-                builder.field(MappedFieldType.Loading.KEY, fieldType().normsLoading());
-            }
-            builder.endObject();
+        if (includeDefaults || fieldType().omitNorms() != defaultFieldType.omitNorms()) {
+            builder.field("norms", fieldType().omitNorms() == false);
         }
         if (indexed && (includeDefaults || fieldType().indexOptions() != defaultFieldType.indexOptions())) {
             builder.field("index_options", indexOptionToString(fieldType().indexOptions()));
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java b/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java
index 10b165ff4c5..98ad76f7fe1 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java
@@ -103,7 +103,6 @@ public abstract class MappedFieldType extends FieldType {
     private NamedAnalyzer searchAnalyzer;
     private NamedAnalyzer searchQuoteAnalyzer;
     private SimilarityProvider similarity;
-    private Loading normsLoading;
     private FieldDataType fieldDataType;
     private Object nullValue;
     private String nullValueAsString; // for sending null value to _all field
@@ -117,7 +116,6 @@ public abstract class MappedFieldType extends FieldType {
         this.searchAnalyzer = ref.searchAnalyzer();
         this.searchQuoteAnalyzer = ref.searchQuoteAnalyzer();
         this.similarity = ref.similarity();
-        this.normsLoading = ref.normsLoading();
         this.fieldDataType = ref.fieldDataType();
         this.nullValue = ref.nullValue();
         this.nullValueAsString = ref.nullValueAsString();
@@ -158,7 +156,6 @@ public abstract class MappedFieldType extends FieldType {
             Objects.equals(indexAnalyzer, fieldType.indexAnalyzer) &&
             Objects.equals(searchAnalyzer, fieldType.searchAnalyzer) &&
             Objects.equals(searchQuoteAnalyzer(), fieldType.searchQuoteAnalyzer()) &&
-            Objects.equals(normsLoading, fieldType.normsLoading) &&
             Objects.equals(fieldDataType, fieldType.fieldDataType) &&
             Objects.equals(nullValue, fieldType.nullValue) &&
             Objects.equals(nullValueAsString, fieldType.nullValueAsString);
@@ -167,7 +164,7 @@ public abstract class MappedFieldType extends FieldType {
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(), name, boost, docValues, indexAnalyzer, searchAnalyzer, searchQuoteAnalyzer,
-            similarity == null ? null : similarity.name(), normsLoading, fieldDataType, nullValue, nullValueAsString);
+            similarity == null ? null : similarity.name(), fieldDataType, nullValue, nullValueAsString);
     }
 
     // norelease: we need to override freeze() and add safety checks that all settings are actually set
@@ -205,7 +202,7 @@ public abstract class MappedFieldType extends FieldType {
             conflicts.add("mapper [" + name() + "] has different [doc_values] values");
         }
         if (omitNorms() && !other.omitNorms()) {
-            conflicts.add("mapper [" + name() + "] has different [omit_norms] values, cannot change from disable to enabled");
+            conflicts.add("mapper [" + name() + "] has different [norms] values, cannot change from disable to enabled");
         }
         if (storeTermVectors() != other.storeTermVectors()) {
             conflicts.add("mapper [" + name() + "] has different [store_term_vector] values");
@@ -242,9 +239,6 @@ public abstract class MappedFieldType extends FieldType {
             if (boost() != other.boost()) {
                 conflicts.add("mapper [" + name() + "] is used by multiple types. Set update_all_types to true to update [boost] across all types.");
             }
-            if (normsLoading() != other.normsLoading()) {
-                conflicts.add("mapper [" + name() + "] is used by multiple types. Set update_all_types to true to update [norms.loading] across all types.");
-            }
             if (Objects.equals(searchAnalyzer(), other.searchAnalyzer()) == false) {
                 conflicts.add("mapper [" + name() + "] is used by multiple types. Set update_all_types to true to update [search_analyzer] across all types.");
             }
@@ -304,15 +298,6 @@ public abstract class MappedFieldType extends FieldType {
         this.docValues = hasDocValues;
     }
 
-    public Loading normsLoading() {
-        return normsLoading;
-    }
-
-    public void setNormsLoading(Loading normsLoading) {
-        checkIfFrozen();
-        this.normsLoading = normsLoading;
-    }
-
     public NamedAnalyzer indexAnalyzer() {
         return indexAnalyzer;
     }
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java
index 3f01493590c..744882e1ccd 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java
@@ -92,14 +92,6 @@ public final class KeywordFieldMapper extends FieldMapper implements AllFieldMap
             return super.indexOptions(indexOptions);
         }
 
-        @Override
-        protected void setupFieldType(BuilderContext context) {
-            if (!omitNormsSet && fieldType.boost() != 1.0f) {
-                fieldType.setOmitNorms(false);
-            }
-            super.setupFieldType(context);
-        }
-
         @Override
         public KeywordFieldMapper build(BuilderContext context) {
             setupFieldType(context);
@@ -128,6 +120,9 @@ public final class KeywordFieldMapper extends FieldMapper implements AllFieldMap
                 } else if (propName.equals("ignore_above")) {
                     builder.ignoreAbove(XContentMapValues.nodeIntegerValue(propNode, -1));
                     iterator.remove();
+                } else if (propName.equals("norms")) {
+                    builder.omitNorms(XContentMapValues.nodeBooleanValue(propNode) == false);
+                    iterator.remove();
                 } else if (parseMultiField(builder, name, parserContext, propName, propNode)) {
                     iterator.remove();
                 }
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java
index 72014482ca8..4b4c0882508 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java
@@ -31,6 +31,7 @@ import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexableFieldType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.Version;
 import org.elasticsearch.common.Explicit;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting.Property;
@@ -116,7 +117,6 @@ public abstract class NumberFieldMapper extends FieldMapper implements AllFieldM
 
         protected void setupFieldType(BuilderContext context) {
             super.setupFieldType(context);
-            fieldType.setOmitNorms(fieldType.omitNorms() && fieldType.boost() == 1.0f);
             int precisionStep = fieldType.numericPrecisionStep();
             if (precisionStep <= 0 || precisionStep >= maxPrecisionStep()) {
                 fieldType.setNumericPrecisionStep(Integer.MAX_VALUE);
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
index 656d6effcfa..4301a2252d8 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
@@ -157,13 +157,30 @@ public class StringFieldMapper extends FieldMapper implements AllFieldMapper.Inc
                             fieldName);
                     final Object index = node.remove("index");
                     final boolean keyword = index != null && "analyzed".equals(index) == false;
-                    // upgrade the index setting
-                    node.put("index", "no".equals(index) == false);
+                    {
+                        // upgrade the index setting
+                        node.put("index", "no".equals(index) == false);
+                    }
+                    {
+                        // upgrade norms settings
+                        Object norms = node.remove("norms");
+                        if (norms instanceof Map) {
+                            norms = ((Map) norms).get("enabled");
+                        }
+                        if (norms != null) {
+                            node.put("norms", TypeParsers.nodeBooleanValue("norms", norms, parserContext));
+                        }
+                        Object omitNorms = node.remove("omit_norms");
+                        if (omitNorms != null) {
+                            node.put("norms", TypeParsers.nodeBooleanValue("omit_norms", omitNorms, parserContext) == false);
+                        }
+                    }
                     if (keyword) {
                         return new KeywordFieldMapper.TypeParser().parse(fieldName, node, parserContext);
                     } else {
                         return new TextFieldMapper.TypeParser().parse(fieldName, node, parserContext);
                     }
+
                 }
                 throw new IllegalArgumentException("The [string] type is removed in 5.0. You should now use either a [text] "
                         + "or [keyword] field instead for field [" + fieldName + "]");
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java b/core/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java
index f8c1c0a812a..c6b91292ace 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java
@@ -71,7 +71,7 @@ public class TypeParsers {
     private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(TypeParsers.class));
     private static final Set BOOLEAN_STRINGS = new HashSet<>(Arrays.asList("true", "false"));
 
-    private static boolean nodeBooleanValue(String name, Object node, Mapper.TypeParser.ParserContext parserContext) {
+    public static boolean nodeBooleanValue(String name, Object node, Mapper.TypeParser.ParserContext parserContext) {
         // Hook onto ParseFieldMatcher so that parsing becomes strict when setting index.query.parse.strict
         if (parserContext.parseFieldMatcher().isStrict()) {
             return XContentMapValues.nodeBooleanValue(node);
@@ -99,9 +99,6 @@ public class TypeParsers {
             } else if (propName.equals("coerce")) {
                 builder.coerce(nodeBooleanValue("coerce", propNode, parserContext));
                 iterator.remove();
-            } else if (propName.equals("omit_norms")) {
-                builder.omitNorms(nodeBooleanValue("omit_norms", propNode, parserContext));
-                iterator.remove();
             } else if (propName.equals("similarity")) {
                 SimilarityProvider similarityProvider = resolveSimilarity(parserContext, name, propNode.toString());
                 builder.similarity(similarityProvider);
@@ -187,6 +184,37 @@ public class TypeParsers {
         }
     }
 
+    public static boolean parseNorms(FieldMapper.Builder builder, String propName, Object propNode, Mapper.TypeParser.ParserContext parserContext) {
+        if (propName.equals("norms")) {
+            if (propNode instanceof Map) {
+                final Map properties = nodeMapValue(propNode, "norms");
+                for (Iterator> propsIterator = properties.entrySet().iterator(); propsIterator.hasNext();) {
+                    Entry entry2 = propsIterator.next();
+                    final String propName2 = Strings.toUnderscoreCase(entry2.getKey());
+                    final Object propNode2 = entry2.getValue();
+                    if (propName2.equals("enabled")) {
+                        builder.omitNorms(!lenientNodeBooleanValue(propNode2));
+                        propsIterator.remove();
+                    } else if (propName2.equals(Loading.KEY)) {
+                        // ignore for bw compat
+                        propsIterator.remove();
+                    }
+                }
+                DocumentMapperParser.checkNoRemainingFields(propName, properties, parserContext.indexVersionCreated());
+                DEPRECATION_LOGGER.deprecated("The [norms{enabled:true/false}] way of specifying norms is deprecated, please use [norms:true/false] instead");
+            } else {
+                builder.omitNorms(nodeBooleanValue("norms", propNode, parserContext) == false);
+            }
+            return true;
+        } else if (propName.equals("omit_norms")) {
+            builder.omitNorms(nodeBooleanValue("norms", propNode, parserContext));
+            DEPRECATION_LOGGER.deprecated("[omit_norms] is deprecated, please use [norms] instead with the opposite boolean value");
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Parse text field attributes. In addition to {@link #parseField common attributes}
      * this will parse analysis and term-vectors related settings.
@@ -194,6 +222,14 @@ public class TypeParsers {
     public static void parseTextField(FieldMapper.Builder builder, String name, Map fieldNode, Mapper.TypeParser.ParserContext parserContext) {
         parseField(builder, name, fieldNode, parserContext);
         parseAnalyzersAndTermVectors(builder, name, fieldNode, parserContext);
+        for (Iterator> iterator = fieldNode.entrySet().iterator(); iterator.hasNext();) {
+            Map.Entry entry = iterator.next();
+            final String propName = Strings.toUnderscoreCase(entry.getKey());
+            final Object propNode = entry.getValue();
+            if (parseNorms(builder, propName, propNode, parserContext)) {
+                iterator.remove();
+            }
+        }
     }
 
     /**
@@ -217,24 +253,8 @@ public class TypeParsers {
             } else if (propName.equals("boost")) {
                 builder.boost(nodeFloatValue(propNode));
                 iterator.remove();
-            } else if (propName.equals("omit_norms")) {
-                builder.omitNorms(nodeBooleanValue("omit_norms", propNode, parserContext));
-                iterator.remove();
-            } else if (propName.equals("norms")) {
-                final Map properties = nodeMapValue(propNode, "norms");
-                for (Iterator> propsIterator = properties.entrySet().iterator(); propsIterator.hasNext();) {
-                    Entry entry2 = propsIterator.next();
-                    final String propName2 = Strings.toUnderscoreCase(entry2.getKey());
-                    final Object propNode2 = entry2.getValue();
-                    if (propName2.equals("enabled")) {
-                        builder.omitNorms(!lenientNodeBooleanValue(propNode2));
-                        propsIterator.remove();
-                    } else if (propName2.equals(Loading.KEY)) {
-                        builder.normsLoading(Loading.parse(nodeStringValue(propNode2, null), null));
-                        propsIterator.remove();
-                    }
-                }
-                DocumentMapperParser.checkNoRemainingFields(propName, properties, parserContext.indexVersionCreated());
+            } else if (parserContext.indexVersionCreated().before(Version.V_5_0_0)
+                    && parseNorms(builder, propName, propNode, parserContext)) {
                 iterator.remove();
             } else if (propName.equals("index_options")) {
                 builder.indexOptions(nodeIndexOptionValue(propNode));
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java
index 97c2fa3933b..7565243251c 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java
@@ -305,7 +305,7 @@ public class AllFieldMapper extends MetadataFieldMapper {
             builder.field("store_term_vector_payloads", fieldType().storeTermVectorPayloads());
         }
         if (includeDefaults || fieldType().omitNorms() != Defaults.FIELD_TYPE.omitNorms()) {
-            builder.field("omit_norms", fieldType().omitNorms());
+            builder.field("norms", !fieldType().omitNorms());
         }
         
         doXContentAnalyzers(builder, includeDefaults);
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/FieldTypeTestCase.java b/core/src/test/java/org/elasticsearch/index/mapper/FieldTypeTestCase.java
index 966edf82621..b7194a3829b 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/FieldTypeTestCase.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/FieldTypeTestCase.java
@@ -130,12 +130,6 @@ public abstract class FieldTypeTestCase extends ESTestCase {
                 other.setSimilarity(new BM25SimilarityProvider("bar", Settings.EMPTY));
             }
         },
-        new Modifier("norms.loading", true) {
-            @Override
-            public void modify(MappedFieldType ft) {
-                ft.setNormsLoading(MappedFieldType.Loading.LAZY);
-            }
-        },
         new Modifier("fielddata", true) {
             @Override
             public void modify(MappedFieldType ft) {
@@ -217,7 +211,6 @@ public abstract class FieldTypeTestCase extends ESTestCase {
             ", searchAnalyzer=" + ft.searchAnalyzer() +
             ", searchQuoteAnalyzer=" + ft.searchQuoteAnalyzer() +
             ", similarity=" + ft.similarity() +
-            ", normsLoading=" + ft.normsLoading() +
             ", fieldDataType=" + ft.fieldDataType() +
             ", nullValue=" + ft.nullValue() +
             ", nullValueAsString='" + ft.nullValueAsString() + "'" +
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java
index 19d0317f492..762a62f3756 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java
@@ -223,7 +223,7 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase {
     }
 
     public void testRandom() throws Exception {
-        boolean omitNorms = false;
+        boolean norms = false;
         boolean stored = false;
         boolean enabled = true;
         boolean tv_stored = false;
@@ -239,7 +239,7 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase {
             allDefault = false;
             mappingBuilder.startObject("_all");
             if (randomBoolean()) {
-                booleanOptionList.add(new Tuple<>("omit_norms", omitNorms = randomBoolean()));
+                booleanOptionList.add(new Tuple<>("norms", norms = randomBoolean()));
             }
             if (randomBoolean()) {
                 booleanOptionList.add(new Tuple<>("store", stored = randomBoolean()));
@@ -285,7 +285,7 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase {
         Document doc = builtDocMapper.parse("test", "test", "1", new BytesArray(json)).rootDoc();
         AllField field = (AllField) doc.getField("_all");
         if (enabled) {
-            assertThat(field.fieldType().omitNorms(), equalTo(omitNorms));
+            assertThat(field.fieldType().omitNorms(), equalTo(!norms));
             assertThat(field.fieldType().stored(), equalTo(stored));
             assertThat(field.fieldType().storeTermVectorOffsets(), equalTo(tv_offsets));
             assertThat(field.fieldType().storeTermVectorPayloads(), equalTo(tv_payloads));
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/boost/CustomBoostMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/boost/CustomBoostMappingTests.java
index 91a0ca15cd4..490477d67e7 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/boost/CustomBoostMappingTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/boost/CustomBoostMappingTests.java
@@ -85,18 +85,17 @@ public class CustomBoostMappingTests extends ESSingleNodeTestCase {
     }
 
     public void testBackCompatFieldMappingBoostValues() throws Exception {
-        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
-            .startObject("s_field").field("type", "keyword").field("boost", 2.0f).endObject()
-            .startObject("l_field").field("type", "long").field("boost", 3.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("i_field").field("type", "integer").field("boost", 4.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("sh_field").field("type", "short").field("boost", 5.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("b_field").field("type", "byte").field("boost", 6.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("d_field").field("type", "double").field("boost", 7.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("f_field").field("type", "float").field("boost", 8.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("date_field").field("type", "date").field("boost", 9.0f).startObject("norms").field("enabled", true).endObject().endObject()
-            .endObject().endObject().endObject().string();
-
         {
+            String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
+                    .startObject("s_field").field("type", "keyword").field("boost", 2.0f).endObject()
+                    .startObject("l_field").field("type", "long").field("boost", 3.0f).endObject()
+                    .startObject("i_field").field("type", "integer").field("boost", 4.0f).endObject()
+                    .startObject("sh_field").field("type", "short").field("boost", 5.0f).endObject()
+                    .startObject("b_field").field("type", "byte").field("boost", 6.0f).endObject()
+                    .startObject("d_field").field("type", "double").field("boost", 7.0f).endObject()
+                    .startObject("f_field").field("type", "float").field("boost", 8.0f).endObject()
+                    .startObject("date_field").field("type", "date").field("boost", 9.0f).endObject()
+                    .endObject().endObject().endObject().string();
             IndexService indexService = createIndex("test", BW_SETTINGS);
             QueryShardContext context = indexService.newQueryShardContext();
             DocumentMapper mapper = indexService.mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
@@ -122,16 +121,34 @@ public class CustomBoostMappingTests extends ESSingleNodeTestCase {
                 .endObject().bytes());
 
             assertThat(doc.rootDoc().getField("s_field").boost(), equalTo(2.0f));
+            assertThat(doc.rootDoc().getField("s_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("l_field").boost(), equalTo(3.0f));
+            assertThat(doc.rootDoc().getField("l_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("i_field").boost(), equalTo(4.0f));
+            assertThat(doc.rootDoc().getField("i_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("sh_field").boost(), equalTo(5.0f));
+            assertThat(doc.rootDoc().getField("sh_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("b_field").boost(), equalTo(6.0f));
+            assertThat(doc.rootDoc().getField("b_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("d_field").boost(), equalTo(7.0f));
+            assertThat(doc.rootDoc().getField("d_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("f_field").boost(), equalTo(8.0f));
+            assertThat(doc.rootDoc().getField("f_field").fieldType().omitNorms(), equalTo(false));
             assertThat(doc.rootDoc().getField("date_field").boost(), equalTo(9.0f));
+            assertThat(doc.rootDoc().getField("date_field").fieldType().omitNorms(), equalTo(false));
         }
 
         {
+            String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
+                    .startObject("s_field").field("type", "keyword").field("boost", 2.0f).endObject()
+                    .startObject("l_field").field("type", "long").field("boost", 3.0f).endObject()
+                    .startObject("i_field").field("type", "integer").field("boost", 4.0f).endObject()
+                    .startObject("sh_field").field("type", "short").field("boost", 5.0f).endObject()
+                    .startObject("b_field").field("type", "byte").field("boost", 6.0f).endObject()
+                    .startObject("d_field").field("type", "double").field("boost", 7.0f).endObject()
+                    .startObject("f_field").field("type", "float").field("boost", 8.0f).endObject()
+                    .startObject("date_field").field("type", "date").field("boost", 9.0f).endObject()
+                    .endObject().endObject().endObject().string();
             IndexService indexService = createIndex("text");
             QueryShardContext context = indexService.newQueryShardContext();
             DocumentMapper mapper = indexService.mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
@@ -157,13 +174,21 @@ public class CustomBoostMappingTests extends ESSingleNodeTestCase {
                 .endObject().bytes());
 
             assertThat(doc.rootDoc().getField("s_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("s_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("l_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("l_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("i_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("i_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("sh_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("sh_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("b_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("b_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("d_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("d_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("f_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("f_field").fieldType().omitNorms(), equalTo(true));
             assertThat(doc.rootDoc().getField("date_field").boost(), equalTo(1f));
+            assertThat(doc.rootDoc().getField("date_field").fieldType().omitNorms(), equalTo(true));
         }
     }
 }
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/boost/FieldLevelBoostTests.java b/core/src/test/java/org/elasticsearch/index/mapper/boost/FieldLevelBoostTests.java
index b1fde6bdd67..90121e66ea8 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/boost/FieldLevelBoostTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/boost/FieldLevelBoostTests.java
@@ -102,13 +102,13 @@ public class FieldLevelBoostTests extends ESSingleNodeTestCase {
     public void testBackCompatFieldLevelMappingBoost() throws Exception {
         String mapping = XContentFactory.jsonBuilder().startObject().startObject("person").startObject("properties")
             .startObject("str_field").field("type", "keyword").field("boost", "2.0").endObject()
-            .startObject("int_field").field("type", "integer").field("boost", "3.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("byte_field").field("type", "byte").field("boost", "4.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("date_field").field("type", "date").field("boost", "5.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("double_field").field("type", "double").field("boost", "6.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("float_field").field("type", "float").field("boost", "7.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("long_field").field("type", "long").field("boost", "8.0").startObject("norms").field("enabled", true).endObject().endObject()
-            .startObject("short_field").field("type", "short").field("boost", "9.0").startObject("norms").field("enabled", true).endObject().endObject()
+            .startObject("int_field").field("type", "integer").field("boost", "3.0").endObject()
+            .startObject("byte_field").field("type", "byte").field("boost", "4.0").endObject()
+            .startObject("date_field").field("type", "date").field("boost", "5.0").endObject()
+            .startObject("double_field").field("type", "double").field("boost", "6.0").endObject()
+            .startObject("float_field").field("type", "float").field("boost", "7.0").endObject()
+            .startObject("long_field").field("type", "long").field("boost", "8.0").endObject()
+            .startObject("short_field").field("type", "short").field("boost", "9.0").endObject()
             .string();
 
         {
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java
index 8af92f266a5..28867ed1f73 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java
@@ -24,22 +24,33 @@ import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexableFieldType;
 import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.Version;
+import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.compress.CompressedXContent;
+import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.index.IndexService;
 import org.elasticsearch.index.mapper.DocumentMapper;
 import org.elasticsearch.index.mapper.DocumentMapperParser;
 import org.elasticsearch.index.mapper.ParsedDocument;
+import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.test.ESSingleNodeTestCase;
+import org.elasticsearch.test.InternalSettingsPlugin;
 import org.junit.Before;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collection;
 
 import static org.hamcrest.Matchers.equalTo;
 
 public class KeywordFieldMapperTests extends ESSingleNodeTestCase {
 
+    @Override
+    protected Collection> getPlugins() {
+        return pluginList(InternalSettingsPlugin.class);
+    }
+
     IndexService indexService;
     DocumentMapperParser parser;
 
@@ -232,4 +243,51 @@ public class KeywordFieldMapperTests extends ESSingleNodeTestCase {
             assertEquals("The [keyword] field does not support positions, got [index_options]=" + indexOptions, e.getMessage());
         }
     }
+
+    public void testBoost() throws IOException {
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties").startObject("field").field("type", "keyword").field("boost", 2f).endObject().endObject()
+                .endObject().endObject().string();
+
+        DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
+
+        assertEquals(mapping, mapper.mappingSource().toString());
+    }
+
+    public void testBoostImplicitlyEnablesNormsOnOldIndex() throws IOException {
+        indexService = createIndex("test2",
+                Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0).build());
+        parser = indexService.mapperService().documentMapperParser();
+
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties").startObject("field").field("type", "keyword").field("boost", 2f).endObject().endObject()
+                .endObject().endObject().string();
+        DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
+
+        String expectedMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties").startObject("field").field("type", "keyword")
+                .field("boost", 2f).field("norms", true).endObject().endObject()
+                .endObject().endObject().string();
+        assertEquals(expectedMapping, mapper.mappingSource().toString());
+    }
+
+    public void testEnableNorms() throws IOException {
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties").startObject("field").field("type", "keyword").field("norms", true).endObject().endObject()
+                .endObject().endObject().string();
+
+        DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
+
+        assertEquals(mapping, mapper.mappingSource().toString());
+
+        ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
+                .startObject()
+                .field("field", "1234")
+                .endObject()
+                .bytes());
+
+        IndexableField[] fields = doc.rootDoc().getFields("field");
+        assertEquals(2, fields.length);
+        assertFalse(fields[0].fieldType().omitNorms());
+    }
 }
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/StringMappingUpgradeTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/StringMappingUpgradeTests.java
index 4b2fe9a7102..d49f50da0ab 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/core/StringMappingUpgradeTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/core/StringMappingUpgradeTests.java
@@ -39,6 +39,7 @@ import org.elasticsearch.test.InternalSettingsPlugin;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.instanceOf;
@@ -130,6 +131,7 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
         XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
                 .startObject("properties").startObject("field").field("type", "string");
         boolean keyword = randomBoolean();
+        boolean hasNorms = keyword == false;
         boolean shouldUpgrade = true;
         if (keyword) {
             mapping.field("index", randomBoolean() ? "not_analyzed" : "no");
@@ -143,7 +145,12 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
             mapping.field("doc_values", randomBoolean());
         }
         if (randomBoolean()) {
-            mapping.field("omit_norms", randomBoolean());
+            hasNorms = randomBoolean();
+            if (randomBoolean()) {
+                mapping.field("omit_norms", hasNorms == false);
+            } else {
+                mapping.field("norms", Collections.singletonMap("enabled", hasNorms));
+            }
         }
         if (randomBoolean()) {
             mapping.startObject("fields").startObject("raw").field("type", "keyword").endObject().endObject();
@@ -172,6 +179,9 @@ public class StringMappingUpgradeTests extends ESSingleNodeTestCase {
             } else {
                 assertThat(field, instanceOf(TextFieldMapper.class));
             }
+            if (field.fieldType().indexOptions() != IndexOptions.NONE) {
+                assertEquals(hasNorms, field.fieldType().omitNorms() == false);
+            }
         }
     }
 }
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/TextFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/TextFieldMapperTests.java
index 3a9d5b46ab9..8dba6dd3fe3 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/core/TextFieldMapperTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/core/TextFieldMapperTests.java
@@ -132,9 +132,7 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
         String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
                 .startObject("properties").startObject("field")
                     .field("type", "text")
-                    .startObject("norms")
-                        .field("enabled", false)
-                    .endObject()
+                    .field("norms", false)
                 .endObject().endObject()
                 .endObject().endObject().string();
 
@@ -386,4 +384,5 @@ public class TextFieldMapperTests extends ESSingleNodeTestCase {
         assertThat(doc.rootDoc().getField("field6").fieldType().storeTermVectorPositions(), equalTo(true));
         assertThat(doc.rootDoc().getField("field6").fieldType().storeTermVectorPayloads(), equalTo(true));
     }
+
 }
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java b/core/src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java
index 09804f82919..c10ccd14262 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java
@@ -684,4 +684,20 @@ public class SimpleNumericTests extends ESSingleNodeTestCase {
         parser = createIndex("index2-" + type, oldIndexSettings).mapperService().documentMapperParser();
         parser.parse("type", new CompressedXContent(mappingWithTV)); // no exception
     }
+
+    public void testRejectNorms() throws IOException {
+        // not supported as of 5.0
+        for (String type : Arrays.asList("byte", "short", "integer", "long", "float", "double")) {
+            DocumentMapperParser parser = createIndex("index-" + type).mapperService().documentMapperParser();
+            String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties")
+                    .startObject("foo")
+                        .field("type", type)
+                        .field("norms", random().nextBoolean())
+                    .endObject()
+                .endObject().endObject().endObject().string();
+            MapperParsingException e = expectThrows(MapperParsingException.class, () -> parser.parse("type", new CompressedXContent(mapping)));
+            assertThat(e.getMessage(), containsString("Mapping definition for [foo] has unsupported parameters:  [norms"));
+        }
+    }
 }
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/string/SimpleStringMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/string/SimpleStringMappingTests.java
index 86c67db219f..8007e624836 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/string/SimpleStringMappingTests.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/string/SimpleStringMappingTests.java
@@ -564,7 +564,7 @@ public class SimpleStringMappingTests extends ESSingleNodeTestCase {
             mapperService.merge("type", new CompressedXContent(updatedMapping), MapperService.MergeReason.MAPPING_UPDATE, false);
             fail();
         } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("different [omit_norms]"));
+            assertThat(e.getMessage(), containsString("different [norms]"));
         }
     }
 
diff --git a/core/src/test/java/org/elasticsearch/index/mapper/update/UpdateMappingOnClusterIT.java b/core/src/test/java/org/elasticsearch/index/mapper/update/UpdateMappingOnClusterIT.java
index a3d6a87c43f..600f84b5f5f 100644
--- a/core/src/test/java/org/elasticsearch/index/mapper/update/UpdateMappingOnClusterIT.java
+++ b/core/src/test/java/org/elasticsearch/index/mapper/update/UpdateMappingOnClusterIT.java
@@ -49,7 +49,7 @@ public class UpdateMappingOnClusterIT extends ESIntegTestCase {
         String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/update/all_mapping_create_index.json");
         String mappingUpdate = copyToStringFromClasspath("/org/elasticsearch/index/mapper/update/all_mapping_update_with_conflicts.json");
         String[] errorMessage = {
-                "[_all] has different [omit_norms] values",
+                "[_all] has different [norms] values",
                 "[_all] has different [store] values",
                 "[_all] has different [store_term_vector] values",
                 "[_all] has different [store_term_vector_offsets] values",
diff --git a/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java
index 0951f3c46df..8e064f46e12 100644
--- a/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java
+++ b/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java
@@ -156,15 +156,15 @@ public class UpdateMappingIntegrationIT extends ESIntegTestCase {
 
     public void testUpdateMappingWithNormsConflicts() throws Exception {
         client().admin().indices().prepareCreate("test")
-                .addMapping("type", "{\"type\":{\"properties\":{\"body\":{\"type\":\"text\", \"norms\": { \"enabled\": false }}}}}")
+                .addMapping("type", "{\"type\":{\"properties\":{\"body\":{\"type\":\"text\", \"norms\": false }}}}")
                 .execute().actionGet();
         try {
             client().admin().indices().preparePutMapping("test").setType("type")
-                    .setSource("{\"type\":{\"properties\":{\"body\":{\"type\":\"text\", \"norms\": { \"enabled\": true }}}}}").execute()
+                    .setSource("{\"type\":{\"properties\":{\"body\":{\"type\":\"text\", \"norms\": true }}}}").execute()
                     .actionGet();
             fail("Expected MergeMappingException");
         } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("mapper [body] has different [omit_norms]"));
+            assertThat(e.getMessage(), containsString("mapper [body] has different [norms]"));
         }
     }
 
diff --git a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java b/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
index 8aa4e017da9..2d178488dd9 100644
--- a/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
+++ b/core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
@@ -51,7 +51,6 @@ import org.hamcrest.Matchers;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
diff --git a/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java b/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java
index 23e2592447b..be190b547ea 100644
--- a/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java
+++ b/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java
@@ -156,12 +156,12 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
                 .endObject()
                 .startObject("first_name")
                 .field("type", "text")
-                .field("omit_norms", "true")
+                .field("norms", false)
                 .field("copy_to", "first_name_phrase")
                 .endObject()
                 .startObject("last_name")
                 .field("type", "text")
-                .field("omit_norms", "true")
+                .field("norms", false)
                 .field("copy_to", "last_name_phrase")
                 .endObject()
                 .endObject()
diff --git a/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java b/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java
index 44b8636d51a..68b496cd566 100644
--- a/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java
+++ b/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java
@@ -117,7 +117,7 @@ public class SearchQueryIT extends ESIntegTestCase {
     public void testOmitNormsOnAll() throws ExecutionException, InterruptedException, IOException {
         assertAcked(prepareCreate("test")
                 .addMapping("type1", jsonBuilder().startObject().startObject("type1")
-                        .startObject("_all").field("omit_norms", true).endObject()
+                        .startObject("_all").field("norms", false).endObject()
                         .endObject().endObject())
                 .setSettings(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)); // only one shard otherwise IDF might be different for comparing scores
 
diff --git a/core/src/test/resources/indices/bwc/index-2.2.0.zip b/core/src/test/resources/indices/bwc/index-2.2.0.zip
index b645084eeef9952f82df979f50b658b4abac3d10..797ca24f4edbc368b347d7a21b39f4b2b5addbe8 100644
GIT binary patch
literal 72250
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 literal 96001 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

NI`UOGdv-LvmlPil--z`c{X8phbf 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

ZDXp1}keVu9t&zj*Me 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

hbG5rbl;t zIgb`Ud`9J1yJXg~A-HI>>}BT(^#BuT3qE70*a(U_0^6YQdijF-TZ-G9#W{0u&Y=<- zx|74Cp5S&&%%wc1O)k@Mw6`!AD>){T!)m>Nvuf#cYG0DCzdPgubAOhUjFGJqDZ*uNB4y&0z#rjn8EC zS2bA-$v}$-31?e4OU+drzmHd&4CJu8g6~x84!LY_%5c%oZ^l>+a=sNb6MmY`*iRUy z*J^S%J}Tm@kr0pVK-#B@Y&*v(PiihY#>)p(eLf{IX+JlpfxT>zm+o%KRIlI%npt=^ zhItp&*xPhgahk*2>_FKWr!tisb)&_;X6EVaKp7g&wzTo>jVy5t=Pt?k1#>oY3O=%# zxjGAAWz)}OOIy(Hrm%Q%D6sP>%j6~1O`n8K_)In+>o?2Yl=*n1&!n=g8rAsKIOK|21e!N;XwV7=$4*gs=fP6$CzcCuVKIni!=Zx!2`z>Cj(CvW5 zP6uM$+*Wt9NMJw3+3(Qe>$G-%n;IIvm>%kKc^DodOP1k&M+9x`i@IqZT$o#Aj^a zp=Q)mfRQIdo*ou$uqSP9hg%%NScu2n@8C0ggXXECjdvc=%^5#8Fo0^GU4FzAo}&>( zPuwiK$#{z?GG{!dp&!(^23f%nMO{!f7*qv)6*TeO?c^$wWhhN`J<0CsL0-nUvG>Sx zIHJ2R2u^~4{Xo;NR4DmMxm`jNP|-y2vWX?qJW?-P*eR61hS7e5R}ZC=u2lTErrY%J zH`>c%wy2$B7-me8J%fawytB=Ag(?4%8OrY<%E1HOUa_0WD!QfomX2MqBo@E#q`aiX zO4-7`O+o*YHCve}_XXiPfTr^Vc4@oSO*L+gbexGwJv>fyo)*-t6`U}cXAh#AhPwbm zI+z5GpR;%tsFrqZn;R}xSZAHXp{*S(Id|0A@gm3m0hUojP|hcJvjZ8YFX3@nH9ot; z3pP~QI*h|m(b>SOHyU`r`Kq7K#6&sGw$$AQ4+LTG7v@2cLP^-QXshgod$h6LhCs>f zBRku;YB3MfJ=|CJ(nmBS7VIk^ad%2?Sa;YJnE%g`FS(X4QOXiT>!5ZIWKa?4z-VKe zADs{Ay@D*9xh2zwRf&Skg z!p613h|l6ItxI>~n}KU~|4xMf7#^)dyHfkt2`#Ep$@bU1aVWA**pOq@KfeY=4-{N zqVuy6Uhs&>-ZL>DtIiX{a4qP~ce?DwWJ2t(ne2rg(7m~Wsd}Awi*NbPP?4PoEI9|m zva7;AXyc4ah62Y`)6ZF7kUj*_S&0cWiH9MPPuFG+4}vtFqwgr+Kp1Mq>M56fQNpDi zD+n+9fIt`E(tf?OmIF!wJguCvz=+475fH2wxa>-tNxzjx^v~=Tg6k!i1s)*1q{ zl}L>KSy10T`~S$+O7edx-;gK&e&u2OPwW+>RK6jg@(l?sIx6u{>1RqQe7FNVt>8w7 zQsWtCCMV*d6Q;U51!YT0af{+5$5O!59)~t zpiJU>Q&@2_-BBpOionGEhiINCQiMPU9K*}f>aTjZxO5c7q@B+Pl3M}=ezItvFVq0w zz|LSOHc)!#7MR#Ye4_|9<6R#R`zgL@mf)%Y{K@bJ@q;1^{7JCp(W(+%`1nSv7D{rX zAgC8bg1(hLx;vc0+pB>k4wZ~`0@;fAA;JIv_fwR5GL#%`wUEbU=w@e&T#we!-0V(2 z2Ha~aQIgT5z_E&fl*%}>LD`4%eaDXo$n9u>JcRFt7C(W^A6I9j2Gyp>)MQM2YZZ zP9GN8`K@Iz>KlA{xF7ls_?FN;nHezJE6Lq)iU{Rg1Cn%;1E5s*H~ipD-qJpi>6l%p z^7>Wuwy-&kBx^xr<4y`mbpxH)nd;>yi}f550sR)qhMUg=n;&hn=V2j^&|UoM#aqaV zq9;cN=?m7_5SZJ!S*{m9GQnKc1E{i7uSROpPd5;3CF%bRs`W=ETf$qT!+Z;{$IWs( zdrq*`!46J8%l06h^*9!sD|qz-1^1jS+24@s>7%7%GdWx9qb8tsdtLgkiBO zu*shUAh~T6G&@G>3!`&2b}c#rvTt7`)S`EJH#l1Ivg37Q8@I#whQU(ai@Sm2_oCtg zKb2c80j72Fd)?~B2lf<(?8S>L_Itv?Hx(@1>cmwZ-Z3c^h_kgrPIJR<) zCcrq`+QzX91V^(#@lVjb;1B4_)ttSJ)1DI=&Eg@4O@)Y=Oo(iUe`bYFj^np^A|B0uY zG;32b36m`LkjNQtw3qYveOS-;6)!kUGM>`NZS*l76}{2Uo)$R$FnYKKfZ3cxUTjSV zjCq|`CtzTkJ887UJ>5p@Yqcg$0Y;PBFp(xpmg4dkFJICp4EqGqEgmoNwz3)2VpoR?e7P62ELc;C@A7$9SMNpU6PvH_C1b{u4xkQCNW3 zwc;Nm>`a@MJ6q})+f9d&|E`{V%;BF}a=YYczL&2P>i7h(2+ahonPz&y`QVS; zbsF^%S|cOaDjR-ur*3MmLA4AK*>F&Z1$mQWGndpNB86nkQpk+uWbnzjQn;ovRN4q)pC#%F*`OVBrC4(I}$Wo_PsZ!4F z=<#<=KLnbo1#M8)+hq3Z;T*flw8=1mUS2X35_PeKKdS*r0nYHiTk9}w&S6q5e@Aii z%yMA2mXh?T+bexx47C-U3Re6GG-$9?anZm&9LX8S4u^hJ@2ZatqF{{}F!7|B1T7m~bur>nE=k01YO~II!;(+>oHTfHPKc{c*8R>GayC zEF8ZN41T&A3>#Y59F;d`ag8LJ1>^+V*q`FitO12IG8}rzD$Wm~zDI}QDj13@`MxxU zEr8;tnBzPAD5`r3tOER$zsvUr(6wd_7O$_s|JX$W*PXYpcknjv7H8Np6V4xC)rfK2Q$r!mh!zxw3YlbFz!7C!OCPS1Z^n~6+be8#8VkBa#2yr z*b*LwVgps@q73|q*6+n536X%n2nR*Yke~V}h~Ws4@B?&rvWc@FhW0vA@}q@3@RlaK z`CO_9u$f9E$}lp(o!MmGE4JWc@g9Lt!KXpG37Xs`)svviGJKOSoBWJs;G4Xu4;6cw z;Gm_k+DuV{Q0NN@?G;^8J$;L}BS9S|q6uapdr&m~tYD^Bvy;Suu!!E|sVbRYOs3qL z#r)VPfF4{g)Kd^7d`l1rW23M`f?lh~qD2F5PK_ zo0~rcl!X?>SddUrS&ZPP5+JBCgDdOpZ6W>v48Itfb}|_euv2`*&m}MYw(ci;L0uPr z2F*QAV z3MfK(LcE!la2%_FcpMAE@+QXSSj`Cq75JceqU|NTT+d5s(H|CVG*AhQ-)fe6yVDnu z8#M1%>ku_^gnUQGUEVO+V!#lLIS2*h%%zq)q*9}+8{2TkS`~&LC)wIBb(fAN@qRQ^ zv{WMEi+C>^D*6x>s}|i3quwF0Z4CVMBp8TzuIff_lRY-}mF+jc=7)-I)Gm2wtY=SK z1V}PKiTGTLJ#F!94F(X1HtvwT;8qTDIp=@WyR*a4J3_qb+H<<(uG(1&+;F?H!E z&C))_8MAeE12E+SHfiv8O*c8P%ggp1RzdnDFxlY0aj0d~BRrl)s+HS+pBg!sC%M?`xkjdgeO z`jZ;Lr)xk&VBrQVV4ckrxYF(e6Zx~kEQ2!|8fj4?G=EmS{8Z6Tu7Ru^CAs7y4v6tA z<;!lr0*v)kk-d%2Ij_Ugtgc3$xSdX)rf;Swp!#yviyAfd3j^O5V(iCTZoa6UU2k%F zC_o3*(qnbDbB%MLx+Ky-wLpaGyjo#T);I$_@H(#r9iYHL2fLb9KG?v9&#R!oy8+>X zQx2vTm1_iNXF$b$WqmY#n|7sA-t&7p>(#7UzN_M_>0uvZ&^*Vkg_hyW>0$3EybeUV zmFtH6an=dW6A0M@RS z$=^A--OU#BUigq$k4lB34exZbBP5o95Mn^IRc&6jly?%<$BX0Zbi>857Xr$R678h` ziw}!#HdvF8Pz?cQ!H<8eyxw8nna4&~WnsIxsU{#~6NM@fQ_ zV5#4))3KL*q!?p0;<|wHUa-g_2X+3SV=KQhaD$^IHVOo2(@1BeC{N`9#G*WyV}4b6 zt3*o^E*R9gafh#}6-p$>7h$e7rT?oJr%)*I8FFrQ&BiGU29+MKRwCGxa|Xrbf=0>! zD{G-{T(f%G0^Adjtt=3+nhJN#p0(ZjpPBXlS_C4C$5yy6y8r*&U(J8wuqY49AY(S2 z>n)l)vgl`UqiOYDS$8W36sl9yYB@KG>Xrgw%`9`l%gR8ba&V^xxxxDKumvB?Q3>$C zo@vW1mXlwNB8^|U#b$AB$&QbMt(XER1`KD8%<;T|I7p`QeL=jf zEc?|$h&?Ih0XeQ#(8RCeh)QTJ=lYUpIdt+8ibahkQ%^B_*!2D=BSV+XgFpo9p;b2U zAaNFS`#>CmoI02Q$s!8FRm1bCEdc$CU}qNbPN!5&AEIhmhrxO;=6fTU3Nqg@EDg1# zEAhmK3B71@ga$CVKu@d#2SM*EC(@NeL=V$Uzl~}K)Y9{D76gm>$R^FF+(9L~0B8Gh zuqm3*B>`RqE4>5=EhSIeC$gpNhDnbW0*wZ~a06cp=Tg~dnY<=`NFk3Au!oqQ(Wi1f zfX0}@b83uJ?t}t=8_?)Z$pr7|$)80x6iWaP06n`Ym5*FYFg3lJtxB>RU!<}lB-|2D zRj*JQF?64gZ{l=lq);I4jSI3wttZ39(&(Nn!t{VqqYwS!lN|^&`b36)WT)Y#0F}u} zA{!=hegrmK%P#=skz{~cjY&A2Y6FbW2ni%_@TN*Rg}0U|0)${Jbt%3)ew}x=flEIl zIBim`xD6EPHi_*cb0CLyE%}q$hye%KRzTU^O@N2R6gr+GU<_y|>>;8)OSao2FF8T1 zhx1h$E+4(sCb9V{XAGh5=*~AN_Wh!lj?j$#4d+c>BUjfJNaSQd6yVxg`UX$=3r>Vj zKSUz@5N!b-`?L&#Qc@%p+Uk(p@CA!HzaAY*w!J%@s@QJ<*k2ZU()$$YR4lJ;Pz5n^SaSiBiu+ z$`R>KA@OLz^fcZz$%BwI1sF+O1c77Mv=N}Smna?(kN%7R;@%zh3-%SJADt_3`kM-+ zyhSJAwqV(>^PF)KVOL-%>XmqvTnFneW5csJw-971;8>4GXk=S<>cA)6d4ZrQvctM4CCFG-fyvbh%T3R)z3?WP9j$k} zSziZxx&s{z1Ga@C{9bmY;@l+r>1fSVXH>?<*=*ezAsRb;FgMF?28ghS3E6#5F}tHJ zoIS>7_fmR0j%(5Tri%&Sg`YD&Ttq^0GECw|lP#)pEK_au2O1rE;U8?a2S#8y=Uk;Y zp8!`^b^AO)>*;j-ZYtJqTt#$Bdme}YavHA@^sxdvPoM;|MvH|qLeuHO6>KvQxSlU9~b|fGkj{U7}D{EDp?MRd(8vjxv*^sSzc}ov4)(=ji z_`7VNu>QK|@mN(92a| zj5olgK+tZLEb1cbb0Yy!B{qkWU+#V z`$bB~WB+d{hX|y>^sz>EYNA10eTP!lY zG_crz>W(rQJshmJ*dpLMK$=>-Qg(xR7P=0$ZYpo7KWf7X+qkho^BvyUjR&;TfuBy+ zoT)si3i3Vw%EKuqYwX8uoPIL-N}<=BUwU4_8;pmhJ<0A%!dWs~Y48MSCqni>`2W+R z+Vg(?CYXLgF-|CvAGML=!B*#CRO$FxO2K=-%~bX^yaX3OXxM7QR$G^EP$*Jq)6_pj z^OL23!(c&g@+zoL)TLA8v!32rhVa8KP_h-J!mFo2D^jygrL(;7Mo8=m&N)%+j_~Xe zHf68*q2*c1Co=5ri&bZsW?Wo_4b?W7ZhVr)uJ<`MSFL)}gepuyMQ?R;3~m!luGn<^o-T5A`t*+lt;gO+JZ9dIE_-i z*5DtCDXyk?BRR#&fBtuY_~c(U;2By3|K8bE{Fk#UiF1Bevh%R%y*av(+)y*QQB)wl zk%0Pn!Ah<-fi1z@8J$r12Fk2TGC&OcLTGsvM|o9VycIAlgM@)nfCWvoCqXFm8a5WrR%CnnmnAydw2}64#`|d*;D5O{lIXh zWw35^3`Exhe9#u#qA^VLfqX0q12v*%Qy`;WPg`y>V2TDsB>iv;SNgD*@S`HUY9k6m z%Ifj~oy<`w-fYjf;HRvC9vdP;YnkfxT$vyhw@H2oA*hAFk{U^HIp0?#YXn-fR?9A@ zZGSH3*{>w7KP^^rCXsoHh`ac=4)kdE3;KUbWi&K}!HyrG<%Zz@l)ptj-F#{3rr3hl z0bqg>5&R|@^HhJ|L&3w*tzPB;Z3`nc6D3k!6&8L^&w1 zE96JW)~h9~2?!Ygjb%%r56>6;=s75_2=p+2PVI-9!K|J_DR~q*I|a8mLh|vijaRp? zP#A7niw*~3i16HEu0YiqY!!b41UgHB1#hBCV<2xi&P*^ggsruaS|d-NRlWE|n8P=D zQ-cn;Q)h1g$^dQHhe@N7V1(x8XnPRDp1n(9A&s2m!$k53)(dFQ+of6%fW@AsvD+oi zxX2>WNcRIX8!9?$1wVUthu;dvq*f>m0bF#u>=wH!>^YTZ`x};ezetDW_DMw`kW-1E zY0>R?*`bn=Sv!ImUIB;@zN?U*)1JatlMQ@d+SH*3!P$bt03HuA2GVBq5MbR@p6#Ys z$~r3Ew1mgt7za|AgxGZ2yj`M-D1=QW6YjGYm#K<=u!S6CM>{wJm=`dMjnXWr=bju8 zZxYYx>j*|^{ep8dbNVq#Kd>!%mfV*HzmmLYL2I>YalF`Shy#@YhE~HsEgPIpoxRFi zWnc$Cr+tF)IBly@&1cXpV5N%JAh;{!lFu|hWnQ{LalRwze-zmFMVMP0LYjCe^pZ1h zkf-K%@!%!AajygApg=^E>_Ar5(+DurszKQ@()KbMigM6xus&M!sef08HPpV==B5D7 z=LtThn^h~CDjj>6fPORqLl;fr_e>Lh+J)`xEwcrTDXPD(!DC zp0H!}iyI#-v0dBH9cxrm^>N0*j+gvODiQs1PVKk)(s-g-7U-inJXYw2P6Qb8^7}RY zcT}m1ywJbU9b2krzo9x6)o3B+=+%SR1yxAv=2D!8;KsJ(L5r}ls-*_)R3hs*kv*ew zx=$5W)wS&y;&%oy&*pt7Y)kotgob4@`vpv4_6y0>CMactSG?I)2Z^LaC`_zik_n7} zQ`#g`1y~P%DLGG6=Arv-8u*WNG zPP?VP-sY!DopX-0jY(y0NboxECbxEaIRrXCN42y$mYW=+v+p>Zap7QR6;~~MtuIaf zfyuavW9uwSeXi=I-7Y(_n={_xDb?UXyAkFQ#Ad5(0ImUPukPwgL$KAn(=nzHg|4RC zjJ_1|;7qC1vkhfc+O?`vbJ>9&$3CmuC45}l?gjHyV`+sln$m|fH@XqbL+WDtF}oXj z-M&qyoF_lIQ8v}>taNP$Z!5-rtW235F8a|OPJ12tkAU$~b8H&F+Xe!{&g!wWyTR3t zl-R%!5T*)QhpdX1M9U-StxE@!N9=&E@|06;ULT{;Ee-?-n=g2Il@{Mx`U}8E&@A6~ zIreMaDQPIx|{t> zW|vkeMZm7*zn0wWPXhbFFrNKdvbAlTjia_Y$M$ZsyF(n-CAJM3A>>R`mV5xLG)w2$ zEr31ipZ*&M~5mGg_{%S*;APSyXgBK59)X zA~};X>~TTqyPDlv%Q*X)`y=Krw+&wnqt^`)N|{~ln4|K-I>v(k+MUf54TL34Bw z%p!2K>nd(+2xH!zwJ;aZRYXbjfDxoEdMOBru^N?-6N+MrZP8fXoJx8XBQ`oGj}`7j zc)(A|5t?noc_Cplp#T0j-A2qm0XV}`*{(e8?2E^Dr@QjBr12eEXts(gF~i$@Er^9i z8pXg^Zv%<_i7*!M*=FFgxRq^IkKW?Te2c|YK$P5Uo65}xK{ijN@}Y~$>Ro<*sz^z; z9%Zu36M91mxIHV3E`UaQ@VL?gk+foz>QugwV>a~_m>y-CR(JZW(34(4d8KvON^thl zSCm6`50bh5xH*-e5y&=Lz-q4K`;&YhSc}@;QEbV)%uW$0or}F@+12b@ zM%myMkx&ob;!D;3C$-fUF6G&~imd@EeQA)lHCR#t=&w=Pqenz`kijuXVC%S7^TG zPJ*ex{8c?en>~5Ax@n!B)H~FE93sf)oi=n?w)h)p18&o0BD^|+1)Y(*NkuN|%{!2+8 z&pQkFZd!6{OYBH;9xcZSue4)SU6K7=;@B(gmNr-Q!bXR4u0Z})vzDKa{_;@Pl%CV1S&Hw=20EDxl+^4|VB-ewAj-J&w$@W^6_1XYq z8O2DoPYgG{A3gnvVXUP!joRyq4HHe3o;!3*kSk3uSwnHzdN`M88|AFJ2@rJrpk|Eh zrf??IXHG zZB8|5=N98zU9_@bUo^}ElM-Zo32oq~-Ko0)KDsH?3)!%5leFjC-GtWim>^O!X~UOV zI!|TSR*3u?YXzEWw4&l9@J-uAPlUAE)0ioOwN7ex+jE;@gxXdWS>} zi3c3l*INMB$T{F7eY}yct=+|Mf@S)o2;Da~HWxzDPsNK{qQt8-B zKaq_uyNEd_r)kcb9tSV_so`uc=MAx|Xtd^MpFpGk!FC~F6!|vpcj>DS_4=~HWL^T= z8ojHSlr(Agc6h<#9bjG*+dK^V`e=uB59j>o1q&kkC)F*+bgfL&&Ef+zr9otRp-it45XP=L-wQr#-rsBOH5{+K+^Qrx#`?BnFgPq&K8AlI?rPn?O zblXoR1;!o{t*%5j0JXBLnB%n4wx%tpKU=Ow)VKEn9nJqDrktz`%241G@=(oM*$NsG za_ZbzrqIV!D58W@t!(+3trd=ID3`01S3jup{h4Ky@s_o#%VhgCt0$C6^Z!T5_K!_fLcv90bVwnt+J$sPf?>PSm{9CB#4IB0mR%ykEy1= z7ttDlI2UbFJs(mUm84uCP{PJ75Zy(zK<+`&%b+Sx68$(3Y-JWVkcTnkDpF4sV^sA@noutKDW&Fj_9n6*50iXeB9m|Sp+9T>O&~*;$+be zp{BaCt(*I~EWvMcdM+A0LLW(148P=V6T0}W$z%6Kj zwyDNfVX^>?deJT6}q$<_CX*;muUc%4&WTx++Q^!5dZ4 zDbER%@*F%XG@|SgBGw>s7NLbaqKs7N@;Avjf^NZK9tebEXw6zkNjo*2-2&)EgQcwi zs~-kZn|vz!cv}my;RlQOwz8N|HNPFYnlN*x9E{X zd4nrAk@M5XZA(2xE01S#oB@FO2Hzb{;%(qb$Y?z-*K*c?+1+q4@5kRXIQ>D<4g_r- zpvyYJ3r`a3F$@8L^oPVovxFUBwxI?fSo&}yftieBZ}FzKrwORPL}4e1955XvJE>HXoO{IA-H<+1@kfh&|)YB+qx6X@H1?$ z06l+LD|2Hb!7YY~Y_B$7+uvvu>2|yVrbhOlXsUwje9*?8fHwWLV^89>Zif~lIq32I z@YxY94vy=c6xVqTpM5`&5Wac_rik8UlUFPLmE-~K8~p+h2jzjscROB4d(6!zoAIpL zi1Wz`(`Z2ydS{Kmsgo5qmJQ&GGSM7@UWR}p)ywCp^_E}0wFEc-GdM(|1$0`wQw%NqweMDk1=Bbry>+^*M9jn_OT zLgAJCwn>gXToE&?uJRHaG7aCyh@$^&HPH6Oin1&wl5z8HM)!IBC>g6HS&$3(#!4Ky zQK>yez|@=}WLfv%RW=ZKcB|_CMQ_B^<&`3|y3kEPlykXsPlL1$0g$!5M`J>EvFOA0 zlQnVEbRVMlKE#TYye^J`=nbKv-I}%m3BvC;c=Z8W z|GVTM#@0@%%AVf?aBk}Cq=PLZFWY8qg=|Ykembl(3`W9J4LVlG-{oYs_ zu8O|2xZ-g8c6*2rlaS7~!*sj(`SDawlg@Kfyp!)!IdjSd+^c zV6QtQ7hYe&?}a!)pEFK&6t3``!C_RBppRT0kQ*^UU8v7{U^$sqYz40I4v5i8d!1uN zR`8dA2>S$SjdzPW_|d9G+l|cw zQ}oLB2lGQPfy1pT?M71;hj>su%#-SC1phiz1@ZU=L zAm=M?=FkNM9KM~QMa8)5?Q(wWnK4umn3|Xh^*Ai+lRe{^oVN?2=ofs zRUK3Bp0jf}8a=ugA+%yViBE?d_X{d&kuc?C4%nnVEXii&bq)0~;13x0C#LYBToqSD zwd9x4-&{TUro7FXyg|l)f>b~mNuF)YGS7&sqZWLB@t!RULHc z?7R)PgDT#P((Kx0QnSCv^DM0jNWmV{%Ow@fvJnJAyXaH0LAZt`U&KVZ{?TcS-(yvP zUyO`*spEFVx?}7JZoY)gxexX~;=c<1fHj6GNPOammW7bpYvb!r6M{5S(0q}P9fkWY$=SkC2eHm^8Ebiy&wAy z?)-}?$LZx&JyIiFz!D(<6U=FYq|MFDnwEkh{ZhG(J4_Z?ON?;|Vm6M6($b&`w@K<( zPNo*6P_+^9{lVRcLnmaNv>5>y>B7T9Xr7+u4_d!2p3e&EbqIul?DyfaRdd6b)00q=WBuZD$#LL~jUg|8Rz_;8uq(pZAv7fz| zw59|ulqMA6iL@v=bdx3frS;Q+vmn}DCeAv9kK7=J!eF$45M=Z(UA?%=8oVe8;t>92 z&ByY(FIE?ABOO?+xkZ3Y`*MiMm9mkvmO76G6wvOq|_nJW<+;4 zKis4N#k|U@ZBvQ;hsMF95H;`;P6J!VGc^_Y^xr!7JtBep2zxfBpT%NgRlQOkdnb&t zbMt6pNJTOUfX1gux7sN~5)+P>ts#l7S&aNiD?lkDBQw7)r(WwA4xO#YJJYm**##kv zO~%$cd{H(dyl>P_N?#}02g2BizLoIPG53T1ur#P6w=YN!{shAATkq*pbhD~Z+IXs! z;{l@1E+J^Tb%uNnRT+cOTKt0S35u#{$O!vq{a#wM#ORye4GAk@lAZ~ zc=KR!010?23f0v%)#L6x$3Je%W_w0O#4$F2-VlC+5G3F7QeP2`_Bo*%$8@1#1Y^T0 zF}GYt97qYCN~S6A!FURwUWZAP|J%NX_~Lv?KBd-|kS;`2HO;%&Z~{L*g}k+ZOfvuZ z&$^Ke=KumFbF$&ueOtbDTFz4xhI76?d(S5Am>*JV8`+Gckf@JbByn|&Q?utv(*wvm<@ag#%aoue_p)@jB1|d4hyKnmXpN!4k}Zr^Q%+ z;AS)U`{LQtz|Eq2xwEstixcH-=t1^M~kohY%W_Zmi|c&o@`)^GQD@|EXa=7;ovX^@JPt ziA0I*QnCjd+MfZKkM0H(>?u$1=e@{B=CG>*isA4V1jbwQ?4>S zD86(^JW(?n=qdv1+O%?+$zYo_DX@BxIvOJ{+Cqhh<9xz~lpkfxsBFq#Iv+3aJf^hE z#AN=xBl6m5CKK^x1+MyiT)s1q7utk^nlq&bMv3GXA$|nL4<2#o2tOn*3VRr?F_9I$ zYCNO>5+n;xL1VgazH?>y#;Ri_R2Z9fVEA^4V^2nAfG!LtdgXrSp?97LU9tL0q#Z+# zCC=@FsBmxy&ZJ{FB#(J5!`ws-G+-SykCZZ4t82pd#wM1SO26RFoY3+q(#R>Sls4Ek zPt?Kmu@fEq_1_5$-tAwefDE28r=Gi_OR8Y!9P^bTJwF1?UfS>*tGaj5$?MO?uaSc> zR!o1z_tMn$E-;f&0}G07KQk z-(U&5jp#J`)bV1UYg~kKWb(>g7=!lMYA!;3=3NlXPpo4Ed-Tl=cSCl-SKGPXFpe5s zrR9Uy33l#<@LtX^$eY-HLVg*6w#;6JTMh8f^dd=Je-Mpw#y1qaRY_a$g7gzLm>Dh> zs3=RjVePJpY9;%Wj_Qm2$cISM_OMZ6lDU@wHCyl=d<9!zR47Gx-29>p4sb<6|?UxY7?y;Gz-7GY(cY%Sa-n-H{QhtM-hynb= z2l3cTmJT!O5`9GtEBtp>0wrur!_f6X>ywI0Or)@&Ki{~7)R;0lpIu;jr)gkqcTBv- z6q1dZfQn5Tj$3Uy2$%h|@<#amT*HO# zng2M1{`0dX5G~5mq&1Li<6-`XUKAaqPf`DRk=9R~2i2}h%%e(ecb)vZPzS{?9TFvG zY?r!Am$BO+bKtS_on9t)x^60~l{KU*GG`)YacY&FeufO-5#Ec2HeN_l=d*bXB3v0` zba(Cx02?ECi->U*Ey89o_Qp<6S>vJMyQpx~N*~dHvD~G}&xIN6@g}6*5Yn+|Q&{_c z#=jCS8NBa&f401aDvwEw@?Qw8z$A4f*_6B^KlO6XxnUF`U9`ryt?)B!niuw=9ugRo z|8|WkU+=EgxK*UHO5ui1fJ6+wIrEz+lc8gxS+bq@DTrtdq%8Nx^<@`pk?9XR(g}3n z2oLUs zuy4XhbG&q4q)^)6eZZL;B5a;pop$*(_|PY9oLnPR;-QR$_4%8Ca2iLzLf><9AtgI@%b6a~a<98oB zxXF2$un!qA|4uli;sKVCFVomoV+TxvChWp@apfwYD4VjQ*3_%ZX9BMV%CvPZ69s)< zRvj8b$7D^1T=^(gVwa}#9o8>v|BxxLazTECNiKBSk2tZ{epX<21~Prd^Gk`GZ!2H* z2_4&qNSQ_cML55@jrUMJeJ!-D?mgp(cKJDiUZqyZ_)~mw;f?FfTy01dOGWq8;=pq2 z(M|b{dG;Ur9H0Kfz+JCePgTd^=5x1&U&RLgjBQPjX|!VjJ0UpJ`oiJS@TYx(zx{6( z9*(euk&7?Z@;2Xx96K7l*GNC9m<^hn`$US}u1qJqQz}AJz?=}2&SfV(!j@ooSdk&> z&kUB9cGK>fl!^L%l?n$B>mh~jC3P#OkxmbWK98Yc4N>k5oJz)mW(dHo-w!UbJ! zKJi{3JM=08e$Rk$Q?Y^Ks*9P_;R%E5CPH+Qx9(w$o0wAW%bgL`;o|z_yEj< zrR5AA>uJ`_*uU}l@%``gjSv4uga6eepgqG!V$A=0UFdYPQls&cm($~{^ZD_e#(EC% zNIJRZkgOi8i3-im5To5(E^x2*UYnAO!t7M6_!uz0Y4fC?rrj#jtCBVTR20Zqq^{Es zg&AlLtKYgE{}`^*9~T=nRh6Kp)=1Ru%wZW*%oPEaoc=Ik%N}aXh9kpr+}kXS_E4W= zsnxr+35;GK!Li2R6_9F7dJw?ZUTYyMHC@~@EyzQdOQAcgUZ;><9_R(!_ysH=|DxVJ|B-bbCsit zA+>o?yuQje{7bv2mpJ)!>@tiYg_rq9$T@!Sqd!@92BND2xrpkSaAk4@ZGkNo>xY5G zU8p*mJzzzDa$q%@jAkv%e)md4irsgZnH{E-P5zN2GKGl#A#pTq-Pmf1bNe0YsG=Ta z?7ESH9kcTg8?T|BhN&tY&W6!LZH-wp`ME=Ix*NIlfidlP&FSf(Bt1FGi_APZ#)hZ}a-1j3Ckk89Ru5ywAd+$a-$_;3lE#MA51H zI17ELF=M2KkdQ6)Q1{oNHV?J(AI9PD!Ils-Uf?fjWBHf<@kFu0W*U&hn3L`fz6xx8hX2Y&`Q5$=Sp}E*0!7 zee-XD^OcLfqjzMrC7jdG_V}?eJ@gt;Da`e&TM33yqbqOvfXx>`5KW=7FTRfXKW>q3 zh5aTu@X%6L^=_u)==3jjAs2UAbgPG-xcOh2RgX)m=IS$!&7#!b-ZNda5@l}c;Rub| zQ4noABN4PFgj0k#`MzsKr|{DqIeZh?78cT_`d;pg?@hUMWI!2hWsK$&pD0ycDppjs z@m_0Kp1i?n-a&txcxa|Hy zbkZA1x(!RF+n(MepOVp21ty9$II&ujDW*U&a;r7JPa3lzf3e=7k(6eF&yvB#xCvH= zI;-dy61KM^ET)9t(Nflj1ij;suWIJ@(efs9CwX2cM373Bc%+|eJSXf6W?XHe5Ld3g zZU~Mx-=$i-NAfw|H02UnS@qrq>pUE2NNQy9ts+^XT5u6_xPE2Z!P<_qKt0aXM}EXz z(`soFlZW#?Q(+j+E*3H_g~cuNS92|tZRndZYGBf=Xe1!$CF}cUmZs1XbtJ|0xs3wB zap=QfN2a6sURtEdpQSUvYc6IM^TLfbicbPbAO8p_YHrgze|Awg6fa{%uOHdg4Ecu( zGHj5wq7udMGd}wa4zEb%RVZ*geWrhFM=hH85dTKM+CAovU%0|J>A7e7s$zw_gQLRg z=CU&X23gm9S!_~eA2|(JtZ=T{dRzqk=sF$IWF=uypJxHJWZOSU^|93%sNK1)^J#WW zc^X}qe(!}-$8MU+Z1yBP0`o0^wS<68TfdPO+#%m=b(vPHLAYfxm3*tF+7N5iOcQCU zTwuG}Sdoh%Uqpm0V;M;9OEq^Nu7gXL2_TFIy4j_a|I^zJ<#+x*)HYWM+B~-6k>+c-@+#Its zl7FN+t>IQpJX`_ok*qGdnyOR}ChIHdi`ug2^u5y9!juuRX^DTf28Z zzbv^^fsobVpp>(Kw4||U2D>*-$wp4!0D@QyiO=5fai0;O<`H@{u+xVG2|caC+Rrs7 z1TGP(Qx>tF4-f0eaGf-*<9&Zk2q zQNt&on87&kUpg-H;}W=W3$6^--TWay%w3=INn(#8J~^tST6b#6J_88y%i&RK z>|n=Ej8_sn>9kYrGIAxOSTeQY3?7tAU+PB5CE1SitCWmi1HgoK8%d zEy%8T);cnQ6dkMwhbpAd$XHZI=0L3V@p~&o!~*Jd0OhMLf}KN&50H#RB*=byJPD)a znK|3=o6GSBY7(UU^lay0qjJe5wMjs(ncvqU#J8KT?L|3xe0QPjq(?AIWNoesxWHz$ zJg$T=SR2mH1xA|NVP$UN3IUs5_E{olxgw{sV!#C>cCI_4_bHU8O9Wa1k-o;tb$P zLT{oyNbu9s94=>-s#Qc?KTMb4RvvJxU4SJf*qp4=Z+I5$F^1+4Uu7e#H-K$iQ9q~W z9p*wo<1CW9McCP`)I5TC?jJZE2QXLGJik$rZc8xXvlPj%^JnzSLIij9G1988rM8F~ zu1^dR9=a=Mh^wg0t(6(4sU0aXz~8wDba<<_@sG~G!n7c)Cy}t$|De|2=;um*(cpf= zJmp*!rB7$jhREUr-tKEw9nw8y^S7H&Io)0WS(nv&_^kXC-O;o9Z;}4kKP*?*IXkr; zf``JY^n7@0FSvemy*rILrG8ZA8gbxx@+z8D%u%xH6*rg7%h;x8wQIcIT+eP@`UMFs zPBr)g99Wu9XD4QG$KRcMKXgM=ipWN056ze`c z;@3>Xzf^FSytJpe>}|jaJNhfFjpI<0E00p>>sD8N2Kd=OA~l3A1$^{l^y zv@GL%Pc_tS*wtiljs)yk@^?t|Nwz-Rly;=-G5DPO2K?K%@dqV!2h=zhc?d03av`b4 z3xj>_0$o4lXFTf9t?kgi_%z869r+Gh&*t$l3WJgQomOgN7zgEjc=rBZEDyZmp)l31 zah=F#4R0i(++{Ow+~BbFW^{00!R#(pU3Pr$z!Iu}&4+xEAU6`4wDsCOx65!<-oR-K z-OZ?E!KyD_bm$G~e&Ul!HatdEwJNZ>=mJE)X&cr8v)0fwWzS>WV4*+o*aWOV8e8J? zUsZB>u{TtkH0ABal(e+KSI(E-!7limG65|z)|g<79-#AG`gN$l29{xU81BN%2?FS7 z6_;6`FRomD|J#OjTQ7C8P_{OGwQ`dZ@n|6}Kb%53?)g0U;FadT`zKu z4lG>?=%0vsZCbFQHLP+5=Z#?m#ckm>^0gy;9%+H}QISJ)w_ik6V3oxMdP~u~Py8cUr%V`~>sW8+TCwlTn|Q%Y zXH!r4y)t(z)+%SSc5=vy*=?upJy%%)wvRze)yn0Iw!`35fI`zL3tSjditA;HdKtS& zF=C*ZvGnc@@0`k521#d_>%QZ_{0A{b)hei+LX-RlYNgDFxNd_Z;!>O$m_aFtHF!*( zvH;s%DNjT>8zZ{@)V#Yz5q}UQ%4uK53w)4c1gv zIBK5kj^vQATqQ`~oF@mSR(#DGxJ!Q>zv-7My)=&8y@{Ql+jwP4uoPZ;QiA^HG}fw) z7GNZ~=|+DT5xL^d zLV&Hhr>v1k)pHQ9un*sAw9DD4QM-uz$Y#(uaVDzy^8V~GHovX$ngDS6a>!5BuS}xZQSE!P6iMoMH2zL^ zBD8)zGK-w485Lm8y??9~>(7u4*yVHsBT3_?oyrUfUW9&g7d%qfzw}+tOB<>MTwy z8_SnK+J z>>BvOt{7L8-sv$s@70o;A>-QxnO6Km6Df4SiA<+KG31l?^&9oxQ|$VJY`S({b4n{* zMTT&&Q^i`dBM8q ze4!8^A@wnVeW~EaY)VGzgrt|NybGmOGF;z^zM?9?U(vxYp zrID7iC3W!{Vz1#h+n+Cx_$V1MSl-2i7Ft#u6Fk9~{k}%yz7d*QSt@1t?5*kE*mazw;Vx z(07Xu|GB$!Yc(|0Xm0K66-|Nw%JuD(qS>tG&69^Z6szZP<=+wylM$&MNXKUx8-W%P z*HUqj5BnwcLh`_!iu^OW_@n{=uNdvl@zTMZrj=RA&%x$dcM|0ni?p#5+7p{(Jt@Zn zG!HGFk?A1?JC3cxqI3yGzerFyqLx)Cm%}t z?tJmnk9%yrX0|1l1#J69sHq6-o7>>}9+k?%9wYgMXg%3q*zU~d5}B|m$W~4A1~Ugq&&Qz3B`qTAVQRnvgWoff5VQnvqj*8^dbIa zA()_m732dqg^X|$bR^UtHt9wD7Z2sfA>d{cF9-cg%Z zOr}*gO8*Wa#>#u7NR4`EFkzq2KuL7Of-c5lpH$?*Oy4yG{p-ZS1j)_ zbMQ*JJ}UpD1TUACFIZF$rplc6BFyJunrLBiow!}Ca$>MW$y+k7{xkrBV5-up&QU;O zmGuz=FhCO9qs9giI*mitRSas*b_)@W&5pto z`3^NenzHylJR;vOBzzx15On-Bx6BvNnHiY@3ktZoXuOlar?A#c8&Qal3OToqiCxev z>bX)XZ>~k7@@7z}Xd{qnBml%vWS!~1qpC<0MC|N!{gL0EsXkOfOy)#PZLPC@L{$L{ zXR}5Z>$QW@o;4&NYfnqR=kFtFcv zZazbG2%+oQxOO0FuJFr*C@PIK_-z)^>2t?EM3BsHFV~GP z@jdK#!DWSAN+|BHg{r@8b39K447Nt$M+H5k(ni17j!j_Xc3l z34ERZ(|-Zr;gf4%-xWkE3&r5}OFDRNcvQ0`Se?3rsWvz7A+)oBrzD$}vwmM=Ag;y{ zJNymr;4hQC1fMZ=3G7{_mg6x1OLS}qwp3{d@Ey_-uwPLkbB<*mH(ju;L`zQ+670+# z%~{LE_t%PaZr?Xn6DF7>1G4zbu0AFDlZey+8U8dy=(}O+GZ@%_XJ+pVw5(5eOnRHQ zN}gPXJZKRUnZbaarz<$j$zfk5$US|3qOgxW2O)Wjmn|JaN7&s5j^Z!^YgW{=s&A|} zFXJ=mBT09+Y{^YD1g8qekw7pI3r@Y@ zyq!#m~10$kJjyjGIbiKW7?W=>Xm4wavw+~;OYp5jYAgV9Lo zb`seK+|J7e`|ep0AGIqa>w_TJk-t_t;KA>@U&gmfNJR}yx;VtI1v6k5o+=DzaC&fb zKmT=jBd^;;p@&ve`?30)`9fVUN==ObIfT@G`_D@(@bJ$9*NNG9u3L~Vwb0>Lg|ELWWbjIqpGAhbNRB1 z`%x^kh6gR**D5YK*a)XJyIf}-ZzJuhF}d!NH6`y^f_k$51I6P3eR@^({DcdTQeZEl zKd2$C+j18`=$qM`wQYcd0OK?YD%iBT6vMz%@u)7FRj2tzr75fZ#Nl*lXU7p>;LPp3 zZk(DS!4&x!Gwe)wq2p@In5MTPt4IqqPc>jz7Sd;!Tvsg?w9mjadotuEWPCp+X zBqr79s$NL&ga7A_x~U9Z1hdy)>Z@c}Ck|g;lSF3%`&HculK#q06S@qc%x}gVS9%^T z%28>7c3h8e8`VQCZ0pj!-h``o$VwfB=bhZC_BZ5E8{Q*HCdJORVFzG;^;#c3JNNi|@!%Ck-iZuCa6t_}$c`;R-dP(s4AMb(C7IIIAR}+kK9Q*%i8%Ry!VZP+9nGmfXA?Q9!ev zG5v-t8^0R4N?i}4iS>0;#%}*<3q3P^tf-nk{$><>|DstWCYIOVO_nY8z-{R?EGu6p zOow#094x8li`QHHy@}aunE`S=xl_@MGZiuzWF6%4g~vs9E%A8{sGrAl0ML-ViJICx zg^#ZaPhcn@j)xd_#IWyBTsjqj4Tush{zDoHeGtdTUy-wnOt1tUMixcK%oq}MSt71G zJPNRIA!DvrGN_<>vX}-=2ca-#hhf|dZZqj9ugz+{2QDBQ6A?lbsp*QylNHaJ-r?us z{t=@Q3w<*ykZUC?MhUvcorrW3YRvcpn_VK_JFfpOx*Sar#NP4o4uP=>m0r?jWa4<& z*o$UmiJ&5&q;}0*70wV<#Ix|=B}+BC9lbR~Q%zfN3k|1GZmM*h{N~* zO>n1GCcub99!NL4KF&j@Rtd}({o0s45=ZZyh&d8mRnMVoYKUn) z@w}_2;(2e1UWnh?og~97m9fCPQI0_JS&HyHh8>1rFA_`afotMSdO51~WI9Q*pW%$7aSF~)9foGIlJm=s}bb<@iv3yPHN40j`16VMwjFiC^om$tf z|AI<#fA;spwmF_O+-cnNwZvxElEQ5&p8aDq$>xqRHQ1UWA=Fpjmcf8=qIpwji9Z)D zcmW?6Y?{T~`&Nu_@52k*J4>gu!0Ze4iHYxpv%y#$G@8zRqByi7z${Cc4?=KiIq^m7 z4Nr{L-@RWziUJ(J1*e0~N{L>Nx=Ou2!RPzJjqX-wmD$j0`ID@w(CcrLSB0CVHmef! z4=;SGvuA1v;WK7CU_K9&rO+*nyl-zr9jMLo{Uq{~c~um5MV+X2itbCwI1{2aHz;f2 zFg&(H5cL_`^mWQ*lP90J&3!`aS?W5G;DO)jI8jpJb9~@tt+>C60>_KDEM$RMT&w|F zxgb@L1$rLxpT|gOITqUiE7FX`eVDvm+zZndk%5Nk54) zqQ(4o0=5-Guf*nWymv^>dgj)g z5Lu_b(I1!S+saMGpdL0vcpgIkZ;LA`E5?P9&YuU(IHmkWsU%;50aLMqrT(s+?{6e$p2O`a(dKV_`-F6v5$Ld3MUYFW%7@U>71xc!ML%atTNd>IP~}LF7l41l8diWe z95)e(w^o&a1fC{24^t=B)RCvm)b~{2=)$JYijEca4mc0&*07yxlUFTFG!b zg{_&2OoAEZ0&UikB+*9yn{|-iks5&VlocF5TwZdVtC6_koD{(-# z8{1T`Pivgm-po;^fA~n)UYMaWiZ&X?+KUNI)=^)~KVxI4eUYTJOvQNZgSKuS8x-W-M{5ecNNgnrAe~5?J&Wkh!Jf?+f)=0Jp|lmkuzgju1@85Ln9zVzSMyzoT?9mzne{Q^`6FGY+ISgOg0N8G_)5gr(D| z^|0f=-FVHH_W|ay9kSDjmmIx>TR7-Cj06d7k-aa0f6%2~MmCa#0dblWij}d+v!y%r zE!d40qe;a}a zfHSj(==-PR@h6bxe-`cZFGJAHTqdm@Gm&K31N|vB@0e6OE1TdLFd1B=sJ(fREKqN% zHEhmHfYfR3x#6dy5&r}QtO>SKbH5LS#|-Fz4NONo`Pw!1WVmA53HEC9i5*foBc6w6 zas8#<>YGk9?%GIcuaP4Cx4y|ddK_k>Cx>j2C#?|Mz*E}`< zBGy0-c8ix?Llv?uRf{h4i|VLrv`M+Qg#UVIAgV&BG;&?p)x`xqyiG4cLKGd+MJ&oB@=R(r$Jbg%&TrkelY^Z9*i(u) zqZfp;Cd4tvP5nGGCWxlnxN|0ur`O(6C$Oe<+cPI56a1U-@7&2sP6Sfws3_lDIF2)h z6{(*-lXw+YQ-X`klwAqrv%_2rnq3KGZ(ZmCC?@8AKeD&PNo)x24yFu_>)EEuej8Xg zO&4z&6gy2%{xhI)Qa&(c`GyyM1`6N(2a5p(i!ng$;n^ zHXj`wzFo=iF2Xp_l(T5I&hf?`RONDMFy^%U>(D>ge9wbBI(4iDV;^0`|6Nliy(L^jp9+im)Ybo~DZc+xQ`Z{lndvDuHoKWQ`tio; zDf{W#>fkiJNdWYdmL2<4EBn>~$o{6Y-rKmC{ZH*_Q4yF;G>|03>~JqGJPpG!S3BMq z8M`I8{K9f>f^i}gF*^iN8lW`(1CgCx+$x#bDN!+yrl^;*&M?%*0ibIPvF8*bu7oJo zBwUBd(1XeFJBlJFAqP3>A8e9H2!(M1LKD~(Zcz=v>J|pwSs02ZS3rHUOZ5|Nkfs@BdbutJJmMP=>lAmc>_Y z#wA(T3;z6u#aY+Bmc_m$Su7k|CB7%vsv&sINI^(Ss+hf_>A8Uf;31^=L(P!ggj_O& z2v+z}986hB7^*#LykDm?NPl5!-i?I$_{LnPUAt#a1n*OfFWnT4Z@iAFXTXtNDZ<<> zxIO!6DGv^;JrF9d$8RF)K6|)3Utd#JIxn|s{GRR{mp=TCLKBQ%0e_AE;RZAKhWCj} z)Xo(>ev+0J5Bjc_y6<(MS)Al7Wp|T{B5!q}eEuy-x8)~p9AAIStXoz#imWQ53oA!d z65dJ1lB=2bt|F)Z+b?J@KA2R3=~-bdgbK_2_S>(ouvF;22-5a(NW(j4!Ak-dCDhvf zl2iyth>TEP>Mhvw0m@+TW@bqF(~ziddKY-aGnhuHRrvUB}4Y%@4GS= ziZ2A07W$gPD_=_gY+7;k^4!xVO2IO@C(kORu{e7eQxc|=as1XWlBIMS7g}i6d3*f(E{z7zZ`CA zv7F98%BS$PBD+!Ife=X+jj>TB?Td^rMR7UaUHTaWHmMzYBUa&1772`xWgLqRNF9iX zvOTKMmVh{AwvfHDfFubUmnu<1;P8|+ycz|8dPJ2Qe)XPPCmJF8ws=RvtC98iva;pX zI%=0?#$-#gdOA2*ZJ3|LV~wR0+vRvN-ZCqjpUrlTqa; zv}CN$ujO%URJF16wYhccvbj8_;;&?5*r0QtynNii@9DYB_@Y?%l`Y91b}OebL#Oik zE1xJ2LKv9lYB`xr^}eyOr!RETx|)MUC!@OtWFTQQxo~mo(ThAFO4=@`7(fV1e7+aI z@>>qt*$N83ts!Tlp~-=c5G5}|ZYD60OT(3hT9D_GxBPw|KD&`~Qms=STTQB4i@7|+ z!Oat2xiKxlf8(lGvI{E8cZx#Zs*B7XZJ6VP!qe7VCN6OZ>G-Pbl7c8H`VliVE@{GO z#!trfyq+2-R|Vn(BFU;vsJ+N59%`d#neqG*yJvGj=y0h8ya7c=y$ z&8P%lsMXe^dUvciq>y%lE>d=jk=n1`aOwDQM#5y0sf|^WUL#V8Xo8jB8qDAAevw8t ziTyp?Y{vpGcrs?&YYH{>Fol?pwpAeGomp*4`+vH>n|H-Kzau{om#Br+o!`)zGRVsb z9k~To+eBg3U);a@ef4;aDt5>uq^u@MxlA!_;bX{PD!@|BI?B+U=Z3H#a=}&#<(&p9 zBe|v4prKb|2{a2dDHJe-46yu=L1nQQ$Spvj$z~uCCf$f-`_kjEQLPYw&C;l0D&xi- z+l!Q67;vbLUxddA(Y(1XXmgZLZepmg+Epf;UWRW7W#U_Up^yL9012D+Ywre&R*4T& zCB#Yx$R0tl_uHz_qUGU0UyWJaQFTWwt9)Dk9Hk6)r57FstUP)bP7u1;mkDzGa_wNUx4)$ONGq2Flq1(^bEp zQn=4cB2rYVAYU5s4gVf6J|r$bWWJw!DVHP-ix^ezXjMRr7IJsDTu2qeUA8dZ#zp6ip7#RhpaOe zj8*!#-pS?OH2Hv;hC1g)YN-GBL+9%Cpx7MB->2V zeLD>Em8GfBv~Kp@Sj9vo_3)e1;%bzYt|88Zjbn0o+ET;QP2FSu8fg0gjoC9}uoiYC zspO&%_!Jh5lwNJkzNOhb#OnF=D@`~{)BSvY--Bh%9GVT!A71j&J-3}`=8JZ4EJ`_8 zCm-FqG1i*Sw#bJg?ICU6!1Vj%Ya7-2YS9lwS1Loz5ycnuf!rUJASVsE036Pd0*Do< z>tFJ{^x7kFrD8bAXjxTdhA12zoZpO>^KaY@TgVl;yjF5au>#~3f7YI+N;!6FDrETa z6@h=6){mg8XjTUbH4L*YP~leU)r@;+wu~PSm*>(Mu%n5TN=Gpembh5{YPOb+nocB9 z>gxzC1(0(sE~EDAk?Lpj0m(+Rkc}KC2z+kId>3}G%d_v^zX<^N?&35&{TOrt8`&1?Z#f~qxgRFl*Ua16GhZb%-?&kgh7Gp9v z8$W87eDhC(E6~ex`O5 zUTx8hoI}P#XmCYJw&zq6!B-B8Quz96J}ZaAU)aT1I9|P>G`v)q(72$s-Ez2;ZHF)_ z^rdr%VS$%68WNpcf~^BVd7N|2P~5FJh!n?e6q@4Zt8d1`mQg`5+~ zl5huu@>qYbM((Dl;UbHYo`e$p(nWPzK?27>R#8x*e<|(IFB98>$F5gVkNDxSK3?5B z;zq2s5F2OWN9b1S+=^O|taDzx%2bpGxg%UHd@9C5Z3Q>i(w!BW_Q<=xwu$nqcJ;PX z3jJ4AD_Qn1HIZf2ea=9IC^rJ%J-oRVvoAZ5it~YSB-7 z19jZ0b{-<9$1kqpwF&Jia1m|rT%-A2NO&xX^Co6%mC9{Hw}mb0KdL*+sJNP?Q6s_K zB?J-z!QI_mLU12ExXfTdg9Hx{JU9fG1PN}z-2)^@fWaZS`<=Ys`<@f>oduk`?w>o0 zX6-*yPj}Vc-PKjKdx~r-(PA?9YLSR2_6s{W7gp6osaNurq}5J@sq^SOg47j#J8N+Y zt`aIYxTpPMqb#!NU6~LbV!qHW-O3D6*F@hs=_L@L{nlaG-jn+lu|VATL*$G=uVyOL z*(zbdp4}|bfdO4uD@Q749R`Uns3j2Mb8&exGwv#`4 z7GJ2RpSq}t3Z3s9j8Rhwkjb968`#&MVOh8^(S2(@*6$ZFDrNO=}D9M@85+UrO) z{wJ*kjU5NJ&n5*O@pR8-3$8~NlJgZp_b70wv z&3DJ9X7WvxKvW#5G3fX(L9c;jtbByZ*L`4$a5RCUnC-0;T=CSe3{-JcJEBf58Yb62 z4vyWzdrMksg(!u`5UBmJ@4(PrAc?3Q<$b*~D{FGj2Jxyhmub>Fm2kC1Q@TO` zRqsH*(>RIgG4@c}vjZ8OUgc>&`@tYfjhz70uj4OY*W%;VW1D@LCIT!)Bpf-``Ono= zeaFy?_l%80)>^H0o1E60eo6p?6S6pCq;Jx^o*uoTHZmRCzyDYk4kIbLgQkMffs?de zWX-Z?)~I=kbu`4Hdo5P}Bk?Pm)-%!3z8u}AEt27%GQ_FLUD}>9h(tE_7SDx|n!ihs z5CwXHzgRp85Q_}y`ss+yU>YSwm0DxV-#J;#Er(8QL_%!pa=2zu4{v5WF$d#}oz$Ea zUCe7c1!Y>n<~$WF6t^r6OIf*m{vi0=La$`X7Qnt_VM*k?gksohlsRlCtl|1?wXXHU zj%S6sy#R}Dg%I~;1+{IJf-yc_-)RC2zEeZ6A)Ex7gqVlfOd=#;uKwb^(R0OqZl-1_ zHTQSVW4CAoNXF<)Ld-!zJ^IW{NAlJ3l`I3g%1OQEqo>vitxSv??FA_ySGLZdSR)dxRs$(K z3ZZVF*(XkHFY}nUA{l?s4Fajt^WhzFx^ng4mA_U#dSGg25<|z#$yBU%s+K3TQ1`Vm zCo&{`&gi^on!g3lWnhz=dmp1fS~&(Y0bKLZb`+7OHSuJ0h6}YpGaXm?L-Y}=lOs4} zn5SlppuY!ak?aUwdbh{CC)%W@@&|k@@F7jjnUYWj_uff(p+8S1yL`8j*rMVRMHx#z zN2*&(7P#Mfc*B-!#L`QvhAaJQRd>rQMXf4HWE=+5 zx}X%P&81;)E;5p*ZP@z97rbQ~7+j7M!KE?cYHg=EtD521kgdPWzHHOD2Ezz+jC zxrZ5O#bCIfBA`G)q7Yg*2~6`S%i`|9$4kgF-3V;?99#+<6A7U9vBD~vG}@`P<300yx|NKCY_O9u%O43TTBWYe_EG0^CVlBy&chIh-DJX z6gsy%p_cjWB8BOesI;JX7a4yM|MjB9BW;mzsE7s6%w;S^QHKS?dlb2`_du(vxPamSLxsAJ(d^Ck%CC( zE^HkE1(a2reX?T_GvZRkI#1S*NRxnkWLtQSlzAQ#(~x7?xjl~tqwwK?$MlQepM5;8 z%~%!~R%bQfF_YEMoSGD?J5oC}Yh$M4)0$0e=Cq{4dd-gdV=b!6O*0(cM;9nmxe!wF zB)=yqLw?9dr-w>$!E$lG`w5c$1#Q$&UJ#$GCLw3SNck$VYKqWf1L!-=MZK#f;1VU9Eviw~*nyq(1XHwp4M!)jy0@I6!dm=% z%mH4G_>(9?f09N;?5imfAn&&6qvi>kGLspL^3hIg05ZupNOq>ckBKR#tfuI-iv24e z;ioe3+L0V~yC3!3R<6F+e87Ln;R&V*aAxRjg@5-6d8p-G|9SJ~qoSUN-wNBpglDw$ z;{~va&-A6y_UO2PjNcPq1gU3p9jUkW(~ePmoRRM+L|QMmnug}qPVR(j#_Y^G@rdSH zB?VC)nU{5>PMA8j59UVfRh}Iz^CW6{fakpniTOZYPtoN5Qqv=1dqX*8; zYqhgKIS*pmA+GpR-X+jvTbFtfJ^!gveo`lPiUv(LegGL(a$iUyvh&i_6s$9LmKQ= z71V+7Mf|f!z3bR0SXuQ0&?w+ zT1QS+nYW|>iNP6CM{Wgj^-oK?I(~F$J`oZ(=+2C!jXsQAxH~Pry>F0p6!nEs8WR`+%m*1Z^ zdR@=WQl@!lWL)Kt)vwps;iLdu-))Abxo)87t1LI|%5GHsxEQdznnd|hRX=m796SGZ zcfbl-Vj~SKB%<5lH9sf9S z+d1|VYV)sxy9QH{ov)BJD4NrIUxL!a$Y;+%XM?HkN6TwX*AjzDLRa%ESJk@(O&%+` z`nu;0+n)rLNN5_rT^+wvY`UDabKQJiynQB~M|?TueNin|coMxb)e?U&v+ccy<_$U- zAFSQm+gI71ZCW0)bDh#a@mhl$^g7$zM)Wc~luWyF+Mng{KK?EQ^q$8^2|stQ0-O&- z3$bqFX>@}ej3HFucE23CKQTEDF*!K}dC})G`sd|kdmr`%lSF@}Ke1Gr^1bqn^Tl^? zu-IZkybefbFfS}lZwPZ&Jadg-Nj*MYJ9Rd_m}kVvohx%&i+h#|*78Pb@FmzVN0OH??Kdl^D=Dv5T78%(a8& zfiv4ywZp(4`f}IC|mg94=8nQ7p>&8B~4uh#y~G+;&o zbfezK>yzlmXhmt`MrwBdhg^ewvufujScug`4Lb7HU& z12+i2W}QB6Mn+8H!=okiU0%k`yHL#Yfa+3E5+PO0OFx8u+s%}24L{N9dHqMyaX={8 zlos+Ry51*2#D1r0e*R;&~1aJhzjxLNE+Alih&PBJf2)Z)>p8HSG(Gam4~SHBqY`w!SeYAH znpqfFSesj0TDSC(rm5$|C&wXYhkh4!ba?iGpMOqvFH~7&npFj)95S;P3dE5+0Pd?O z*CgxuiGlrKb@lYn&E>tCq2Mr5oPn@^+?=aZ)HXEtwE)}yGYb&^V}Zwg|9=^v`esImGSc?PMSi2a=@*9&hbKaF&>ug7D6wh+TY-PgGcZWn+J<&)PC-4sdlP<~R&QAd1Mac}Hl?q7OMcFfSBsEm;0T+=EGikt@;u zMHq?`-WRX=+!?2(6i;cIrh9BkB__!Y@#N&2z#DI@yXi~R8TL7PhGi5)Uh`8_1|<_? zt`sfP_!g?}{sgP9xH_L7>!$P%z|3nDw|F>=&}XwADwaVDl=cSd(=4IdLC$MzJf0dP zj^Bt632hBuS!uf}z^EU32>20Q#!%Qj`(l}cat`RQa`hcX7s1HPjBqtRpYTLCD$RT)<(2lY#s zcskvqPrue{sa^-_EQf26c>}L?T+GMm;&kaqdxnarI7DAR)(zHo4pv@&3|49q^F!Zs z$(tV{;@NpjDXcfI1k7$>O^6VS|2=Qb|o#NVpG36uMeYo$2M?p~G=R}b7 zN$ethOCz65@uC{lj{;Tv!)o!6f)WjCB@e8`6*>%MBvhmT3c|R@uk06V3VxPqAH(xrJ?_A3qam zfmX;2?eH+bnKqA3;T*QkoT6w2D~gIh>pudkC2Qc+CoYaz6MUt~uzH=mV4NiN@XKbE z&!*fDcyNms0eY={6UswI{)I6T~IGwFM9fwd+T|8ms zz(+O?c4k7^+A(pPSE+`snn$q60ZiwdEWB;U7X*zKFcsF$c5dYZ>Q~7?-Z91e;_C`7 z0-|TUCk*wi5oVo+>Mws5Eyi7MrD-&Qs%E`FNLO$-y-}y0MuAI+$M^X@I}DcF=Jdb3 z(Zzr2UgF*-M*nhZ0Db?-t3ie(aQATVvUmZcRf?Mz!euV$h*!nWVr6A1`{J)@0;?SQ z#SCtdAl_s-o8a$dD%*z!J;4dcY|41rZ5Ygxo&Rm@{T%DZYIX*Oa$l?}9%eZD-R$=? z^73K!QfydjqN1Fjw)kv(yqC)>EU>L8w%nyx0R6=HDBna*aY;jzs(Bw5pZQLuuK%snpYZ@leOi)sR6>+yRM&rS@0m;3 zE&^ZUqr+3@K{=daKwK$kobTE|Fv1`GTb3tZl7)CurI1E_TLGPosiPr-qbbM{z`|%^ z=y+RC^}?GJTbVICT3`DUYHAU!3CHI6bJD98P!~+1#|j&TCNG*Z@Hmt_N~cq}4rd6O zFcb!3xkBNSW;o%KBnKxo)}3$F&9)Qp@PBy$^_=PnBJN`!)Yfl2Oq<(1*{M3Fh1NZ5 zu*~5W2k(GB57;eGhr|3Zxryy-&dTFF;iajg3xVl6JQaf^qxp%>#q0GJQZfFd%<(^J zP>p;&+a4}&T;q|E4y390K9(R}M7dlzzUS~dnOS-}k>1AaY zbxgL#&*UC}=Gx;)Z`5s*cVP4J=`EF_d1uTLk`XH>{Gt-o9E@epV=8*Y=oH_N^cKFo z=>3Lu3!F-6Po_ixOf@ypTLCeR97{e=ae7sgGEBVp%d;nDeDmyvf?WrK(40~Gm`L8M zu8@og_%eD$*20SGX zf*i0Hjf`fa2$rzHd%#3{K$7#_qP#lEe@4LubJrjVe-hk$yaPr#fUZAB)^Aw**-nu~ zu)@sd!FI7f*q!@rCeHk|4|JykXE=s)rMY^PWH2>Z<_Led;IfZ&g~(Da&C8kItsPm? znM%8@@+<0%{0%b%c)xr}V^{W}19iJPT17dqFQx-jjuOy86_u#Aq70)W4>WiJrPpl&Gqr=pkVPFTp5qD-hb!%&=t61yk@1TrI9n`4XxHceMM z;PBqZeR0GhaPvaiaur?brIX&5!1WU^@5u{TB{^sqQdnfjGYj=sndx5_fB%DnBK-Rb z6Y5gr*X3VDr)sKj|5ID~M_uWkqO7z-1Ahtl)sX)d1+gd8XCI+|MEzB_db_-TSHKds zU7cq`zS#n4xc}q&G3 zH$+c-|4UcLkh<7g887e42-?Lh$%M$4fQ;p)Jp%FXV3^&P;hu96;!6VsM9&E1Kw&6C)bYI5JR~df4cVl>qBqe`l=n-NAqqy5Em+vqJoL z2Aseh3`o8B{TMfsA-^-cl<#0bQX}_c+zihD&QMmpg8>QE-;Z%K$o@NH>n;W) Date: Mon, 14 Mar 2016 09:06:11 +0100 Subject: [PATCH 47/49] Fix test bug: norms are on by default on _all. --- .../elasticsearch/index/mapper/all/SimpleAllMapperTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java index 762a62f3756..501c538b870 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/all/SimpleAllMapperTests.java @@ -223,7 +223,7 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase { } public void testRandom() throws Exception { - boolean norms = false; + boolean norms = true; boolean stored = false; boolean enabled = true; boolean tv_stored = false; From c90b4f3bae4a87c8618b91db087cd85ec2e1eab9 Mon Sep 17 00:00:00 2001 From: Clinton Gormley Date: Mon, 14 Mar 2016 09:58:46 +0100 Subject: [PATCH 48/49] Docs: Added note about upgrading from 1.x to 5.x --- docs/reference/migration/index.asciidoc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/reference/migration/index.asciidoc b/docs/reference/migration/index.asciidoc index f8d742b3b67..0dda43da713 100644 --- a/docs/reference/migration/index.asciidoc +++ b/docs/reference/migration/index.asciidoc @@ -8,11 +8,14 @@ your application from one version of Elasticsearch to another. As a general rule: -* Migration between major versions -- e.g. `1.x` to `2.x` -- +* Migration between minor versions -- e.g. `5.x` to `5.y` -- can be + performed by <>. + +* Migration between consecutive major versions -- e.g. `2.x` to `5.x` -- requires a <>. -* Migration between minor versions -- e.g. `1.x` to `1.y` -- can be - performed by <>. +* Migration between non-consecutive major versions -- e.g. `1.x` to `5.x` -- + is not supported. See <> for more info. -- From c3cd8564df0ff836d996a618397a00a8a583abca Mon Sep 17 00:00:00 2001 From: Clinton Gormley Date: Mon, 14 Mar 2016 10:46:31 +0100 Subject: [PATCH 49/49] Corrected regexp syntax docs for COMPLEMENT --- docs/reference/query-dsl/regexp-syntax.asciidoc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/reference/query-dsl/regexp-syntax.asciidoc b/docs/reference/query-dsl/regexp-syntax.asciidoc index e57d0e1c779..68ca5912458 100644 --- a/docs/reference/query-dsl/regexp-syntax.asciidoc +++ b/docs/reference/query-dsl/regexp-syntax.asciidoc @@ -220,12 +220,20 @@ Complement:: -- The complement is probably the most useful option. The shortest pattern that -follows a tilde `"~"` is negated. For the string `"abcdef"`: +follows a tilde `"~"` is negated. For instance, `"ab~cd" means: + +* Starts with `a` +* Followed by `b` +* Followed by a string of any length that it anything but `c` +* Ends with `d` + +For the string `"abcdef"`: ab~df # match - ab~cf # no match - a~(cd)f # match - a~(bc)f # no match + ab~cf # match + ab~cdef # no match + a~(cb)def # match + a~(bc)def # no match Enabled with the `COMPLEMENT` or `ALL` flags.