diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MarvelPlugin.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MarvelPlugin.java index ab7ad4f9758..9969777d11f 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MarvelPlugin.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MarvelPlugin.java @@ -6,13 +6,12 @@ package org.elasticsearch.marvel; import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.ClusterModule; -import org.elasticsearch.cluster.settings.Validator; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.marvel.agent.AgentService; import org.elasticsearch.marvel.agent.collector.CollectorModule; import org.elasticsearch.marvel.agent.exporter.ExporterModule; @@ -33,7 +32,6 @@ import org.elasticsearch.xpack.XPackPlugin; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Map; public class MarvelPlugin extends Plugin { @@ -110,10 +108,16 @@ public class MarvelPlugin extends Plugin { } } - public void onModule(ClusterModule module) { - Exporters.registerDynamicSettings(module); - for (Map.Entry setting : MarvelSettings.dynamicSettings().entrySet()) { - module.registerClusterDynamicSetting(setting.getKey(), setting.getValue()); - } + public void onModule(SettingsModule module) { + module.registerSetting(Exporters.EXPORTERS_SETTING); + module.registerSetting(MarvelSettings.INDICES_SETTING); + module.registerSetting(MarvelSettings.INTERVAL_SETTING); + module.registerSetting(MarvelSettings.INDEX_RECOVERY_TIMEOUT_SETTING); + module.registerSetting(MarvelSettings.INDEX_STATS_TIMEOUT_SETTING); + module.registerSetting(MarvelSettings.INDICES_STATS_TIMEOUT_SETTING); + module.registerSetting(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY_SETTING); + module.registerSetting(MarvelSettings.COLLECTORS_SETTING); + module.registerSetting(MarvelSettings.CLUSTER_STATE_TIMEOUT_SETTING); + module.registerSetting(MarvelSettings.CLUSTER_STATS_TIMEOUT_SETTING); } } diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/AgentService.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/AgentService.java index 5ba84e921e4..cf783efe9e3 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/AgentService.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/AgentService.java @@ -9,6 +9,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.CollectionUtils; @@ -20,33 +21,33 @@ import org.elasticsearch.marvel.agent.exporter.Exporter; import org.elasticsearch.marvel.agent.exporter.Exporters; import org.elasticsearch.marvel.agent.exporter.MarvelDoc; import org.elasticsearch.marvel.agent.settings.MarvelSettings; -import org.elasticsearch.node.settings.NodeSettingsService; import java.util.*; +import java.util.concurrent.TimeUnit; -public class AgentService extends AbstractLifecycleComponent implements NodeSettingsService.Listener { +public class AgentService extends AbstractLifecycleComponent { private volatile ExportingWorker exportingWorker; private volatile Thread workerThread; private volatile long samplingInterval; - - private final MarvelSettings marvelSettings; - private final Collection collectors; + private final String[] settingsCollectors; private final Exporters exporters; @Inject - public AgentService(Settings settings, NodeSettingsService nodeSettingsService, - MarvelSettings marvelSettings, Set collectors, Exporters exporters) { + public AgentService(Settings settings, ClusterSettings clusterSettings, Set collectors, Exporters exporters) { super(settings); - this.marvelSettings = marvelSettings; - this.samplingInterval = marvelSettings.interval().millis(); - - this.collectors = Collections.unmodifiableSet(filterCollectors(collectors, marvelSettings.collectors())); + samplingInterval = MarvelSettings.INTERVAL_SETTING.get(settings).millis(); + settingsCollectors = MarvelSettings.COLLECTORS_SETTING.get(settings).toArray(new String[0]); + clusterSettings.addSettingsUpdateConsumer(MarvelSettings.INTERVAL_SETTING, this::setInterval); + this.collectors = Collections.unmodifiableSet(filterCollectors(collectors, settingsCollectors)); this.exporters = exporters; + } - nodeSettingsService.addListener(this); + private void setInterval(TimeValue interval) { + this.samplingInterval = interval.millis(); + applyIntervalSettings(); } protected Set filterCollectors(Set collectors, String[] filters) { @@ -136,14 +137,12 @@ public class AgentService extends AbstractLifecycleComponent imple } } - @Override - public void onRefreshSettings(Settings settings) { - TimeValue newSamplingInterval = settings.getAsTime(MarvelSettings.INTERVAL, null); - if (newSamplingInterval != null && newSamplingInterval.millis() != samplingInterval) { - logger.info("sampling interval updated to [{}]", newSamplingInterval); - samplingInterval = newSamplingInterval.millis(); - applyIntervalSettings(); - } + public TimeValue getSamplingInterval() { + return new TimeValue(samplingInterval, TimeUnit.MILLISECONDS); + } + + public String[] collectors() { + return settingsCollectors; } class ExportingWorker implements Runnable { diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/exporter/Exporters.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/exporter/Exporters.java index 4702974e306..25e9220dbce 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/exporter/Exporters.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/exporter/Exporters.java @@ -6,48 +6,70 @@ package org.elasticsearch.marvel.agent.exporter; import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.cluster.ClusterService; -import org.elasticsearch.cluster.settings.Validator; import org.elasticsearch.common.component.AbstractLifecycleComponent; +import org.elasticsearch.common.component.Lifecycle; 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.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.marvel.agent.exporter.local.LocalExporter; import org.elasticsearch.marvel.shield.MarvelSettingsFilter; -import org.elasticsearch.node.settings.NodeSettingsService; import java.util.*; /** * */ -public class Exporters extends AbstractLifecycleComponent implements Iterable, NodeSettingsService.Listener { +public class Exporters extends AbstractLifecycleComponent implements Iterable { - static final String EXPORTERS_SETTING = "marvel.agent.exporters"; + public static final Setting EXPORTERS_SETTING = Setting.groupSetting("marvel.agent.exporters.", true, Setting.Scope.CLUSTER); private final Map factories; private final MarvelSettingsFilter settingsFilter; private final ClusterService clusterService; private volatile CurrentExporters exporters = CurrentExporters.EMPTY; + private volatile Settings exporterSettings; @Inject public Exporters(Settings settings, Map factories, MarvelSettingsFilter settingsFilter, ClusterService clusterService, - NodeSettingsService nodeSettingsService) { + ClusterSettings clusterSettings) { super(settings); this.factories = factories; this.settingsFilter = settingsFilter; this.clusterService = clusterService; - nodeSettingsService.addListener(this); + exporterSettings = EXPORTERS_SETTING.get(settings); + clusterSettings.addSettingsUpdateConsumer(EXPORTERS_SETTING, this::setExportersSetting); + + } + + private synchronized void setExportersSetting(Settings exportersSetting) { + this.exporterSettings = exportersSetting; + if (this.lifecycleState() == Lifecycle.State.STARTED) { + + CurrentExporters existing = exporters; + Settings updatedSettings = exportersSetting; + if (updatedSettings.names().isEmpty()) { + return; + } + this.exporters = initExporters(Settings.builder() + .put(existing.settings) + .put(updatedSettings) + .build()); + existing.close(logger); + } } @Override protected void doStart() { - exporters = initExporters(settings.getAsSettings(EXPORTERS_SETTING)); + synchronized (this) { + exporters = initExporters(exporterSettings); + } } @Override @@ -104,20 +126,6 @@ public class Exporters extends AbstractLifecycleComponent implements return bulks.isEmpty() ? null : new ExportBulk.Compound(bulks); } - @Override - public void onRefreshSettings(Settings settings) { - CurrentExporters existing = exporters; - Settings updatedSettings = settings.getAsSettings(EXPORTERS_SETTING); - if (updatedSettings.names().isEmpty()) { - return; - } - this.exporters = initExporters(Settings.builder() - .put(existing.settings) - .put(updatedSettings) - .build()); - existing.close(logger); - } - // TODO only rebuild the exporters that need to be updated according to settings CurrentExporters initExporters(Settings settings) { Set singletons = new HashSet<>(); @@ -167,10 +175,6 @@ public class Exporters extends AbstractLifecycleComponent implements return new CurrentExporters(settings, exporters); } - public static void registerDynamicSettings(ClusterModule clusterModule) { - clusterModule.registerClusterDynamicSetting(EXPORTERS_SETTING + "*", Validator.EMPTY); - } - static class CurrentExporters implements Iterable { static final CurrentExporters EMPTY = new CurrentExporters(Settings.EMPTY, Collections.emptyMap()); diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSetting.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSetting.java deleted file mode 100644 index ea9562a906f..00000000000 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSetting.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.marvel.agent.settings; - -import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.unit.TimeValue; - -import java.util.Arrays; - -public abstract class MarvelSetting { - - private final String name; - private final String description; - - private final V defaultValue; - private volatile V value; - - MarvelSetting(String name, String description, V defaultValue) { - this.name = name; - this.description = description; - this.defaultValue = defaultValue; - this.value = defaultValue; - } - - abstract boolean onRefresh(Settings settings); - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public V getValue() { - return value; - } - - public V getDefaultValue() { - return defaultValue; - } - - public synchronized void setValue(V value) { - this.value = value; - } - - public String getValueAsString() { - return getValue() != null ? getValue().toString() : "null"; - } - - @Override - public String toString() { - return "marvel setting [" + getName() + " : " + getValueAsString() + "]"; - } - - public static BooleanSetting booleanSetting(String name, Boolean defaultValue, String description) { - return new BooleanSetting(name, description, defaultValue); - } - - public static StringSetting stringSetting(String name, String defaultValue, String description) { - return new StringSetting(name, description, defaultValue); - } - - public static StringArraySetting arraySetting(String name, String[] defaultValue, String description) { - return new StringArraySetting(name, description, defaultValue); - } - - public static TimeValueSetting timeSetting(String name, TimeValue defaultValue, String description) { - return new TimeValueSetting(name, description, defaultValue); - } - - public static TimeoutValueSetting timeoutSetting(String name, TimeValue defaultTimeoutValue, String description) { - return new TimeoutValueSetting(name, description, defaultTimeoutValue); - } - - static class BooleanSetting extends MarvelSetting { - - BooleanSetting(String name, String description, Boolean defaultValue) { - super(name, description, defaultValue); - } - - @Override - boolean onRefresh(Settings settings) { - Boolean updated = settings.getAsBoolean(getName(), null); - if ((updated != null) && !updated.equals(getValue())) { - setValue(updated); - return true; - } - return false; - } - } - - static class StringSetting extends MarvelSetting { - - StringSetting(String name, String description, String defaultValue) { - super(name, description, defaultValue); - } - - @Override - boolean onRefresh(Settings settings) { - String updated = settings.get(getName(), null); - if ((updated != null) && !updated.equals(getValue())) { - setValue(updated); - return true; - } - return false; - } - } - - static class StringArraySetting extends MarvelSetting { - - StringArraySetting(String name, String description, String[] defaultValue) { - super(name, description, defaultValue); - } - - @Override - boolean onRefresh(Settings settings) { - String[] updated = settings.getAsArray(getName(), null); - if ((updated != null) && (!Arrays.equals(updated, getValue()))) { - setValue(updated); - return true; - } - return false; - } - - @Override - public String getValueAsString() { - return Strings.arrayToCommaDelimitedString(getValue()); - } - } - - static class TimeValueSetting extends MarvelSetting { - - TimeValueSetting(String name, String description, TimeValue defaultValue) { - super(name, description, defaultValue); - } - - @Override - boolean onRefresh(Settings settings) { - TimeValue updated = get(settings, null); - if ((updated != null) && ((getValue() == null) || (updated.millis() != getValue().millis()))) { - setValue(updated); - return true; - } - return false; - } - - private TimeValue get(Settings settings, TimeValue defaultValue) { - try { - TimeValue t = settings.getAsTime(getName(), defaultValue); - if (t != null) { - return t; - } - } catch (ElasticsearchParseException e) { - Long l = settings.getAsLong(getName(), defaultValue != null ? defaultValue.millis() : null); - if (l != null) { - return TimeValue.timeValueMillis(l); - } - } - return null; - } - } - - static class TimeoutValueSetting extends TimeValueSetting { - - TimeoutValueSetting(String name, String description, TimeValue defaultValue) { - super(name, description, defaultValue); - } - } -} diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSettings.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSettings.java index d1c52a0fae7..0480105aa5c 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSettings.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/settings/MarvelSettings.java @@ -5,24 +5,18 @@ */ package org.elasticsearch.marvel.agent.settings; -import org.elasticsearch.cluster.settings.Validator; -import org.elasticsearch.common.Strings; 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.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.marvel.MarvelPlugin; -import org.elasticsearch.xpack.XPackPlugin; -import org.elasticsearch.node.settings.NodeSettingsService; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.function.Function; -import static org.elasticsearch.marvel.agent.settings.MarvelSetting.*; - -public class MarvelSettings extends AbstractComponent implements NodeSettingsService.Listener { +public class MarvelSettings extends AbstractComponent { private static final String PREFIX = MarvelPlugin.NAME + ".agent."; @@ -30,150 +24,104 @@ public class MarvelSettings extends AbstractComponent implements NodeSettingsSer public static final String MARVEL_DATA_INDEX_NAME = MARVEL_INDICES_PREFIX + "data"; public static final TimeValue MAX_LICENSE_GRACE_PERIOD = TimeValue.timeValueHours(7 * 24); - public static final String INTERVAL = PREFIX + "interval"; - public static final String INDEX_STATS_TIMEOUT = PREFIX + "index.stats.timeout"; - public static final String INDICES_STATS_TIMEOUT = PREFIX + "indices.stats.timeout"; - public static final String INDICES = PREFIX + "indices"; - public static final String CLUSTER_STATE_TIMEOUT = PREFIX + "cluster.state.timeout"; - public static final String CLUSTER_STATS_TIMEOUT = PREFIX + "cluster.stats.timeout"; - public static final String INDEX_RECOVERY_TIMEOUT = PREFIX + "index.recovery.timeout"; - public static final String INDEX_RECOVERY_ACTIVE_ONLY = PREFIX + "index.recovery.active_only"; - public static final String COLLECTORS = PREFIX + "collectors"; + /** Sampling interval between two collections (default to 10s) */ + public static final Setting INTERVAL_SETTING = Setting.timeSetting(PREFIX + "interval", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** Timeout value when collecting index statistics (default to 10m) */ + public static final Setting INDEX_STATS_TIMEOUT_SETTING = Setting.timeSetting(PREFIX + "index.stats.timeout", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** Timeout value when collecting total indices statistics (default to 10m) */ + public static final Setting INDICES_STATS_TIMEOUT_SETTING = Setting.timeSetting(PREFIX + "indices.stats.timeout", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** List of indices names whose stats will be exported (default to all indices) */ + public static final Setting> INDICES_SETTING = Setting.listSetting(PREFIX + "indices", Collections.emptyList(), Function.identity(), true, Setting.Scope.CLUSTER); + /** Timeout value when collecting the cluster state (default to 10m) */ + public static final Setting CLUSTER_STATE_TIMEOUT_SETTING = Setting.timeSetting(PREFIX + "cluster.state.timeout", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** Timeout value when collecting the recovery information (default to 10m) */ + public static final Setting CLUSTER_STATS_TIMEOUT_SETTING = Setting.timeSetting(PREFIX + "cluster.stats.timeout", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** Timeout value when collecting the recovery information (default to 10m) */ + public static final Setting INDEX_RECOVERY_TIMEOUT_SETTING = Setting.timeSetting(PREFIX + "index.recovery.timeout", TimeValue.timeValueSeconds(10), true, Setting.Scope.CLUSTER); + /** Flag to indicate if only active recoveries should be collected (default to false: all recoveries are collected) */ + public static final Setting INDEX_RECOVERY_ACTIVE_ONLY_SETTING = Setting.boolSetting(PREFIX + "index.recovery.active_only", false, true, Setting.Scope.CLUSTER) ; + /** List of collectors allowed to collect data (default to all)*/ + public static final Setting> COLLECTORS_SETTING = Setting.listSetting(PREFIX + "collectors", Collections.emptyList(), Function.identity(), false, Setting.Scope.CLUSTER); - private Map settings = Collections.emptyMap(); + private TimeValue indexStatsTimeout; + private TimeValue indicesStatsTimeout; + private TimeValue clusterStateTimeout; + private TimeValue clusterStatsTimeout; + private TimeValue recoveryTimeout; + private boolean recoveryActiveOnly; + private String[] indices; @Inject - public MarvelSettings(Settings clusterSettings, NodeSettingsService nodeSettingsService) { - super(clusterSettings); + public MarvelSettings(Settings settings, ClusterSettings clusterSettings) { + super(settings); logger.trace("initializing marvel settings"); - this.settings = defaultSettings(); - - logger.trace("updating marvel settings with cluster settings"); - updateSettings(clusterSettings); - - logger.trace("registering the service as a node settings listener"); - nodeSettingsService.addListener(this); - } - - private Map defaultSettings() { - Map map = new HashMap<>(); - map.put(INTERVAL, timeSetting(INTERVAL, TimeValue.timeValueSeconds(10), - "Sampling interval between two collections (default to 10s)")); - map.put(INDEX_STATS_TIMEOUT, timeoutSetting(INDEX_STATS_TIMEOUT, TimeValue.timeValueMinutes(10), - "Timeout value when collecting index statistics (default to 10m)")); - map.put(INDICES_STATS_TIMEOUT, timeoutSetting(INDICES_STATS_TIMEOUT, TimeValue.timeValueMinutes(10), - "Timeout value when collecting total indices statistics (default to 10m)")); - map.put(INDICES, arraySetting(INDICES, Strings.EMPTY_ARRAY, - "List of indices names whose stats will be exported (default to all indices)")); - map.put(CLUSTER_STATE_TIMEOUT, timeoutSetting(CLUSTER_STATE_TIMEOUT, TimeValue.timeValueMinutes(10), - "Timeout value when collecting the cluster state (default to 10m)")); - map.put(CLUSTER_STATS_TIMEOUT, timeoutSetting(CLUSTER_STATS_TIMEOUT, TimeValue.timeValueMinutes(10), - "Timeout value when collecting the cluster statistics (default to 10m)")); - map.put(INDEX_RECOVERY_TIMEOUT, timeoutSetting(INDEX_RECOVERY_TIMEOUT, TimeValue.timeValueMinutes(10), - "Timeout value when collecting the recovery information (default to 10m)")); - map.put(INDEX_RECOVERY_ACTIVE_ONLY, booleanSetting(INDEX_RECOVERY_ACTIVE_ONLY, Boolean.FALSE, - "Flag to indicate if only active recoveries should be collected (default to false: all recoveries are collected)")); - map.put(COLLECTORS, arraySetting(COLLECTORS, Strings.EMPTY_ARRAY, - "List of collectors allowed to collect data (default to all)")); - return Collections.unmodifiableMap(map); - } - - public static Map dynamicSettings() { - Map dynamics = new HashMap<>(); - dynamics.put(INTERVAL, Validator.TIME); - dynamics.put(INDEX_STATS_TIMEOUT, Validator.TIMEOUT); - dynamics.put(INDICES_STATS_TIMEOUT, Validator.TIMEOUT); - dynamics.put(INDICES + ".*", Validator.EMPTY); - dynamics.put(CLUSTER_STATE_TIMEOUT, Validator.TIMEOUT); - dynamics.put(CLUSTER_STATS_TIMEOUT, Validator.TIMEOUT); - dynamics.put(INDEX_RECOVERY_TIMEOUT, Validator.TIMEOUT); - dynamics.put(INDEX_RECOVERY_ACTIVE_ONLY, Validator.BOOLEAN); - return dynamics; - } - - @Override - public void onRefreshSettings(Settings clusterSettings) { - if (clusterSettings.names() == null || clusterSettings.names().isEmpty()) { - return; - } - updateSettings(clusterSettings); - } - - private void updateSettings(Settings clusterSettings) { - for (MarvelSetting setting : settings.values()) { - if (setting.onRefresh(clusterSettings)) { - logger.info("{} updated", setting); - } - } - } - - /** - * Returns the setting corresponding to the given name - * - * @param name The given name - * @return The associated setting, null if not found - */ - MarvelSetting getSetting(String name) { - MarvelSetting setting = settings.get(name); - if (setting == null) { - throw new IllegalArgumentException("no marvel setting initialized for [" + name + "]"); - } - return setting; - } - - /** - * Returns the settings corresponding to the given name - * - * @param name The given name - * @return The associated setting - */ - T getSettingValue(String name) { - MarvelSetting setting = getSetting(name); - if (setting == null) { - throw new IllegalArgumentException("no marvel setting initialized for [" + name + "]"); - } - return (T) setting.getValue(); - } - - Collection settings() { - return settings.values(); - } - - public TimeValue interval() { - return getSettingValue(INTERVAL); + setIndexStatsTimeout(INDEX_STATS_TIMEOUT_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(INDEX_STATS_TIMEOUT_SETTING, this::setIndexStatsTimeout); + setIndicesStatsTimeout(INDICES_STATS_TIMEOUT_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(INDICES_STATS_TIMEOUT_SETTING, this::setIndicesStatsTimeout); + setIndices(INDICES_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(INDICES_SETTING, this::setIndices); + setClusterStateTimeout(CLUSTER_STATE_TIMEOUT_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(CLUSTER_STATE_TIMEOUT_SETTING, this::setClusterStateTimeout); + setClusterStatsTimeout(CLUSTER_STATS_TIMEOUT_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(CLUSTER_STATS_TIMEOUT_SETTING, this::setClusterStatsTimeout); + setRecoveryTimeout(INDEX_RECOVERY_TIMEOUT_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(INDEX_RECOVERY_TIMEOUT_SETTING, this::setRecoveryTimeout); + setRecoveryActiveOnly(INDEX_RECOVERY_ACTIVE_ONLY_SETTING.get(settings)); + clusterSettings.addSettingsUpdateConsumer(INDEX_RECOVERY_ACTIVE_ONLY_SETTING, this::setRecoveryActiveOnly); } public TimeValue indexStatsTimeout() { - return getSettingValue(INDEX_STATS_TIMEOUT); + return indexStatsTimeout; } - public TimeValue indicesStatsTimeout() { - return getSettingValue(INDICES_STATS_TIMEOUT); - } + public TimeValue indicesStatsTimeout() { return indicesStatsTimeout; } public String[] indices() { - return getSettingValue(INDICES); + return indices; } public TimeValue clusterStateTimeout() { - return getSettingValue(CLUSTER_STATE_TIMEOUT); + return clusterStateTimeout; } public TimeValue clusterStatsTimeout() { - return getSettingValue(CLUSTER_STATS_TIMEOUT); + return clusterStatsTimeout; } public TimeValue recoveryTimeout() { - return getSettingValue(INDEX_RECOVERY_TIMEOUT); + return recoveryTimeout; } - public boolean recoveryActiveOnly() { - return getSettingValue(INDEX_RECOVERY_ACTIVE_ONLY); + public boolean recoveryActiveOnly() { return recoveryActiveOnly; } + + private void setIndexStatsTimeout(TimeValue indexStatsTimeout) { + this.indexStatsTimeout = indexStatsTimeout; } - public String[] collectors() { - return getSettingValue(COLLECTORS); + private void setIndicesStatsTimeout(TimeValue indicesStatsTimeout) { + this.indicesStatsTimeout = indicesStatsTimeout; + } + + private void setClusterStateTimeout(TimeValue clusterStateTimeout) { + this.clusterStateTimeout = clusterStateTimeout; + } + + private void setClusterStatsTimeout(TimeValue clusterStatsTimeout) { + this.clusterStatsTimeout = clusterStatsTimeout; + } + + private void setRecoveryTimeout(TimeValue recoveryTimeout) { + this.recoveryTimeout = recoveryTimeout; + } + + private void setRecoveryActiveOnly(boolean recoveryActiveOnly) { + this.recoveryActiveOnly = recoveryActiveOnly; + } + + private void setIndices(List indices) { + this.indices = indices.toArray(new String[0]); } } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/AbstractCollectorTestCase.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/AbstractCollectorTestCase.java index a92f5c73480..5c2ed9f650e 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/AbstractCollectorTestCase.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/AbstractCollectorTestCase.java @@ -55,7 +55,7 @@ public class AbstractCollectorTestCase extends MarvelIntegTestCase { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) .put(Node.HTTP_ENABLED, false) - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexRecoveryCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexRecoveryCollectorTests.java index 71cd0508b74..50f1054cdb8 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexRecoveryCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexRecoveryCollectorTests.java @@ -39,8 +39,8 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { protected Settings nodeSettings(int nodeOrdinal) { return settingsBuilder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY, activeOnly) - .put(MarvelSettings.INDICES, indexName) + .put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY_SETTING.getKey(), activeOnly) + .put(MarvelSettings.INDICES_SETTING.getKey(), indexName) .build(); } @@ -156,7 +156,7 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { } public void testEmptyCluster() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, Strings.EMPTY_ARRAY)); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), Strings.EMPTY_ARRAY)); waitForNoBlocksOnNode(node); try { @@ -167,7 +167,7 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterAllIndices() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, MetaData.ALL)); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), MetaData.ALL)); waitForNoBlocksOnNode(node); try { @@ -178,7 +178,7 @@ public class IndexRecoveryCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterMissingIndex() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, "unknown")); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), "unknown")); waitForNoBlocksOnNode(node); try { diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexStatsCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexStatsCollectorTests.java index 82b16e41d26..9baebfb7c51 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexStatsCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndexStatsCollectorTests.java @@ -44,7 +44,7 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterAllIndices() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, MetaData.ALL)); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), MetaData.ALL)); waitForNoBlocksOnNode(node); try { @@ -55,7 +55,7 @@ public class IndexStatsCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterMissingIndex() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, "unknown")); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), "unknown")); waitForNoBlocksOnNode(node); try { diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndicesStatsCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndicesStatsCollectorTests.java index fe4e8efc8ad..66ef6e75092 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndicesStatsCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/indices/IndicesStatsCollectorTests.java @@ -46,7 +46,7 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterAllIndices() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, MetaData.ALL)); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), MetaData.ALL)); waitForNoBlocksOnNode(node); try { @@ -57,7 +57,7 @@ public class IndicesStatsCollectorTests extends AbstractCollectorTestCase { } public void testEmptyClusterMissingIndex() throws Exception { - final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES, "unknown")); + final String node = internalCluster().startNode(settingsBuilder().put(MarvelSettings.INDICES_SETTING.getKey(), "unknown")); waitForNoBlocksOnNode(node); try { diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/shards/ShardsCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/shards/ShardsCollectorTests.java index e87a5b18190..e9eeb9cacfd 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/shards/ShardsCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/shards/ShardsCollectorTests.java @@ -31,7 +31,7 @@ public class ShardsCollectorTests extends AbstractCollectorTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INDICES, "test-shards*") + .put(MarvelSettings.INDICES_SETTING.getKey(), "test-shards*") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/AbstractExporterTemplateTestCase.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/AbstractExporterTemplateTestCase.java index 1fbfdc1ea78..da8f7be7fed 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/AbstractExporterTemplateTestCase.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/AbstractExporterTemplateTestCase.java @@ -34,7 +34,7 @@ public abstract class AbstractExporterTemplateTestCase extends MarvelIntegTestCa protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder settings = Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1"); + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1"); for (Map.Entry setting : exporterSettings().getAsMap().entrySet()) { settings.put("marvel.agent.exporters._exporter." + setting.getKey(), setting.getValue()); diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java index 91db50c1a39..5be1bbcaa81 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java @@ -7,21 +7,18 @@ package org.elasticsearch.marvel.agent.exporter; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.marvel.agent.exporter.local.LocalExporter; import org.elasticsearch.marvel.agent.renderer.RendererRegistry; +import org.elasticsearch.marvel.agent.settings.MarvelSettings; import org.elasticsearch.marvel.shield.MarvelSettingsFilter; import org.elasticsearch.marvel.shield.SecuredClient; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.test.ESTestCase; import org.junit.Before; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import static org.hamcrest.Matchers.containsString; @@ -45,7 +42,7 @@ public class ExportersTests extends ESTestCase { private Map factories; private MarvelSettingsFilter settingsFilter; private ClusterService clusterService; - private NodeSettingsService nodeSettingsService; + private ClusterSettings clusterSettings; @Before public void init() throws Exception { @@ -57,10 +54,9 @@ public class ExportersTests extends ESTestCase { // we always need to have the local exporter as it serves as the default one factories.put(LocalExporter.TYPE, new LocalExporter.Factory(securedClient, clusterService, mock(RendererRegistry.class))); - + clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList(MarvelSettings.COLLECTORS_SETTING, MarvelSettings.INTERVAL_SETTING, Exporters.EXPORTERS_SETTING))); settingsFilter = mock(MarvelSettingsFilter.class); - nodeSettingsService = mock(NodeSettingsService.class); - exporters = new Exporters(Settings.EMPTY, factories, settingsFilter, clusterService, nodeSettingsService); + exporters = new Exporters(Settings.EMPTY, factories, settingsFilter, clusterService, clusterSettings); } public void testInitExportersDefault() throws Exception { @@ -170,14 +166,13 @@ public class ExportersTests extends ESTestCase { public void testSettingsUpdate() throws Exception { Exporter.Factory factory = spy(new TestFactory("_type", false)); factories.put("_type", factory); - TestNodeSettingsService nodeSettingsService = new TestNodeSettingsService(); final AtomicReference settingsHolder = new AtomicReference<>(); exporters = new Exporters(Settings.builder() .put("marvel.agent.exporters._name0.type", "_type") .put("marvel.agent.exporters._name1.type", "_type") - .build(), factories, settingsFilter, clusterService, nodeSettingsService) { + .build(), factories, settingsFilter, clusterService, clusterSettings) { @Override CurrentExporters initExporters(Settings settings) { settingsHolder.set(settings); @@ -196,8 +191,7 @@ public class ExportersTests extends ESTestCase { .put("marvel.agent.exporters._name0.foo", "bar") .put("marvel.agent.exporters._name1.foo", "bar") .build(); - nodeSettingsService.updateSettings(update); - + clusterSettings.applySettings(update); assertThat(settingsHolder.get(), notNullValue()); settings = settingsHolder.get().getAsMap(); assertThat(settings.size(), is(4)); @@ -215,7 +209,7 @@ public class ExportersTests extends ESTestCase { Exporters exporters = new Exporters(Settings.builder() .put("marvel.agent.exporters._name0.type", "mock") .put("marvel.agent.exporters._name1.type", "mock_master_only") - .build(), factories, settingsFilter, clusterService, nodeSettingsService); + .build(), factories, settingsFilter, clusterService, clusterSettings); exporters.start(); DiscoveryNode localNode = mock(DiscoveryNode.class); @@ -239,7 +233,7 @@ public class ExportersTests extends ESTestCase { Exporters exporters = new Exporters(Settings.builder() .put("marvel.agent.exporters._name0.type", "mock") .put("marvel.agent.exporters._name1.type", "mock_master_only") - .build(), factories, settingsFilter, clusterService, nodeSettingsService); + .build(), factories, settingsFilter, clusterService, clusterSettings); exporters.start(); DiscoveryNode localNode = mock(DiscoveryNode.class); @@ -304,22 +298,4 @@ public class ExportersTests extends ESTestCase { } } - static class TestNodeSettingsService extends NodeSettingsService { - private final List listeners = new ArrayList<>(); - - public TestNodeSettingsService() { - super(Settings.EMPTY); - } - - @Override - public void addListener(Listener listener) { - listeners.add(listener); - } - - public void updateSettings(Settings settings) { - for (Listener listener : listeners) { - listener.onRefreshSettings(settings); - } - } - } } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/http/HttpExporterTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/http/HttpExporterTests.java index 58c232403b7..1e7720fe2e7 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/http/HttpExporterTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/http/HttpExporterTests.java @@ -84,7 +84,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { enqueueResponse(200, "successful bulk request "); Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) .put("marvel.agent.exporters._http.connection.keep_alive", false) @@ -121,7 +121,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { public void testDynamicHostChange() { // disable exporting to be able to use non valid hosts Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", "test0"); @@ -145,7 +145,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { public void testHostChangeReChecksTemplate() throws Exception { Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) .put("marvel.agent.exporters._http.connection.keep_alive", false) @@ -247,7 +247,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { public void testUnsupportedClusterVersion() throws Exception { Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) .put("marvel.agent.exporters._http.connection.keep_alive", false); @@ -274,7 +274,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { public void testDynamicIndexFormatChange() throws Exception { Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", webServer.getHostName() + ":" + webServer.getPort()) .put("marvel.agent.exporters._http.connection.keep_alive", false) @@ -372,7 +372,7 @@ public class HttpExporterTests extends MarvelIntegTestCase { final String host = webServer.getHostName() + ":" + webServer.getPort(); Settings.Builder builder = Settings.builder() - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters._http.type", "http") .put("marvel.agent.exporters._http.host", host) .put("marvel.agent.exporters._http.connection.keep_alive", false); diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/local/LocalExporterTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/local/LocalExporterTests.java index 8c589ba5022..e4a0b673114 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/local/LocalExporterTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/local/LocalExporterTests.java @@ -47,7 +47,7 @@ public class LocalExporterTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterInfoTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterInfoTests.java index 6837d7cf18c..1651a30baa3 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterInfoTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterInfoTests.java @@ -35,8 +35,8 @@ public class ClusterInfoTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, ClusterInfoCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), ClusterInfoCollector.NAME) .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStateTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStateTests.java index d875b63dfe7..47ed2b5f569 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStateTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStateTests.java @@ -36,8 +36,8 @@ public class ClusterStateTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, ClusterStateCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), ClusterStateCollector.NAME) .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStatsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStatsTests.java index 09b109b5761..223bafa2b3e 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStatsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/cluster/ClusterStatsTests.java @@ -29,8 +29,8 @@ public class ClusterStatsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, ClusterStatsCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), ClusterStatsCollector.NAME) .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexRecoveryTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexRecoveryTests.java index 30cd53066c5..055a9134d39 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexRecoveryTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexRecoveryTests.java @@ -34,9 +34,9 @@ public class IndexRecoveryTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.INDICES, INDEX_PREFIX + "*") - .put(MarvelSettings.COLLECTORS, IndexRecoveryCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.INDICES_SETTING.getKey(), INDEX_PREFIX + "*") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), IndexRecoveryCollector.NAME) .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexStatsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexStatsTests.java index 396a80190d5..a5da18fa7b5 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexStatsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndexStatsTests.java @@ -27,8 +27,8 @@ public class IndexStatsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, IndexStatsCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), IndexStatsCollector.NAME) .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndicesStatsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndicesStatsTests.java index 52b5ac96e2d..94fa102eb08 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndicesStatsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/indices/IndicesStatsTests.java @@ -27,8 +27,8 @@ public class IndicesStatsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, IndicesStatsCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), IndicesStatsCollector.NAME) .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/MultiNodesStatsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/MultiNodesStatsTests.java index 5c09eab39bf..1c105fffd33 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/MultiNodesStatsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/MultiNodesStatsTests.java @@ -29,7 +29,7 @@ public class MultiNodesStatsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/NodeStatsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/NodeStatsTests.java index d725054aa7d..a289ea03a31 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/NodeStatsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/node/NodeStatsTests.java @@ -28,8 +28,8 @@ public class NodeStatsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, NodeStatsCollector.NAME) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), NodeStatsCollector.NAME) .put("marvel.agent.exporters.default_local.type", LocalExporter.TYPE) .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/shards/ShardsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/shards/ShardsTests.java index 8c673e98625..bb1bff7369a 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/shards/ShardsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/renderer/shards/ShardsTests.java @@ -41,9 +41,9 @@ public class ShardsTests extends MarvelIntegTestCase { protected Settings nodeSettings(int nodeOrdinal) { return Settings.builder() .put(super.nodeSettings(nodeOrdinal)) - .put(MarvelSettings.INTERVAL, "-1") - .put(MarvelSettings.COLLECTORS, ShardsCollector.NAME) - .put(MarvelSettings.INDICES, INDEX_PREFIX + "*") + .put(MarvelSettings.INTERVAL_SETTING.getKey(), "-1") + .put(MarvelSettings.COLLECTORS_SETTING.getKey(), ShardsCollector.NAME) + .put(MarvelSettings.INDICES_SETTING.getKey(), INDEX_PREFIX + "*") .put("marvel.agent.exporters.default_local.type", "local") .build(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingTests.java deleted file mode 100644 index 4297a41c806..00000000000 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.marvel.agent.settings; - -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.test.ESTestCase; - -import static org.elasticsearch.common.settings.Settings.settingsBuilder; -import static org.hamcrest.Matchers.equalTo; - -public class MarvelSettingTests extends ESTestCase { - public void testBooleanMarvelSetting() { - String name = randomAsciiOfLength(10); - String description = randomAsciiOfLength(20); - Boolean defaultValue = null; - if (randomBoolean()) { - defaultValue = randomBoolean(); - } - - MarvelSetting.BooleanSetting setting = MarvelSetting.booleanSetting(name, defaultValue, description); - assertThat(setting.getName(), equalTo(name)); - assertThat(setting.getDescription(), equalTo(description)); - assertThat(setting.getValue(), equalTo(defaultValue)); - - setting.onRefresh(settingsBuilder().put(name, Boolean.FALSE).build()); - assertFalse(setting.getValue()); - - setting.onRefresh(settingsBuilder().put(name, Boolean.TRUE).build()); - assertTrue(setting.getValue()); - } - - public void testTimeValueMarvelSetting() { - String name = randomAsciiOfLength(10); - String description = randomAsciiOfLength(20); - TimeValue defaultValue = null; - if (randomBoolean()) { - defaultValue = newRandomTimeValue(); - } - - MarvelSetting.TimeValueSetting setting = MarvelSetting.timeSetting(name, defaultValue, description); - assertThat(setting.getName(), equalTo(name)); - assertThat(setting.getDescription(), equalTo(description)); - if (defaultValue == null) { - assertNull(setting.getValue()); - } else { - assertThat(setting.getValue().millis(), equalTo(defaultValue.millis())); - } - - setting.onRefresh(settingsBuilder().put(name, 15000L).build()); - assertThat(setting.getValue().millis(), equalTo(15000L)); - - TimeValue updated = newRandomTimeValue(); - setting.onRefresh(settingsBuilder().put(name, updated.toString()).build()); - assertThat(setting.getValue().millis(), equalTo(updated.millis())); - - updated = newRandomTimeValue(); - setting.onRefresh(settingsBuilder().put(name, updated.toString()).build()); - assertThat(setting.getValue().millis(), equalTo(updated.millis())); - } - - public void testStringMarvelSetting() { - String name = randomAsciiOfLength(10); - String description = randomAsciiOfLength(20); - String defaultValue = null; - if (randomBoolean()) { - defaultValue = randomAsciiOfLength(15); - } - - MarvelSetting.StringSetting setting = MarvelSetting.stringSetting(name, defaultValue, description); - assertThat(setting.getName(), equalTo(name)); - assertThat(setting.getDescription(), equalTo(description)); - if (defaultValue == null) { - assertNull(setting.getValue()); - } else { - assertThat(setting.getValue(), equalTo(defaultValue)); - } - - setting.onRefresh(settingsBuilder().build()); - assertThat(setting.getValue(), equalTo(defaultValue)); - - String updated = randomAsciiOfLength(15); - setting.onRefresh(settingsBuilder().put(name, updated).build()); - assertThat(setting.getValue(), equalTo(updated)); - - updated = randomAsciiOfLength(15); - setting.onRefresh(settingsBuilder().put(name, updated).build()); - assertThat(setting.getValue(), equalTo(updated)); - } - - public void testStringArrayMarvelSetting() { - String name = randomAsciiOfLength(10); - String description = randomAsciiOfLength(20); - String[] defaultValue = null; - if (randomBoolean()) { - defaultValue = randomStringArray(); - } - - MarvelSetting.StringArraySetting setting = MarvelSetting.arraySetting(name, defaultValue, description); - assertThat(setting.getName(), equalTo(name)); - assertThat(setting.getDescription(), equalTo(description)); - if (defaultValue == null) { - assertNull(setting.getValue()); - } else { - assertArrayEquals(setting.getValue(), defaultValue); - } - - setting.onRefresh(settingsBuilder().build()); - assertArrayEquals(setting.getValue(), defaultValue); - - String[] updated = randomStringArray(); - setting.onRefresh(settingsBuilder().put(name, Strings.arrayToCommaDelimitedString(updated)).build()); - assertArrayEquals(setting.getValue(), updated); - - updated = randomStringArray(); - setting.onRefresh(settingsBuilder().put(name, Strings.arrayToCommaDelimitedString(updated)).build()); - assertArrayEquals(setting.getValue(), updated); - } - - private TimeValue newRandomTimeValue() { - return TimeValue.parseTimeValue(randomFrom("10ms", "1.5s", "1.5m", "1.5h", "1.5d", "1000d"), null, getClass().getSimpleName() + ".unit"); - } - - private String[] randomStringArray() { - int n = randomIntBetween(1, 5); - String[] values = new String[n]; - for (int i = 0; i < n; i++) { - values[i] = randomAsciiOfLength(5); - } - return values; - } -} diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingsTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingsTests.java index f0711a5731a..7df5ac19043 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingsTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/settings/MarvelSettingsTests.java @@ -6,8 +6,10 @@ package org.elasticsearch.marvel.agent.settings; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestBuilder; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.marvel.agent.AgentService; import org.elasticsearch.marvel.test.MarvelIntegTestCase; import org.elasticsearch.node.Node; import org.elasticsearch.test.ESIntegTestCase; @@ -18,8 +20,11 @@ import static org.hamcrest.Matchers.instanceOf; import org.apache.lucene.util.LuceneTestCase.BadApple; +import java.util.Arrays; +import java.util.List; + //test is just too slow, please fix it to not be sleep-based -@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007") +//@BadApple(bugUrl = "https://github.com/elastic/x-plugins/issues/1007") @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 1, numClientNodes = 0) public class MarvelSettingsTests extends MarvelIntegTestCase { private final TimeValue interval = newRandomTimeValue(); @@ -43,22 +48,21 @@ public class MarvelSettingsTests extends MarvelIntegTestCase { private Settings marvelSettings() { return Settings.builder() - .put(MarvelSettings.INTERVAL, interval) - .put(MarvelSettings.INDEX_STATS_TIMEOUT, indexStatsTimeout) - .put(MarvelSettings.INDICES_STATS_TIMEOUT, indicesStatsTimeout) - .putArray(MarvelSettings.INDICES, indices) - .put(MarvelSettings.CLUSTER_STATE_TIMEOUT, clusterStateTimeout) - .put(MarvelSettings.CLUSTER_STATS_TIMEOUT, clusterStatsTimeout) - .put(MarvelSettings.INDEX_RECOVERY_TIMEOUT, recoveryTimeout) - .put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY, recoveryActiveOnly) - .putArray(MarvelSettings.COLLECTORS, collectors) + .put(MarvelSettings.INTERVAL_SETTING.getKey(), interval) + .put(MarvelSettings.INDEX_STATS_TIMEOUT_SETTING.getKey(), indexStatsTimeout) + .put(MarvelSettings.INDICES_STATS_TIMEOUT_SETTING.getKey(), indicesStatsTimeout) + .putArray(MarvelSettings.INDICES_SETTING.getKey(), indices) + .put(MarvelSettings.CLUSTER_STATE_TIMEOUT_SETTING.getKey(), clusterStateTimeout) + .put(MarvelSettings.CLUSTER_STATS_TIMEOUT_SETTING.getKey(), clusterStatsTimeout) + .put(MarvelSettings.INDEX_RECOVERY_TIMEOUT_SETTING.getKey(), recoveryTimeout) + .put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY_SETTING.getKey(), recoveryActiveOnly) + .putArray(MarvelSettings.COLLECTORS_SETTING.getKey(), collectors) .build(); } public void testMarvelSettings() throws Exception { logger.info("--> testing marvel settings service initialization"); for (final MarvelSettings marvelSettings : internalCluster().getInstances(MarvelSettings.class)) { - assertThat(marvelSettings.interval().millis(), equalTo(interval.millis())); assertThat(marvelSettings.indexStatsTimeout().millis(), equalTo(indexStatsTimeout.millis())); assertThat(marvelSettings.indicesStatsTimeout().millis(), equalTo(indicesStatsTimeout.millis())); assertArrayEquals(marvelSettings.indices(), indices); @@ -66,39 +70,41 @@ public class MarvelSettingsTests extends MarvelIntegTestCase { assertThat(marvelSettings.clusterStatsTimeout().millis(), equalTo(clusterStatsTimeout.millis())); assertThat(marvelSettings.recoveryTimeout().millis(), equalTo(recoveryTimeout.millis())); assertThat(marvelSettings.recoveryActiveOnly(), equalTo(recoveryActiveOnly)); - assertArrayEquals(marvelSettings.collectors(), collectors); + } + + for (final AgentService service : internalCluster().getInstances(AgentService.class)) { + assertThat(service.getSamplingInterval().millis(), equalTo(interval.millis())); + assertArrayEquals(service.collectors(), collectors); + } logger.info("--> testing marvel dynamic settings update"); Settings.Builder transientSettings = Settings.builder(); - - for (String setting : MarvelSettings.dynamicSettings().keySet()) { - Object updated = null; - - if (setting.endsWith(".*")) { - setting = setting.substring(0, setting.lastIndexOf('.')); - } - - switch (setting) { - case MarvelSettings.INTERVAL: - case MarvelSettings.INDEX_STATS_TIMEOUT: - case MarvelSettings.INDICES_STATS_TIMEOUT: - case MarvelSettings.CLUSTER_STATE_TIMEOUT: - case MarvelSettings.CLUSTER_STATS_TIMEOUT: - case MarvelSettings.INDEX_RECOVERY_TIMEOUT: + final Setting[] marvelSettings = new Setting[] { + MarvelSettings.INDICES_SETTING, + MarvelSettings.INTERVAL_SETTING, + MarvelSettings.INDEX_RECOVERY_TIMEOUT_SETTING, + MarvelSettings.INDEX_STATS_TIMEOUT_SETTING, + MarvelSettings.INDICES_STATS_TIMEOUT_SETTING, + MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY_SETTING, + MarvelSettings.COLLECTORS_SETTING, + MarvelSettings.CLUSTER_STATE_TIMEOUT_SETTING, + MarvelSettings.CLUSTER_STATS_TIMEOUT_SETTING}; + for (Setting setting : marvelSettings) { + if (setting.isDynamic()) { + Object updated = null; + if (setting.get(Settings.EMPTY) instanceof TimeValue) { updated = newRandomTimeValue(); - transientSettings.put(setting, updated); - break; - case MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY: + transientSettings.put(setting.getKey(), updated); + } else if (setting.get(Settings.EMPTY) instanceof Boolean) { updated = randomBoolean(); - transientSettings.put(setting, updated); - break; - case MarvelSettings.INDICES: + transientSettings.put(setting.getKey(), updated); + } else if (setting.get(Settings.EMPTY) instanceof List) { updated = randomStringArray(); - transientSettings.putArray(setting, (String[]) updated); - break; - default: + transientSettings.putArray(setting.getKey(), (String[]) updated); + } else { fail("unknown dynamic setting [" + setting + "]"); + } } } @@ -107,47 +113,36 @@ public class MarvelSettingsTests extends MarvelIntegTestCase { assertAcked(prepareRandomUpdateSettings(updatedSettings).get()); logger.error("--> checking that the value has been correctly updated on all marvel settings services"); - assertBusy(new Runnable() { - @Override - public void run() { - for (String setting : MarvelSettings.dynamicSettings().keySet()) { - for (final MarvelSettings marvelSettings : internalCluster().getInstances(MarvelSettings.class)) { - MarvelSetting current = null; - Object value = null; - - switch (setting) { - case MarvelSettings.INTERVAL: - case MarvelSettings.INDEX_STATS_TIMEOUT: - case MarvelSettings.INDICES_STATS_TIMEOUT: - case MarvelSettings.CLUSTER_STATE_TIMEOUT: - case MarvelSettings.CLUSTER_STATS_TIMEOUT: - case MarvelSettings.INDEX_RECOVERY_TIMEOUT: - current = marvelSettings.getSetting(setting); - value = current.getValue(); - assertThat(value, instanceOf(TimeValue.class)); - assertThat(((TimeValue) value).millis(), equalTo(updatedSettings.getAsTime(setting, null).millis())); - break; - - case MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY: - current = marvelSettings.getSetting(setting); - value = current.getValue(); - assertThat(value, instanceOf(Boolean.class)); - assertThat(((Boolean) value), equalTo(updatedSettings.getAsBoolean(setting, null))); - break; - - default: - if (setting.startsWith(MarvelSettings.INDICES)) { - current = marvelSettings.getSetting(MarvelSettings.INDICES); - value = current.getValue(); - assertArrayEquals((String[]) value, updatedSettings.getAsArray(MarvelSettings.INDICES)); - } else { - fail("unable to check value for unknown dynamic setting [" + setting + "]"); - } - } + for (Setting setting : marvelSettings) { + if (setting.isDynamic() == false) { + continue; + } + if (setting == MarvelSettings.INTERVAL_SETTING) { + for (final AgentService service : internalCluster().getInstances(AgentService.class)) { + assertEquals(service.getSamplingInterval(), setting.get(updatedSettings)); + } + } else { + for (final MarvelSettings marvelSettings1 : internalCluster().getInstances(MarvelSettings.class)) { + if (setting == MarvelSettings.INDEX_STATS_TIMEOUT_SETTING) { + assertEquals(marvelSettings1.indexStatsTimeout(), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.INDICES_STATS_TIMEOUT_SETTING) { + assertEquals(marvelSettings1.indicesStatsTimeout(), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.CLUSTER_STATS_TIMEOUT_SETTING) { + assertEquals(marvelSettings1.clusterStatsTimeout(), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.CLUSTER_STATE_TIMEOUT_SETTING) { + assertEquals(marvelSettings1.clusterStateTimeout(), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.INDEX_RECOVERY_TIMEOUT_SETTING) { + assertEquals(marvelSettings1.recoveryTimeout(), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY_SETTING) { + assertEquals(Boolean.valueOf(marvelSettings1.recoveryActiveOnly()), setting.get(updatedSettings)); + } else if (setting == MarvelSettings.INDICES_SETTING) { + assertEquals(Arrays.asList(marvelSettings1.indices()), setting.get(updatedSettings)); + } else { + fail("unable to check value for unknown dynamic setting [" + setting + "]"); } } } - }); + } } private ClusterUpdateSettingsRequestBuilder prepareRandomUpdateSettings(Settings updateSettings) { diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/test/MarvelIntegTestCase.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/test/MarvelIntegTestCase.java index 5c973fa091d..17a00470a52 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/test/MarvelIntegTestCase.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/test/MarvelIntegTestCase.java @@ -365,7 +365,7 @@ public abstract class MarvelIntegTestCase extends ESIntegTestCase { } protected void updateMarvelInterval(long value, TimeUnit timeUnit) { - assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(MarvelSettings.INTERVAL, value, timeUnit))); + assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(Settings.builder().put(MarvelSettings.INTERVAL_SETTING.getKey(), value, timeUnit))); } /** Shield related settings */ diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java index d1d7471904d..da97976543d 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ShieldPlugin.java @@ -14,6 +14,7 @@ import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.plugins.Plugin; @@ -131,7 +132,6 @@ public class ShieldPlugin extends Plugin { list.add(InternalCryptoService.class); list.add(FileRolesStore.class); list.add(Realms.class); - list.add(IPFilter.class); return list; } return Collections.emptyList(); @@ -153,12 +153,13 @@ public class ShieldPlugin extends Plugin { return settingsBuilder.build(); } - public void onModule(ClusterModule clusterDynamicSettingsModule) { - clusterDynamicSettingsModule.registerClusterDynamicSetting("shield.transport.filter.*", Validator.EMPTY); - clusterDynamicSettingsModule.registerClusterDynamicSetting("shield.http.filter.*", Validator.EMPTY); - clusterDynamicSettingsModule.registerClusterDynamicSetting("transport.profiles.*", Validator.EMPTY); - clusterDynamicSettingsModule.registerClusterDynamicSetting(IPFilter.IP_FILTER_ENABLED_SETTING, Validator.EMPTY); - clusterDynamicSettingsModule.registerClusterDynamicSetting(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, Validator.EMPTY); + public void onModule(SettingsModule settingsModule) { + settingsModule.registerSetting(IPFilter.IP_FILTER_ENABLED_SETTING); + settingsModule.registerSetting(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING); + settingsModule.registerSetting(IPFilter.HTTP_FILTER_ALLOW_SETTING); + settingsModule.registerSetting(IPFilter.HTTP_FILTER_DENY_SETTING); + settingsModule.registerSetting(IPFilter.TRANSPORT_FILTER_ALLOW_SETTING); + settingsModule.registerSetting(IPFilter.TRANSPORT_FILTER_DENY_SETTING); } @Override diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java index a453f993792..cecd14a4911 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java @@ -5,20 +5,17 @@ */ package org.elasticsearch.shield.transport.filter; -import com.carrotsearch.hppc.ObjectObjectHashMap; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.collect.HppcMaps; -import org.elasticsearch.common.component.AbstractLifecycleComponent; -import org.elasticsearch.common.component.Lifecycle; -import org.elasticsearch.common.component.LifecycleListener; +import org.apache.lucene.util.SetOnce; +import org.elasticsearch.common.Booleans; import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.internal.Nullable; +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.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; -import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.shield.audit.AuditTrail; import org.elasticsearch.shield.license.ShieldLicenseState; import org.elasticsearch.transport.Transport; @@ -30,10 +27,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; import static java.util.Collections.unmodifiableMap; -public class IPFilter extends AbstractLifecycleComponent { +public class IPFilter { /** * .http has been chosen for handling HTTP filters, which are not part of the profiles @@ -43,8 +41,19 @@ public class IPFilter extends AbstractLifecycleComponent { */ public static final String HTTP_PROFILE_NAME = ".http"; - public static final String IP_FILTER_ENABLED_SETTING = "shield.transport.filter.enabled"; - public static final String IP_FILTER_ENABLED_HTTP_SETTING = "shield.http.filter.enabled"; + public static final Setting IP_FILTER_ENABLED_HTTP_SETTING = Setting.boolSetting("shield.http.filter.enabled", true, true, Setting.Scope.CLUSTER); + public static final Setting IP_FILTER_ENABLED_SETTING = new Setting<>("shield.transport.filter.enabled", (s) -> IP_FILTER_ENABLED_HTTP_SETTING.getDefault(s), Booleans::parseBooleanExact, true, Setting.Scope.CLUSTER); + public static final Setting> TRANSPORT_FILTER_ALLOW_SETTING = Setting.listSetting("shield.transport.filter.allow", Collections.emptyList(), Function.identity(), true, Setting.Scope.CLUSTER); + public static final Setting> TRANSPORT_FILTER_DENY_SETTING = Setting.listSetting("shield.transport.filter.deny", Collections.emptyList(), Function.identity(), true, Setting.Scope.CLUSTER); + + public static final Setting> HTTP_FILTER_ALLOW_SETTING = Setting.listSetting("shield.http.filter.allow", (s) -> { + return Arrays.asList(s.getAsArray("transport.profiles.default.shield.filter.allow", TRANSPORT_FILTER_ALLOW_SETTING.get(s).toArray(new String[0]))); + }, Function.identity(), true, Setting.Scope.CLUSTER); + public static final Setting> HTTP_FILTER_DENY_SETTING = Setting.listSetting("shield.http.filter.deny", (s) -> { + return Arrays.asList(s.getAsArray("transport.profiles.default.shield.filter.deny", TRANSPORT_FILTER_DENY_SETTING.get(s).toArray(new String[0]))); + }, Function.identity(), true, Setting.Scope.CLUSTER); + + public static final ShieldIpFilterRule DEFAULT_PROFILE_ACCEPT_ALL = new ShieldIpFilterRule(true, "default:accept_all") { @Override @@ -63,66 +72,81 @@ public class IPFilter extends AbstractLifecycleComponent { } }; - private final LifecycleListener parseSettingsListener = new LifecycleListener() { - @Override - public void afterStart() { - IPFilter.this.rules = IPFilter.this.parseSettings(settings); - } - }; - - - private NodeSettingsService nodeSettingsService; private final AuditTrail auditTrail; - private final Transport transport; private final ShieldLicenseState licenseState; private final boolean alwaysAllowBoundAddresses; - private Map rules = Collections.emptyMap(); - private HttpServerTransport httpServerTransport = null; + + private final ESLogger logger; + private volatile Map rules = Collections.emptyMap(); + private volatile boolean isIpFilterEnabled; + private volatile boolean isHttpFilterEnabled; + private volatile Map transportGroups; + private volatile List transportAllowFilter; + private volatile List transportDenyFilter; + private volatile List httpAllowFilter; + private volatile List httpDenyFilter; + private final SetOnce boundTransportAddress = new SetOnce<>(); + private final SetOnce boundHttpTransportAddress = new SetOnce<>(); + private final SetOnce> profileBoundAddress = new SetOnce<>(); @Inject - public IPFilter(final Settings settings, AuditTrail auditTrail, NodeSettingsService nodeSettingsService, - Transport transport, ShieldLicenseState licenseState) { - super(settings); - this.nodeSettingsService = nodeSettingsService; + public IPFilter(final Settings settings, AuditTrail auditTrail, ClusterSettings clusterSettings, + ShieldLicenseState licenseState) { + this.logger = Loggers.getLogger(getClass(), settings); this.auditTrail = auditTrail; - this.transport = transport; this.licenseState = licenseState; this.alwaysAllowBoundAddresses = settings.getAsBoolean("shield.filter.always_allow_bound_address", true); + httpDenyFilter = HTTP_FILTER_DENY_SETTING.get(settings); + httpAllowFilter = HTTP_FILTER_ALLOW_SETTING.get(settings); + transportAllowFilter = TRANSPORT_FILTER_ALLOW_SETTING.get(settings); + transportDenyFilter = TRANSPORT_FILTER_DENY_SETTING.get(settings); + isHttpFilterEnabled = IP_FILTER_ENABLED_HTTP_SETTING.get(settings); + isIpFilterEnabled = IP_FILTER_ENABLED_SETTING.get(settings); + + this.transportGroups = Transport.TRANSPORT_PROFILES_SETTING.get(settings).getAsGroups(); // this is pretty crazy that we allow this to be updateable!!! - we have to fix this very soon + clusterSettings.addSettingsUpdateConsumer(IP_FILTER_ENABLED_HTTP_SETTING, this::setHttpFiltering); + clusterSettings.addSettingsUpdateConsumer(IP_FILTER_ENABLED_SETTING, this::setTransportFiltering); + clusterSettings.addSettingsUpdateConsumer(TRANSPORT_FILTER_ALLOW_SETTING, this::setTransportAllowFilter); + clusterSettings.addSettingsUpdateConsumer(TRANSPORT_FILTER_DENY_SETTING, this::setTransportDenyFilter); + clusterSettings.addSettingsUpdateConsumer(HTTP_FILTER_ALLOW_SETTING, this::setHttpAllowFilter); + clusterSettings.addSettingsUpdateConsumer(HTTP_FILTER_DENY_SETTING, this::setHttpDenyFilter); + clusterSettings.addSettingsUpdateConsumer(Transport.TRANSPORT_PROFILES_SETTING, this::setTransportProfiles); + updateRules(); } - @Override - protected void doStart() throws ElasticsearchException { - nodeSettingsService.addListener(new ApplySettings(settings)); - - if (transport.lifecycleState() == Lifecycle.State.STARTED) { - rules = parseSettings(settings); - } else { - transport.addLifecycleListener(parseSettingsListener); - } + private void setTransportProfiles(Settings settings) { + transportGroups = settings.getAsGroups(); + updateRules(); } - @Override - protected void doStop() throws ElasticsearchException { + private void setHttpDenyFilter(List filter) { + this.httpDenyFilter = filter; + updateRules(); } - @Override - protected void doClose() throws ElasticsearchException { + private void setHttpAllowFilter(List filter) { + this.httpAllowFilter = filter; + updateRules(); } - // this cannot be put into the constructor as HTTP might be disabled - @Inject(optional = true) - public void setHttpServerTransport(@Nullable HttpServerTransport httpServerTransport) { - if (httpServerTransport == null) { - return; - } + private void setTransportDenyFilter(List filter) { + this.transportDenyFilter = filter; + updateRules(); + } - this.httpServerTransport = httpServerTransport; + private void setTransportAllowFilter(List filter) { + this.transportAllowFilter = filter; + updateRules(); + } - if (httpServerTransport.lifecycleState() == Lifecycle.State.STARTED) { - IPFilter.this.rules = IPFilter.this.parseSettings(settings); - } else { - httpServerTransport.addLifecycleListener(parseSettingsListener); - } + private void setTransportFiltering(boolean enabled) { + this.isIpFilterEnabled = enabled; + updateRules(); + } + + private void setHttpFiltering(boolean enabled) { + this.isHttpFilterEnabled = enabled; + updateRules(); } public boolean accept(String profile, InetAddress peerAddress) { @@ -151,49 +175,43 @@ public class IPFilter extends AbstractLifecycleComponent { return true; } - private Map parseSettings(Settings settings) { - boolean isIpFilterEnabled = settings.getAsBoolean(IP_FILTER_ENABLED_SETTING, true); - boolean isHttpFilterEnabled = settings.getAsBoolean(IP_FILTER_ENABLED_HTTP_SETTING, isIpFilterEnabled); + private synchronized void updateRules() { + this.rules = parseSettings(); + } - if (!isIpFilterEnabled && !isHttpFilterEnabled) { + private Map parseSettings() { + if (isIpFilterEnabled || isHttpFilterEnabled) { + Map profileRules = new HashMap<>(); + if (isHttpFilterEnabled && boundHttpTransportAddress.get() != null) { + TransportAddress[] localAddresses = boundHttpTransportAddress.get().boundAddresses(); + profileRules.put(HTTP_PROFILE_NAME, createRules(httpAllowFilter, httpDenyFilter, localAddresses)); + } + + if (isIpFilterEnabled && boundTransportAddress.get() != null) { + TransportAddress[] localAddresses = boundTransportAddress.get().boundAddresses(); + profileRules.put("default", createRules(transportAllowFilter, transportDenyFilter, localAddresses)); + for (Map.Entry entry : transportGroups.entrySet()) { + String profile = entry.getKey(); + BoundTransportAddress profileBoundTransportAddress = profileBoundAddress.get().get(profile); + if (profileBoundTransportAddress == null) { + // this could happen if a user updates the settings dynamically with a new profile + logger.warn("skipping ip filter rules for profile [{}] since the profile is not bound to any addresses", profile); + continue; + } + Settings profileSettings = entry.getValue().getByPrefix("shield.filter."); + profileRules.put(profile, createRules(Arrays.asList(profileSettings.getAsArray("allow")), Arrays.asList(profileSettings.getAsArray("deny")), profileBoundTransportAddress.boundAddresses())); + } + } + + logger.debug("loaded ip filtering profiles: {}", profileRules.keySet()); + return unmodifiableMap(profileRules); + } else { return Collections.emptyMap(); } - Map profileRules = new HashMap<>(); - - if (isHttpFilterEnabled && httpServerTransport != null && httpServerTransport.lifecycleState() == Lifecycle.State.STARTED) { - TransportAddress[] localAddresses = this.httpServerTransport.boundAddress().boundAddresses(); - String[] httpAllowed = settings.getAsArray("shield.http.filter.allow", settings.getAsArray("transport.profiles.default.shield.filter.allow", settings.getAsArray("shield.transport.filter.allow"))); - String[] httpDenied = settings.getAsArray("shield.http.filter.deny", settings.getAsArray("transport.profiles.default.shield.filter.deny", settings.getAsArray("shield.transport.filter.deny"))); - profileRules.put(HTTP_PROFILE_NAME, createRules(httpAllowed, httpDenied, localAddresses)); - } - - if (isIpFilterEnabled && this.transport.lifecycleState() == Lifecycle.State.STARTED) { - TransportAddress[] localAddresses = this.transport.boundAddress().boundAddresses(); - - String[] allowed = settings.getAsArray("shield.transport.filter.allow"); - String[] denied = settings.getAsArray("shield.transport.filter.deny"); - profileRules.put("default", createRules(allowed, denied, localAddresses)); - - Map groupedSettings = settings.getGroups("transport.profiles."); - for (Map.Entry entry : groupedSettings.entrySet()) { - String profile = entry.getKey(); - BoundTransportAddress profileBoundTransportAddress = transport.profileBoundAddresses().get(profile); - if (profileBoundTransportAddress == null) { - // this could happen if a user updates the settings dynamically with a new profile - logger.warn("skipping ip filter rules for profile [{}] since the profile is not bound to any addresses", profile); - continue; - } - Settings profileSettings = entry.getValue().getByPrefix("shield.filter."); - profileRules.put(profile, createRules(profileSettings.getAsArray("allow"), profileSettings.getAsArray("deny"), profileBoundTransportAddress.boundAddresses())); - } - } - - logger.debug("loaded ip filtering profiles: {}", profileRules.keySet()); - return unmodifiableMap(profileRules); } - private ShieldIpFilterRule[] createRules(String[] allow, String[] deny, TransportAddress[] boundAddresses) { + private ShieldIpFilterRule[] createRules(List allow, List deny, TransportAddress[] boundAddresses) { List rules = new ArrayList<>(); // if we are always going to allow the bound addresses, then the rule for them should be the first rule in the list if (alwaysAllowBoundAddresses) { @@ -212,95 +230,14 @@ public class IPFilter extends AbstractLifecycleComponent { return rules.toArray(new ShieldIpFilterRule[rules.size()]); } - private class ApplySettings implements NodeSettingsService.Listener { + public void setBoundTransportAddress(BoundTransportAddress boundTransportAddress, Map profileBoundAddress) { + this.boundTransportAddress.set(boundTransportAddress); + this.profileBoundAddress.set(profileBoundAddress); + updateRules(); + } - String[] allowed; - String[] denied; - String[] httpAllowed; - String[] httpDenied; - ObjectObjectHashMap profileAllowed; - ObjectObjectHashMap profileDenied; - private boolean enabled; - private boolean httpEnabled; - - public ApplySettings(Settings settings) { - loadValuesFromSettings(settings); - } - - private void loadValuesFromSettings(Settings settings) { - this.enabled = settings.getAsBoolean(IP_FILTER_ENABLED_SETTING, this.enabled); - this.httpEnabled = settings.getAsBoolean(IP_FILTER_ENABLED_HTTP_SETTING, this.httpEnabled); - this.allowed = settings.getAsArray("shield.transport.filter.allow", this.allowed); - this.denied = settings.getAsArray("shield.transport.filter.deny", this.denied); - this.httpAllowed = settings.getAsArray("shield.http.filter.allow", this.httpAllowed); - this.httpDenied = settings.getAsArray("shield.http.filter.deny", this.httpDenied); - - if (settings.getGroups("transport.profiles.").size() == 0) { - profileAllowed = HppcMaps.newMap(0); - profileDenied = HppcMaps.newMap(0); - } - - profileAllowed = HppcMaps.newNoNullKeysMap(settings.getGroups("transport.profiles.").size()); - profileDenied = HppcMaps.newNoNullKeysMap(settings.getGroups("transport.profiles.").size()); - for (Map.Entry entry : settings.getGroups("transport.profiles.").entrySet()) { - profileAllowed.put(entry.getKey(), entry.getValue().getAsArray("shield.filter.allow")); - profileDenied.put(entry.getKey(), entry.getValue().getAsArray("shield.filter.deny")); - } - } - - @Override - public void onRefreshSettings(Settings settings) { - if (ipFilterSettingsInvolved(settings) && settingsChanged(settings)) { - IPFilter.this.rules = parseSettings(settings); - loadValuesFromSettings(settings); - } - } - - private boolean settingsChanged(Settings settings) { - // simple checks first - if (this.enabled != settings.getAsBoolean(IP_FILTER_ENABLED_SETTING, this.enabled) || - this.httpEnabled != settings.getAsBoolean(IP_FILTER_ENABLED_HTTP_SETTING, this.httpEnabled) || - !Arrays.equals(allowed, settings.getAsArray("shield.transport.filter.allow")) || - !Arrays.equals(denied, settings.getAsArray("shield.transport.filter.deny")) || - !Arrays.equals(httpAllowed, settings.getAsArray("shield.http.filter.allow")) || - !Arrays.equals(httpDenied, settings.getAsArray("shield.http.filter.deny")) - ) { - return true; - } - - // profile checks now - ObjectObjectHashMap newProfileAllowed = HppcMaps.newNoNullKeysMap(settings.getGroups("transport.profiles.").size()); - ObjectObjectHashMap newProfileDenied = HppcMaps.newNoNullKeysMap(settings.getGroups("transport.profiles.").size()); - for (Map.Entry entry : settings.getGroups("transport.profiles.").entrySet()) { - newProfileAllowed.put(entry.getKey(), entry.getValue().getAsArray("shield.filter.allow")); - newProfileDenied.put(entry.getKey(), entry.getValue().getAsArray("shield.filter.deny")); - } - - boolean allowedProfileChanged = !newProfileAllowed.equals(profileAllowed); - boolean deniedProfileChanged = !newProfileDenied.equals(profileDenied); - return allowedProfileChanged || deniedProfileChanged; - } - - private boolean ipFilterSettingsInvolved(Settings settings) { - boolean containsStaticIpFilterSettings = settings.get("shield.transport.filter.allow") != null || - settings.get("shield.transport.filter.deny") != null || - settings.get("shield.http.filter.allow") != null || - settings.get("shield.http.filter.deny") != null || - settings.get(IP_FILTER_ENABLED_SETTING) != null || - settings.get(IP_FILTER_ENABLED_HTTP_SETTING) != null; - - if (containsStaticIpFilterSettings) { - return true; - } - - // now if any profile has a filter setting configured - for (Map.Entry entry : settings.getGroups("transport.profiles.").entrySet()) { - if (entry.getValue().get("shield.filter.allow") != null || entry.getValue().get("shield.filter.deny") != null) { - return true; - } - } - - return false; - } + public void setBoundHttpTransportAddress(BoundTransportAddress boundHttpTransportAddress) { + this.boundHttpTransportAddress.set(boundHttpTransportAddress); + updateRules(); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java index 6d06d0e0562..adc02c5ecdb 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java @@ -73,6 +73,12 @@ public class ShieldNettyHttpServerTransport extends NettyHttpServerTransport { } } + @Override + protected void doStart() { + super.doStart(); + ipFilter.setBoundHttpTransportAddress(this.boundAddress()); + } + @Override public ChannelPipelineFactory configureServerChannelPipelineFactory() { return new HttpSslChannelPipelineFactory(this); diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java index c09c9dd1e78..d17e858477a 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java @@ -62,6 +62,14 @@ public class ShieldNettyTransport extends NettyTransport { this.settingsFilter = settingsFilter; } + @Override + protected void doStart() { + super.doStart(); + if (authenticator != null) { + authenticator.setBoundTransportAddress(this.boundAddress(), profileBoundAddresses()); + } + } + @Override public ChannelPipelineFactory configureClientChannelPipelineFactory() { return new SslClientChannelPipelineFactory(this); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IPFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IPFilterTests.java index 7fc03242658..bf6238fe4e6 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IPFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IPFilterTests.java @@ -8,12 +8,12 @@ package org.elasticsearch.shield.transport.filter; import org.elasticsearch.common.component.Lifecycle; import org.elasticsearch.common.network.InetAddresses; import org.elasticsearch.common.network.NetworkAddress; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.shield.audit.AuditTrail; import org.elasticsearch.shield.license.ShieldLicenseState; import org.elasticsearch.test.ESTestCase; @@ -23,11 +23,7 @@ import org.junit.Before; import org.mockito.ArgumentCaptor; import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.hamcrest.Matchers.is; @@ -46,14 +42,21 @@ public class IPFilterTests extends ESTestCase { private AuditTrail auditTrail; private Transport transport; private HttpServerTransport httpTransport; - private NodeSettingsService nodeSettingsService; + private ClusterSettings clusterSettings; @Before public void init() { licenseState = mock(ShieldLicenseState.class); when(licenseState.securityEnabled()).thenReturn(true); auditTrail = mock(AuditTrail.class); - nodeSettingsService = mock(NodeSettingsService.class); + clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList( + IPFilter.HTTP_FILTER_ALLOW_SETTING, + IPFilter.HTTP_FILTER_DENY_SETTING, + IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, + IPFilter.IP_FILTER_ENABLED_SETTING, + IPFilter.TRANSPORT_FILTER_ALLOW_SETTING, + IPFilter.TRANSPORT_FILTER_DENY_SETTING, + Transport.TRANSPORT_PROFILES_SETTING))); httpTransport = mock(HttpServerTransport.class); InetSocketTransportAddress httpAddress = new InetSocketTransportAddress(InetAddress.getLoopbackAddress(), 9200); @@ -75,8 +78,8 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.allow", "127.0.0.1") .put("shield.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsDenied("10.2.3.4"); } @@ -88,7 +91,8 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.allow", "2001:0db8:1234::/48") .putArray("shield.transport.filter.deny", "1234:db8:85a3:0:0:8a2e:370:7334", "4321:db8:1234::/48") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("2001:0db8:1234:0000:0000:8a2e:0370:7334"); assertAddressIsDenied("1234:0db8:85a3:0000:0000:8a2e:0370:7334"); @@ -101,7 +105,8 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.allow", "127.0.0.1") .put("shield.transport.filter.deny", "*.google.com") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsDenied("8.8.8.8"); @@ -111,8 +116,8 @@ public class IPFilterTests extends ESTestCase { Settings settings = settingsBuilder() .put("shield.transport.filter.allow", "_all") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsAllowed("173.194.70.100"); } @@ -124,8 +129,8 @@ public class IPFilterTests extends ESTestCase { .put("transport.profiles.client.shield.filter.allow", "192.168.0.1") .put("transport.profiles.client.shield.filter.deny", "_all") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("127.0.0.1"); assertAddressIsDenied("192.168.0.1"); assertAddressIsAllowedForProfile("client", "192.168.0.1"); @@ -137,16 +142,16 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.allow", "10.0.0.1") .put("shield.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("10.0.0.1"); assertAddressIsDenied("10.0.0.2"); } public void testDefaultAllow() throws Exception { Settings settings = settingsBuilder().build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowed("10.0.0.1"); assertAddressIsAllowed("10.0.0.2"); } @@ -158,9 +163,9 @@ public class IPFilterTests extends ESTestCase { .put("shield.http.filter.allow", "10.0.0.0/8") .put("shield.http.filter.deny", "192.168.0.1") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - ipFilter.setHttpServerTransport(httpTransport); - + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowedForProfile(IPFilter.HTTP_PROFILE_NAME, "10.2.3.4"); assertAddressIsDeniedForProfile(IPFilter.HTTP_PROFILE_NAME, "192.168.0.1"); } @@ -170,8 +175,9 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.allow", "127.0.0.1") .put("shield.transport.filter.deny", "10.0.0.0/8") .build(); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - ipFilter.setHttpServerTransport(httpTransport); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); assertAddressIsAllowedForProfile(IPFilter.HTTP_PROFILE_NAME, "127.0.0.1"); assertAddressIsDeniedForProfile(IPFilter.HTTP_PROFILE_NAME, "10.2.3.4"); @@ -189,8 +195,9 @@ public class IPFilterTests extends ESTestCase { } else { settings = settingsBuilder().put("shield.transport.filter.deny", "_all").build(); } - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); - ipFilter.setHttpServerTransport(httpTransport); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); + ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); for (String addressString : addressStrings) { assertAddressIsAllowedForProfile(IPFilter.HTTP_PROFILE_NAME, addressString); @@ -203,7 +210,8 @@ public class IPFilterTests extends ESTestCase { .put("shield.transport.filter.deny", "_all") .build(); when(licenseState.securityEnabled()).thenReturn(false); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); // don't use the assert helper because we don't want the audit trail to be invoked here String message = String.format(Locale.ROOT, "Expected address %s to be allowed", "8.8.8.8"); @@ -213,7 +221,9 @@ public class IPFilterTests extends ESTestCase { // for sanity enable license and check that it is denied when(licenseState.securityEnabled()).thenReturn(true); - ipFilter = new IPFilter(settings, auditTrail, nodeSettingsService, transport, licenseState).start(); + ipFilter = new IPFilter(settings, auditTrail, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); + assertAddressIsDeniedForProfile("default", "8.8.8.8"); } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringUpdateTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringUpdateTests.java index 0f9e986dd0b..80fb88e0b22 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringUpdateTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/filter/IpFilteringUpdateTests.java @@ -88,8 +88,8 @@ public class IpFilteringUpdateTests extends ShieldIntegTestCase { // now disable ip filtering dynamically and make sure nothing is rejected settings = settingsBuilder() - .put(IPFilter.IP_FILTER_ENABLED_SETTING, false) - .put(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, true) + .put(IPFilter.IP_FILTER_ENABLED_SETTING.getKey(), false) + .put(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING.getKey(), true) .build(); updateSettings(settings); assertConnectionAccepted("default", "127.0.0.8"); @@ -108,7 +108,7 @@ public class IpFilteringUpdateTests extends ShieldIntegTestCase { if (httpEnabled) { assertConnectionRejected(".http", "127.0.0.8"); settings = settingsBuilder() - .put(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, false) + .put(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING.getKey(), false) .build(); // as we permanently switch between persistent and transient settings, just set both here to make sure we overwrite assertAcked(client().admin().cluster().prepareUpdateSettings().setPersistentSettings(settings)); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/netty/IPFilterNettyUpstreamHandlerTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/netty/IPFilterNettyUpstreamHandlerTests.java index 550aff91cfe..c7e804c1efb 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/netty/IPFilterNettyUpstreamHandlerTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/netty/IPFilterNettyUpstreamHandlerTests.java @@ -7,12 +7,12 @@ package org.elasticsearch.shield.transport.netty; import org.elasticsearch.common.component.Lifecycle; import org.elasticsearch.common.network.InetAddresses; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.shield.audit.AuditTrail; import org.elasticsearch.shield.license.ShieldLicenseState; import org.elasticsearch.shield.transport.filter.IPFilter; @@ -32,6 +32,8 @@ import org.junit.Before; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Arrays; +import java.util.HashSet; import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.hamcrest.Matchers.is; @@ -57,18 +59,24 @@ public class IPFilterNettyUpstreamHandlerTests extends ESTestCase { InetSocketTransportAddress address = new InetSocketTransportAddress(InetAddress.getLoopbackAddress(), 9300); when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { address }, address)); when(transport.lifecycleState()).thenReturn(Lifecycle.State.STARTED); - - NodeSettingsService nodeSettingsService = mock(NodeSettingsService.class); + ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(Arrays.asList( + IPFilter.HTTP_FILTER_ALLOW_SETTING, + IPFilter.HTTP_FILTER_DENY_SETTING, + IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, + IPFilter.IP_FILTER_ENABLED_SETTING, + IPFilter.TRANSPORT_FILTER_ALLOW_SETTING, + IPFilter.TRANSPORT_FILTER_DENY_SETTING, + Transport.TRANSPORT_PROFILES_SETTING))); ShieldLicenseState licenseState = mock(ShieldLicenseState.class); when(licenseState.securityEnabled()).thenReturn(true); - IPFilter ipFilter = new IPFilter(settings, AuditTrail.NOOP, nodeSettingsService, transport, licenseState).start(); - + IPFilter ipFilter = new IPFilter(settings, AuditTrail.NOOP, clusterSettings, licenseState); + ipFilter.setBoundTransportAddress(transport.boundAddress(), transport.profileBoundAddresses()); if (isHttpEnabled) { HttpServerTransport httpTransport = mock(HttpServerTransport.class); InetSocketTransportAddress httpAddress = new InetSocketTransportAddress(InetAddress.getLoopbackAddress(), 9200); when(httpTransport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { httpAddress }, httpAddress)); when(httpTransport.lifecycleState()).thenReturn(Lifecycle.State.STARTED); - ipFilter.setHttpServerTransport(httpTransport); + ipFilter.setBoundHttpTransportAddress(httpTransport.boundAddress()); } if (isHttpEnabled) { diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 84347f29857..2e2a58dcb15 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -7,13 +7,13 @@ package org.elasticsearch.xpack; import org.elasticsearch.SpecialPermission; import org.elasticsearch.action.ActionModule; -import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.index.IndexModule; import org.elasticsearch.license.plugin.LicensePlugin; import org.elasticsearch.marvel.MarvelPlugin; @@ -120,10 +120,10 @@ public class XPackPlugin extends Plugin { watcherPlugin.onModule(module); } - public void onModule(ClusterModule module) { + public void onModule(SettingsModule module) { shieldPlugin.onModule(module); - watcherPlugin.onModule(module); marvelPlugin.onModule(module); + watcherPlugin.onModule(module); } public void onModule(NetworkModule module) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherModule.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherModule.java index 6f6d3dc8d08..cd2cd63e645 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherModule.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherModule.java @@ -8,6 +8,7 @@ package org.elasticsearch.watcher; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.multibindings.Multibinder; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.watcher.support.WatcherIndexTemplateRegistry; import org.elasticsearch.watcher.support.WatcherIndexTemplateRegistry.TemplateConfig; @@ -19,11 +20,15 @@ public class WatcherModule extends AbstractModule { public static final String HISTORY_TEMPLATE_NAME = "watch_history"; public static final String TRIGGERED_TEMPLATE_NAME = "triggered_watches"; public static final String WATCHES_TEMPLATE_NAME = "watches"; + public static final Setting HISTORY_TEMPLATE_SETTING = Setting.groupSetting("watcher.history.index.", true, Setting.Scope.CLUSTER); + public static final Setting TRIGGERED_TEMPLATE_SETTING = Setting.groupSetting("watcher.triggered_watches.index.", true, Setting.Scope.CLUSTER); + public static final Setting WATCHES_TEMPLATE_SETTING = Setting.groupSetting("watcher.watches.index.", true, Setting.Scope.CLUSTER); + public final static TemplateConfig[] TEMPLATE_CONFIGS = new TemplateConfig[]{ - new TemplateConfig(TRIGGERED_TEMPLATE_NAME, "watcher.triggered_watches.index"), - new TemplateConfig(HISTORY_TEMPLATE_NAME, "watcher.history.index"), - new TemplateConfig(WATCHES_TEMPLATE_NAME, "watcher.watches.index") + new TemplateConfig(TRIGGERED_TEMPLATE_NAME, TRIGGERED_TEMPLATE_SETTING), + new TemplateConfig(HISTORY_TEMPLATE_NAME, HISTORY_TEMPLATE_SETTING), + new TemplateConfig(WATCHES_TEMPLATE_NAME, WATCHES_TEMPLATE_SETTING) }; protected final Settings settings; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java index aef44c9e58a..11e45c685b8 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/WatcherPlugin.java @@ -20,6 +20,7 @@ import org.elasticsearch.common.logging.support.LoggerMessageFormat; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.ScriptModule; import org.elasticsearch.shield.authz.AuthorizationModule; @@ -184,10 +185,13 @@ public class WatcherPlugin extends Plugin { } } - public void onModule(ClusterModule module) { + public void onModule(SettingsModule module) { for (TemplateConfig templateConfig : WatcherModule.TEMPLATE_CONFIGS) { - module.registerClusterDynamicSetting(templateConfig.getDynamicSettingsPrefix(), Validator.EMPTY); + module.registerSetting(templateConfig.getSetting()); } + module.registerSetting(InternalSlackService.SLACK_ACCOUNT_SETTING); + module.registerSetting(InternalEmailService.EMAIL_ACCOUNT_SETTING); + module.registerSetting(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING); } public void onModule(NetworkModule module) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/InternalEmailService.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/InternalEmailService.java index 92bf6e1a1b7..dbec5ed1dcc 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/InternalEmailService.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/InternalEmailService.java @@ -9,8 +9,9 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.component.AbstractLifecycleComponent; 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.Settings; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.watcher.shield.WatcherSettingsFilter; import org.elasticsearch.watcher.support.secret.SecretService; @@ -25,22 +26,24 @@ public class InternalEmailService extends AbstractLifecycleComponent EMAIL_ACCOUNT_SETTING = Setting.groupSetting("watcher.actions.email.service.", true, Setting.Scope.CLUSTER); + + @Inject - public InternalEmailService(Settings settings, SecretService secretService, NodeSettingsService nodeSettingsService, WatcherSettingsFilter settingsFilter) { + public InternalEmailService(Settings settings, SecretService secretService, ClusterSettings clusterSettings, WatcherSettingsFilter settingsFilter) { super(settings); this.secretService = secretService; - nodeSettingsService.addListener(new NodeSettingsService.Listener() { - @Override - public void onRefreshSettings(Settings settings) { - reset(settings); - } - }); + clusterSettings.addSettingsUpdateConsumer(EMAIL_ACCOUNT_SETTING, this::setEmailAccountSettings); settingsFilter.filterOut("watcher.actions.email.service.account.*.smtp.password"); + setEmailAccountSettings(EMAIL_ACCOUNT_SETTING.get(settings)); + } + + private void setEmailAccountSettings(Settings settings) { + this.accounts = createAccounts(settings, logger); } @Override protected void doStart() throws ElasticsearchException { - reset(settings); } @Override @@ -75,24 +78,6 @@ public class InternalEmailService extends AbstractLifecycleComponent HIPCHAT_ACCOUNT_SETTING = Setting.groupSetting("watcher.actions.hipchat.service.", true, Setting.Scope.CLUSTER); @Inject - public InternalHipChatService(Settings settings, HttpClient httpClient, NodeSettingsService nodeSettingsService, WatcherSettingsFilter settingsFilter) { + public InternalHipChatService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings, WatcherSettingsFilter settingsFilter) { super(settings); this.httpClient = httpClient; - nodeSettingsService.addListener(new NodeSettingsService.Listener() { - @Override - public void onRefreshSettings(Settings settings) { - reset(settings); - } - }); settingsFilter.filterOut("watcher.actions.hipchat.service.account.*.auth_token"); + clusterSettings.addSettingsUpdateConsumer(HIPCHAT_ACCOUNT_SETTING, this::setHipchatAccountSetting); } @Override protected void doStart() { - reset(settings); + setHipchatAccountSetting(HIPCHAT_ACCOUNT_SETTING.get(settings)); } @Override @@ -46,6 +43,10 @@ public class InternalHipChatService extends AbstractLifecycleComponent implements SlackService { private final HttpClient httpClient; + public static final Setting SLACK_ACCOUNT_SETTING = Setting.groupSetting("watcher.actions.slack.service.", true, Setting.Scope.CLUSTER); private volatile SlackAccounts accounts; @Inject - public InternalSlackService(Settings settings, HttpClient httpClient, NodeSettingsService nodeSettingsService, WatcherSettingsFilter settingsFilter) { + public InternalSlackService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings, WatcherSettingsFilter settingsFilter) { super(settings); this.httpClient = httpClient; - nodeSettingsService.addListener(new NodeSettingsService.Listener() { - @Override - public void onRefreshSettings(Settings settings) { - reset(settings); - } - }); settingsFilter.filterOut("watcher.actions.slack.service.account.*.url"); + clusterSettings.addSettingsUpdateConsumer(SLACK_ACCOUNT_SETTING, this::setSlackAccountSetting); } @Override protected void doStart() { - reset(settings); + setSlackAccountSetting(SLACK_ACCOUNT_SETTING.get(settings)); } @Override @@ -51,27 +48,14 @@ public class InternalSlackService extends AbstractLifecycleComponent customIndexSettings; @Inject - public WatcherIndexTemplateRegistry(Settings settings, NodeSettingsService nodeSettingsService, ClusterService clusterService, + public WatcherIndexTemplateRegistry(Settings settings, ClusterSettings clusterSettings, ClusterService clusterService, ThreadPool threadPool, ClientProxy client, Set configs) { super(settings); this.client = client; @@ -53,12 +54,12 @@ public class WatcherIndexTemplateRegistry extends AbstractComponent implements C this.clusterService = clusterService; this.indexTemplates = unmodifiableSet(new HashSet<>(configs)); clusterService.add(this); - nodeSettingsService.addListener(this); Map customIndexSettings = new HashMap<>(); for (TemplateConfig indexTemplate : indexTemplates) { - Settings customSettings = this.settings.getAsSettings(indexTemplate.getSettingsPrefix()); - customIndexSettings.put(indexTemplate.getSettingsPrefix(), customSettings); + clusterSettings.addSettingsUpdateConsumer(indexTemplate.getSetting(), (s) -> updateConfig(indexTemplate, s)); + Settings customSettings = this.settings.getAsSettings(indexTemplate.getSetting().getKey()); + customIndexSettings.put(indexTemplate.getSetting().getKey(), customSettings); } this.customIndexSettings = unmodifiableMap(customIndexSettings); } @@ -101,51 +102,44 @@ public class WatcherIndexTemplateRegistry extends AbstractComponent implements C } } - @Override - public void onRefreshSettings(Settings settings) { + private void updateConfig(TemplateConfig config, Settings settings) { if (clusterService.localNode().masterNode() == false) { // Only the node that runs or will run Watcher should update the templates. Otherwise unnecessary put template // calls would happen return; } + if (settings.names().isEmpty()) { + return; + } - for (TemplateConfig config : indexTemplates) { - Settings newSettings = Settings.builder() - .put(settings.getAsSettings(config.getSettingsPrefix())) - .build(); - if (newSettings.names().isEmpty()) { + Settings existingSettings = customIndexSettings.get(config.getSetting().getKey()); + if (existingSettings == null) { + existingSettings = Settings.EMPTY; + } + + boolean changed = false; + Settings.Builder builder = Settings.builder().put(existingSettings); + for (Map.Entry newSettingsEntry : settings.getAsMap().entrySet()) { + String name = "index." + newSettingsEntry.getKey(); + if (FORBIDDEN_INDEX_SETTING.equals(name)) { + logger.warn("overriding the default [{}} setting is forbidden. ignoring...", name); continue; } - Settings existingSettings = customIndexSettings.get(config.getSettingsPrefix()); - if (existingSettings == null) { - existingSettings = Settings.EMPTY; + String newValue = newSettingsEntry.getValue(); + String currentValue = existingSettings.get(name); + if (!newValue.equals(currentValue)) { + changed = true; + builder.put(name, newValue); + logger.info("changing setting [{}] from [{}] to [{}]", name, currentValue, newValue); } + } - boolean changed = false; - Settings.Builder builder = Settings.builder().put(existingSettings); - for (Map.Entry newSettingsEntry : newSettings.getAsMap().entrySet()) { - String name = "index." + newSettingsEntry.getKey(); - if (FORBIDDEN_INDEX_SETTING.equals(name)) { - logger.warn("overriding the default [{}} setting is forbidden. ignoring...", name); - continue; - } - - String newValue = newSettingsEntry.getValue(); - String currentValue = existingSettings.get(name); - if (!newValue.equals(currentValue)) { - changed = true; - builder.put(name, newValue); - logger.info("changing setting [{}] from [{}] to [{}]", name, currentValue, newValue); - } - } - - if (changed) { - Map customIndexSettings = new HashMap(this.customIndexSettings); - customIndexSettings.put(config.getSettingsPrefix(), builder.build()); - this.customIndexSettings = customIndexSettings; - putTemplate(config, false); - } + if (changed) { + Map customIndexSettings = new HashMap(this.customIndexSettings); + customIndexSettings.put(config.getSetting().getKey(), builder.build()); + this.customIndexSettings = customIndexSettings; + putTemplate(config, false); } } @@ -171,7 +165,7 @@ public class WatcherIndexTemplateRegistry extends AbstractComponent implements C } PutIndexTemplateRequest request = new PutIndexTemplateRequest(config.getTemplateName()).source(template); - Settings customSettings = customIndexSettings.get(config.getSettingsPrefix()); + Settings customSettings = customIndexSettings.get(config.getSetting().getKey()); if (customSettings != null && customSettings.names().size() > 0) { Settings updatedSettings = Settings.builder() .put(request.settings()) @@ -190,23 +184,19 @@ public class WatcherIndexTemplateRegistry extends AbstractComponent implements C public static class TemplateConfig { private final String templateName; - private final String settingsPrefix; + private final Setting setting; - public TemplateConfig(String templateName, String settingsPrefix) { + public TemplateConfig(String templateName, Setting setting) { this.templateName = templateName; - this.settingsPrefix = settingsPrefix; + this.setting = setting; } public String getTemplateName() { return templateName; } - public String getSettingsPrefix() { - return settingsPrefix; - } - - public String getDynamicSettingsPrefix() { - return settingsPrefix + ".*"; + public Setting getSetting() { + return setting; } } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/InternalEmailServiceTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/InternalEmailServiceTests.java index 6dc687c5677..cb1918fe0c4 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/InternalEmailServiceTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/InternalEmailServiceTests.java @@ -6,9 +6,8 @@ package org.elasticsearch.watcher.actions.email.service; import org.elasticsearch.common.logging.ESLogger; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.shield.WatcherSettingsFilter; import org.elasticsearch.watcher.support.secret.Secret; @@ -16,6 +15,8 @@ import org.elasticsearch.watcher.support.secret.SecretService; import org.junit.After; import org.junit.Before; +import java.util.Collections; + import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.sameInstance; @@ -33,7 +34,7 @@ public class InternalEmailServiceTests extends ESTestCase { @Before public void init() throws Exception { accounts = mock(Accounts.class); - service = new InternalEmailService(Settings.EMPTY, new SecretService.PlainText(), new NodeSettingsService(Settings.EMPTY), WatcherSettingsFilter.Noop.INSTANCE) { + service = new InternalEmailService(Settings.EMPTY, new SecretService.PlainText(), new ClusterSettings(Settings.EMPTY, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING)), WatcherSettingsFilter.Noop.INSTANCE) { @Override protected Accounts createAccounts(Settings settings, ESLogger logger) { return accounts; diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/ManualPublicSmtpServersTester.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/ManualPublicSmtpServersTester.java index f0acbd44461..8b036e82b5a 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/ManualPublicSmtpServersTester.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/email/service/ManualPublicSmtpServersTester.java @@ -8,15 +8,16 @@ package org.elasticsearch.watcher.actions.email.service; import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.common.inject.Provider; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.watcher.shield.WatcherSettingsFilter; import org.elasticsearch.watcher.support.secret.SecretService; import java.io.IOException; import java.io.InputStream; +import java.util.Collections; @AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/379") public class ManualPublicSmtpServersTester { @@ -128,7 +129,7 @@ public class ManualPublicSmtpServersTester { static InternalEmailService startEmailService(Settings.Builder builder) { Settings settings = builder.build(); - InternalEmailService service = new InternalEmailService(settings, new SecretService.PlainText(), new NodeSettingsService(settings), WatcherSettingsFilter.Noop.INSTANCE); + InternalEmailService service = new InternalEmailService(settings, new SecretService.PlainText(), new ClusterSettings(settings, Collections.singleton(InternalEmailService.EMAIL_ACCOUNT_SETTING)), WatcherSettingsFilter.Noop.INSTANCE); service.start(); return service; } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/hipchat/service/InternalHipChatServiceTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/hipchat/service/InternalHipChatServiceTests.java index beb3882624a..7be3c576e91 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/hipchat/service/InternalHipChatServiceTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/actions/hipchat/service/InternalHipChatServiceTests.java @@ -5,14 +5,16 @@ */ package org.elasticsearch.watcher.actions.hipchat.service; +import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; -import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.watcher.shield.WatcherSettingsFilter; import org.elasticsearch.watcher.support.http.HttpClient; import org.junit.Before; +import java.util.Collections; + import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; @@ -29,13 +31,11 @@ import static org.mockito.Mockito.verify; */ public class InternalHipChatServiceTests extends ESTestCase { private HttpClient httpClient; - private NodeSettingsService nodeSettingsService; private WatcherSettingsFilter settingsFilter; @Before public void init() throws Exception { httpClient = mock(HttpClient.class); - nodeSettingsService = mock(NodeSettingsService.class); settingsFilter = mock(WatcherSettingsFilter.class); } @@ -58,7 +58,7 @@ public class InternalHipChatServiceTests extends ESTestCase { settingsBuilder.put("watcher.actions.hipchat.service.account." + accountName + ".port", port); } buildMessageDefaults(accountName, settingsBuilder, defaultRoom, null, defaultFrom, defaultColor, defaultFormat, defaultNotify); - InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, nodeSettingsService, settingsFilter); + InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, new ClusterSettings(settingsBuilder.build(), Collections.singleton(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING)), settingsFilter); service.start(); HipChatAccount account = service.getAccount(accountName); @@ -107,7 +107,7 @@ public class InternalHipChatServiceTests extends ESTestCase { settingsBuilder.put("watcher.actions.hipchat.service.account." + accountName + ".port", port); } buildMessageDefaults(accountName, settingsBuilder, null, null, defaultFrom, defaultColor, defaultFormat, defaultNotify); - InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, nodeSettingsService, settingsFilter); + InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, new ClusterSettings(settingsBuilder.build(), Collections.singleton(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING)), settingsFilter); service.start(); HipChatAccount account = service.getAccount(accountName); @@ -136,7 +136,7 @@ public class InternalHipChatServiceTests extends ESTestCase { Settings.Builder settingsBuilder = Settings.builder() .put("watcher.actions.hipchat.service.account." + accountName + ".profile", HipChatAccount.Profile.INTEGRATION.value()) .put("watcher.actions.hipchat.service.account." + accountName + ".auth_token", "_token"); - try (InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, nodeSettingsService, + try (InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, new ClusterSettings(settingsBuilder.build(), Collections.singleton(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING)), settingsFilter)) { service.start(); fail("Expected SettingsException"); @@ -164,7 +164,7 @@ public class InternalHipChatServiceTests extends ESTestCase { settingsBuilder.put("watcher.actions.hipchat.service.account." + accountName + ".port", port); } buildMessageDefaults(accountName, settingsBuilder, defaultRoom, defaultUser, null, defaultColor, defaultFormat, defaultNotify); - InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, nodeSettingsService, settingsFilter); + InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, new ClusterSettings(settingsBuilder.build(), Collections.singleton(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING)), settingsFilter); service.start(); HipChatAccount account = service.getAccount(accountName); @@ -227,7 +227,7 @@ public class InternalHipChatServiceTests extends ESTestCase { buildMessageDefaults(name, settingsBuilder, null, null, null, defaultColor, defaultFormat, defaultNotify); } - InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, nodeSettingsService, settingsFilter); + InternalHipChatService service = new InternalHipChatService(settingsBuilder.build(), httpClient, new ClusterSettings(settingsBuilder.build(), Collections.singleton(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING)), settingsFilter); service.start(); for (int i = 0; i < 5; i++) { diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/NoMasterNodeTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/NoMasterNodeTests.java index a33add93404..0aac1dedb38 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/NoMasterNodeTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/watcher/test/integration/NoMasterNodeTests.java @@ -78,7 +78,7 @@ public class NoMasterNodeTests extends AbstractWatcherIntegrationTestCase { return Settings.builder() .put(settings) .put(unicastSettings) - .put(ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES, 2) + .put(ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING.getKey(), 2) .put("discovery.type", "zen") .build(); }