Settings: Cut over to affix settings where filters are needed (elastic/x-pack-elasticsearch#3685)

x-pack makes extensive use of group settings in its exporters as well as
its notification services. This does not cope well with settings being
marked as filtered.

This replaces a fair share of group settings (unfortunately not all of
them) with affix key settings, allowing for better filtering and
registering of settings.

Original commit: elastic/x-pack-elasticsearch@968bc8c2ee
This commit is contained in:
Alexander Reelsen 2018-01-24 13:14:08 +01:00 committed by GitHub
parent 4475b718a4
commit 1ebccfcf50
37 changed files with 517 additions and 277 deletions

View File

@ -171,24 +171,24 @@ public class Monitoring extends Plugin implements ActionPlugin {
@Override
public List<Setting<?>> getSettings() {
return Collections.unmodifiableList(
Arrays.asList(MonitoringField.HISTORY_DURATION,
CLEAN_WATCHER_HISTORY,
MonitoringService.INTERVAL,
Exporters.EXPORTERS_SETTINGS,
Collector.INDICES,
ClusterStatsCollector.CLUSTER_STATS_TIMEOUT,
IndexRecoveryCollector.INDEX_RECOVERY_TIMEOUT,
IndexRecoveryCollector.INDEX_RECOVERY_ACTIVE_ONLY,
IndexStatsCollector.INDEX_STATS_TIMEOUT,
JobStatsCollector.JOB_STATS_TIMEOUT,
NodeStatsCollector.NODE_STATS_TIMEOUT)
);
List<Setting<?>> settings = new ArrayList<>();
settings.add(MonitoringField.HISTORY_DURATION);
settings.add(CLEAN_WATCHER_HISTORY);
settings.add(MonitoringService.INTERVAL);
settings.add(Collector.INDICES);
settings.add(ClusterStatsCollector.CLUSTER_STATS_TIMEOUT);
settings.add(IndexRecoveryCollector.INDEX_RECOVERY_TIMEOUT);
settings.add(IndexRecoveryCollector.INDEX_RECOVERY_ACTIVE_ONLY);
settings.add(IndexStatsCollector.INDEX_STATS_TIMEOUT);
settings.add(JobStatsCollector.JOB_STATS_TIMEOUT);
settings.add(NodeStatsCollector.NODE_STATS_TIMEOUT);
settings.addAll(Exporters.getSettings());
return Collections.unmodifiableList(settings);
}
@Override
public List<String> getSettingsFilter() {
final String exportersKey = Exporters.EXPORTERS_SETTINGS.getKey();
final String exportersKey = "xpack.monitoring.exporters.";
return Collections.unmodifiableList(Arrays.asList(exportersKey + "*.auth.*", exportersKey + "*.ssl.*"));
}
}

View File

@ -16,7 +16,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@ -142,7 +141,8 @@ public class ClusterAlertsUtil {
* @throws SettingsException if an unknown cluster alert ID exists in the blacklist.
*/
public static List<String> getClusterAlertsBlacklist(final Exporter.Config config) {
final List<String> blacklist = config.settings().getAsList(CLUSTER_ALERTS_BLACKLIST_SETTING, Collections.emptyList());
final List<String> blacklist =
CLUSTER_ALERTS_BLACKLIST_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// validate the blacklist only contains recognized IDs
if (blacklist.isEmpty() == false) {
@ -151,9 +151,8 @@ public class ClusterAlertsUtil {
if (unknownIds.isEmpty() == false) {
throw new SettingsException(
"[" + Exporter.settingFQN(config, CLUSTER_ALERTS_BLACKLIST_SETTING) + "] contains unrecognized Cluster Alert IDs [" +
String.join(", ", unknownIds) + "]"
);
"[" + CLUSTER_ALERTS_BLACKLIST_SETTING.getConcreteSettingForNamespace(config.name()).getKey() +
"] contains unrecognized Cluster Alert IDs [" + String.join(", ", unknownIds) + "]");
}
}

View File

@ -6,36 +6,70 @@
package org.elasticsearch.xpack.monitoring.exporter;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.license.XPackLicenseState;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
public abstract class Exporter implements AutoCloseable {
private static final Setting.AffixSetting<Boolean> ENABLED_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","enabled",
(key) -> Setting.boolSetting(key, true, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> TYPE_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","type",
(key) -> Setting.simpleString(key, (v, s) -> {
switch (v) {
case "":
case "http":
case "local":
break;
default:
throw new IllegalArgumentException("only exporter types [http] and [local] are allowed [" + v +
"] is invalid");
}
}, Property.Dynamic, Property.NodeScope));
/**
* Every {@code Exporter} adds the ingest pipeline to bulk requests, but they should, at the exporter level, allow that to be disabled.
* <p>
* Note: disabling it obviously loses any benefit of using it, but it does allow clusters that don't run with ingest to not use it.
*/
public static final String USE_INGEST_PIPELINE_SETTING = "use_ingest";
public static final Setting.AffixSetting<Boolean> USE_INGEST_PIPELINE_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","use_ingest",
(key) -> Setting.boolSetting(key, true, Property.Dynamic, Property.NodeScope));
/**
* Every {@code Exporter} allows users to explicitly disable cluster alerts.
*/
public static final String CLUSTER_ALERTS_MANAGEMENT_SETTING = "cluster_alerts.management.enabled";
public static final Setting.AffixSetting<Boolean> CLUSTER_ALERTS_MANAGEMENT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.", "cluster_alerts.management.enabled",
(key) -> Setting.boolSetting(key, true, Property.Dynamic, Property.NodeScope));
/**
* Every {@code Exporter} allows users to explicitly disable specific cluster alerts.
* <p>
* When cluster alerts management is enabled, this should delete anything blacklisted here in addition to not creating it.
*/
public static final String CLUSTER_ALERTS_BLACKLIST_SETTING = "cluster_alerts.management.blacklist";
public static final Setting.AffixSetting<List<String>> CLUSTER_ALERTS_BLACKLIST_SETTING = Setting
.affixKeySetting("xpack.monitoring.exporters.", "cluster_alerts.management.blacklist",
(key) -> Setting.listSetting(key, Collections.emptyList(), Function.identity(), Property.Dynamic, Property.NodeScope));
/**
* Every {@code Exporter} allows users to use a different index time format.
*/
public static final String INDEX_NAME_TIME_FORMAT_SETTING = "index.name.time_format";
private static final Setting.AffixSetting<String> INDEX_NAME_TIME_FORMAT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","index.name.time_format",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final String INDEX_FORMAT = "YYYY.MM.dd";
protected final Config config;
@ -77,43 +111,39 @@ public abstract class Exporter implements AutoCloseable {
protected abstract void doClose();
protected static String settingFQN(final Config config) {
return Exporters.EXPORTERS_SETTINGS.getKey() + config.name;
}
public static String settingFQN(final Config config, final String setting) {
return Exporters.EXPORTERS_SETTINGS.getKey() + config.name + "." + setting;
}
protected static DateTimeFormatter dateTimeFormatter(final Config config) {
String format = config.settings().get(INDEX_NAME_TIME_FORMAT_SETTING, "YYYY.MM.dd");
Setting<String> setting = INDEX_NAME_TIME_FORMAT_SETTING.getConcreteSettingForNamespace(config.name);
String format = setting.exists(config.settings()) ? setting.get(config.settings()) : INDEX_FORMAT;
try {
return DateTimeFormat.forPattern(format).withZoneUTC();
} catch (IllegalArgumentException e) {
throw new SettingsException("[" + settingFQN(config, INDEX_NAME_TIME_FORMAT_SETTING)
+ "] invalid index name time format: [" + format + "]", e);
throw new SettingsException("[" + INDEX_NAME_TIME_FORMAT_SETTING.getKey() + "] invalid index name time format: ["
+ format + "]", e);
}
}
public static List<Setting.AffixSetting<?>> getSettings() {
return Arrays.asList(USE_INGEST_PIPELINE_SETTING, CLUSTER_ALERTS_MANAGEMENT_SETTING, TYPE_SETTING, ENABLED_SETTING,
INDEX_NAME_TIME_FORMAT_SETTING, CLUSTER_ALERTS_BLACKLIST_SETTING);
}
public static class Config {
private final String name;
private final String type;
private final boolean enabled;
private final Settings globalSettings;
private final Settings settings;
private final ClusterService clusterService;
private final XPackLicenseState licenseState;
public Config(String name, String type, Settings globalSettings, Settings settings,
public Config(String name, String type, Settings settings,
ClusterService clusterService, XPackLicenseState licenseState) {
this.name = name;
this.type = type;
this.globalSettings = globalSettings;
this.settings = settings;
this.clusterService = clusterService;
this.licenseState = licenseState;
this.enabled = settings.getAsBoolean("enabled", true);
this.enabled = ENABLED_SETTING.getConcreteSettingForNamespace(name).get(settings);
}
public String name() {
@ -128,10 +158,6 @@ public abstract class Exporter implements AutoCloseable {
return enabled;
}
public Settings globalSettings() {
return globalSettings;
}
public Settings settings() {
return settings;
}

View File

@ -18,6 +18,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.monitoring.exporter.http.HttpExporter;
import org.elasticsearch.xpack.core.monitoring.exporter.MonitoringDoc;
import org.elasticsearch.xpack.monitoring.exporter.local.LocalExporter;
@ -33,16 +34,9 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.common.settings.Setting.groupSetting;
public class Exporters extends AbstractLifecycleComponent implements Iterable<Exporter> {
/**
* Settings/Options per configured exporter
*/
public static final Setting<Settings> EXPORTERS_SETTINGS =
groupSetting("xpack.monitoring.exporters.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private final Map<String, Exporter.Factory> factories;
private final AtomicReference<Map<String, Exporter>> exporters;
private final ClusterService clusterService;
@ -60,14 +54,15 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
this.clusterService = Objects.requireNonNull(clusterService);
this.licenseState = Objects.requireNonNull(licenseState);
clusterService.getClusterSettings().addSettingsUpdateConsumer(EXPORTERS_SETTINGS, this::setExportersSetting);
clusterService.getClusterSettings().addSettingsUpdateConsumer(this::setExportersSetting, getSettings());
// this ensures, that logging is happening by adding an empty consumer per affix setting
for (Setting.AffixSetting<?> affixSetting : getSettings()) {
clusterService.getClusterSettings().addAffixUpdateConsumer(affixSetting, (s, o) -> {}, (s, o) -> {});
}
}
private void setExportersSetting(Settings exportersSetting) {
if (this.lifecycleState() == Lifecycle.State.STARTED) {
if (exportersSetting.names().isEmpty()) {
return;
}
if (this.lifecycle.started()) {
Map<String, Exporter> updated = initExporters(exportersSetting);
closeExporters(logger, this.exporters.getAndSet(updated));
}
@ -75,7 +70,7 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
@Override
protected void doStart() {
exporters.set(initExporters(EXPORTERS_SETTINGS.get(settings)));
exporters.set(initExporters(settings));
}
@Override
@ -129,10 +124,11 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
return bulks.isEmpty() ? null : new ExportBulk.Compound(bulks, threadContext);
}
Map<String, Exporter> initExporters(Settings exportersSettings) {
Map<String, Exporter> initExporters(Settings settings) {
Set<String> singletons = new HashSet<>();
Map<String, Exporter> exporters = new HashMap<>();
boolean hasDisabled = false;
Settings exportersSettings = settings.getByPrefix("xpack.monitoring.exporters.");
for (String name : exportersSettings.names()) {
Settings exporterSettings = exportersSettings.getAsSettings(name);
String type = exporterSettings.get("type");
@ -143,7 +139,7 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
if (factory == null) {
throw new SettingsException("unknown exporter type [" + type + "] set for exporter [" + name + "]");
}
Exporter.Config config = new Exporter.Config(name, type, settings, exporterSettings, clusterService, licenseState);
Exporter.Config config = new Exporter.Config(name, type, settings, clusterService, licenseState);
if (!config.enabled()) {
hasDisabled = true;
if (logger.isDebugEnabled()) {
@ -171,8 +167,7 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
//
if (exporters.isEmpty() && !hasDisabled) {
Exporter.Config config =
new Exporter.Config("default_" + LocalExporter.TYPE, LocalExporter.TYPE, settings, Settings.EMPTY,
clusterService, licenseState);
new Exporter.Config("default_" + LocalExporter.TYPE, LocalExporter.TYPE, settings, clusterService, licenseState);
exporters.put(config.name(), factories.get(LocalExporter.TYPE).create(config));
}
@ -210,4 +205,14 @@ public class Exporters extends AbstractLifecycleComponent implements Iterable<Ex
listener.onResponse(null);
}
}
/**
* Return all the settings of all the exporters, no matter if HTTP or Local
*/
public static List<Setting.AffixSetting<?>> getSettings() {
List<Setting.AffixSetting<?>> settings = new ArrayList<>();
settings.addAll(Exporter.getSettings());
settings.addAll(HttpExporter.getSettings());
return settings;
}
}

View File

@ -22,9 +22,12 @@ import org.elasticsearch.client.sniff.ElasticsearchHostsSniffer.Scheme;
import org.elasticsearch.client.sniff.Sniffer;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.unit.TimeValue;
@ -41,12 +44,14 @@ import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Supplier;
/**
@ -71,45 +76,66 @@ public class HttpExporter extends Exporter {
/**
* A string array representing the Elasticsearch node(s) to communicate with over HTTP(S).
*/
public static final String HOST_SETTING = "host";
public static final Setting.AffixSetting<List<String>> HOST_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","host",
(key) -> Setting.listSetting(key, Collections.emptyList(), Function.identity(),
Property.Dynamic, Property.NodeScope));
/**
* Master timeout associated with bulk requests.
*/
public static final String BULK_TIMEOUT_SETTING = "bulk.timeout";
public static final Setting.AffixSetting<TimeValue> BULK_TIMEOUT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","bulk.timeout",
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope));
/**
* Timeout used for initiating a connection.
*/
public static final String CONNECTION_TIMEOUT_SETTING = "connection.timeout";
public static final Setting.AffixSetting<TimeValue> CONNECTION_TIMEOUT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","connection.timeout",
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(6), Property.Dynamic, Property.NodeScope));
/**
* Timeout used for reading from the connection.
*/
public static final String CONNECTION_READ_TIMEOUT_SETTING = "connection.read_timeout";
public static final Setting.AffixSetting<TimeValue> CONNECTION_READ_TIMEOUT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","connection.read_timeout",
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(60), Property.Dynamic, Property.NodeScope));
/**
* Username for basic auth.
*/
public static final String AUTH_USERNAME_SETTING = "auth.username";
public static final Setting.AffixSetting<String> AUTH_USERNAME_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","auth.username",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
/**
* Password for basic auth.
*/
public static final String AUTH_PASSWORD_SETTING = "auth.password";
public static final Setting.AffixSetting<String> AUTH_PASSWORD_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","auth.password",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
/**
* The SSL settings.
*
* @see SSLService
*/
public static final String SSL_SETTING = "ssl";
public static final Setting.AffixSetting<Settings> SSL_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","ssl",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope, Property.Filtered));
/**
* Proxy setting to allow users to send requests to a remote cluster that requires a proxy base path.
*/
public static final String PROXY_BASE_PATH_SETTING = "proxy.base_path";
public static final Setting.AffixSetting<String> PROXY_BASE_PATH_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","proxy.base_path",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
/**
* A boolean setting to enable or disable sniffing for extra connections.
*/
public static final String SNIFF_ENABLED_SETTING = "sniff.enabled";
public static final Setting.AffixSetting<Boolean> SNIFF_ENABLED_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","sniff.enabled",
(key) -> Setting.boolSetting(key, false, Property.Dynamic, Property.NodeScope));
/**
* A parent setting to header key/value pairs, whose names are user defined.
*/
public static final String HEADERS_SETTING = "headers";
public static final Setting.AffixSetting<Settings> HEADERS_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","headers",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope));
/**
* Blacklist of headers that the user is not allowed to set.
* <p>
@ -119,15 +145,21 @@ public class HttpExporter extends Exporter {
/**
* ES level timeout used when checking and writing templates (used to speed up tests)
*/
public static final String TEMPLATE_CHECK_TIMEOUT_SETTING = "index.template.master_timeout";
public static final Setting.AffixSetting<TimeValue> TEMPLATE_CHECK_TIMEOUT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","index.template.master_timeout",
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope));
/**
* A boolean setting to enable or disable whether to create placeholders for the old templates.
*/
public static final String TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING = "index.template.create_legacy_templates";
public static final Setting.AffixSetting<Boolean> TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","index.template.create_legacy_templates",
(key) -> Setting.boolSetting(key, true, Property.Dynamic, Property.NodeScope));
/**
* ES level timeout used when checking and writing pipelines (used to speed up tests)
*/
public static final String PIPELINE_CHECK_TIMEOUT_SETTING = "index.pipeline.master_timeout";
public static final Setting.AffixSetting<TimeValue> PIPELINE_CHECK_TIMEOUT_SETTING =
Setting.affixKeySetting("xpack.monitoring.exporters.","index.pipeline.master_timeout",
(key) -> Setting.timeSetting(key, TimeValue.timeValueSeconds(10), Property.Dynamic, Property.NodeScope));
/**
* Minimum supported version of the remote monitoring cluster (same major).
@ -234,14 +266,15 @@ public class HttpExporter extends Exporter {
*/
static RestClient createRestClient(final Config config, final SSLService sslService, final NodeFailureListener listener) {
final RestClientBuilder builder = RestClient.builder(createHosts(config)).setFailureListener(listener);
final String proxyBasePath = config.settings().get(PROXY_BASE_PATH_SETTING);
Setting<String> concreteSetting = PROXY_BASE_PATH_SETTING.getConcreteSettingForNamespace(config.name());
final String proxyBasePath = concreteSetting.get(config.settings());
// allow the user to configure proxies
if (proxyBasePath != null) {
if (Strings.isNullOrEmpty(proxyBasePath) == false) {
try {
builder.setPathPrefix(proxyBasePath);
} catch (final IllegalArgumentException e) {
throw new SettingsException("[" + settingFQN(config, "proxy.base_path") + "] is malformed [" + proxyBasePath + "]", e);
throw new SettingsException("[" + concreteSetting.getKey() + "] is malformed [" + proxyBasePath + "]", e);
}
}
@ -265,12 +298,12 @@ public class HttpExporter extends Exporter {
* @throws IndexOutOfBoundsException if no {@linkplain #HOST_SETTING hosts} are set
*/
static Sniffer createSniffer(final Config config, final RestClient client, final NodeFailureListener listener) {
final Settings settings = config.settings();
Sniffer sniffer = null;
// the sniffer is allowed to be ENABLED; it's disabled by default until we think it's ready for use
if (settings.getAsBoolean(SNIFF_ENABLED_SETTING, false)) {
final List<String> hosts = config.settings().getAsList(HOST_SETTING);
boolean sniffingEnabled = SNIFF_ENABLED_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
if (sniffingEnabled) {
final List<String> hosts = HOST_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// createHosts(config) ensures that all schemes are the same for all hosts!
final Scheme scheme = hosts.get(0).startsWith("https") ? Scheme.HTTPS : Scheme.HTTP;
final ElasticsearchHostsSniffer hostsSniffer =
@ -281,7 +314,7 @@ public class HttpExporter extends Exporter {
// inform the sniffer whenever there's a node failure
listener.setSniffer(sniffer);
logger.debug("[" + settingFQN(config) + "] using host sniffing");
logger.debug("exporter [{}] using host sniffing", config.name());
}
return sniffer;
@ -294,7 +327,7 @@ public class HttpExporter extends Exporter {
* @return Never {@code null}.
*/
static MultiHttpResource createResources(final Config config) {
final String resourceOwnerName = settingFQN(config);
final String resourceOwnerName = "xpack.monitoring.exporters." + config.name();
// order controls the order that each is checked; more direct checks should always happen first (e.g., version checks)
final List<HttpResource> resources = new ArrayList<>();
@ -319,10 +352,11 @@ public class HttpExporter extends Exporter {
* @throws SettingsException if any setting is malformed or if no host is set
*/
private static HttpHost[] createHosts(final Config config) {
final List<String> hosts = config.settings().getAsList(HOST_SETTING);
final List<String> hosts = HOST_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());;
String configKey = HOST_SETTING.getConcreteSettingForNamespace(config.name()).getKey();
if (hosts.isEmpty()) {
throw new SettingsException("missing required setting [" + settingFQN(config, HOST_SETTING) + "]");
throw new SettingsException("missing required setting [" + configKey + "]");
}
final List<HttpHost> httpHosts = new ArrayList<>(hosts.size());
@ -336,7 +370,7 @@ public class HttpExporter extends Exporter {
try {
httpHost = HttpHostBuilder.builder(host).build();
} catch (IllegalArgumentException e) {
throw new SettingsException("[" + settingFQN(config, HOST_SETTING) + "] invalid host: [" + host + "]", e);
throw new SettingsException("[" + configKey + "] invalid host: [" + host + "]", e);
}
if ("http".equals(httpHost.getSchemeName())) {
@ -347,16 +381,13 @@ public class HttpExporter extends Exporter {
// fail if we find them configuring the scheme/protocol in different ways
if (httpHostFound && httpsHostFound) {
throw new SettingsException(
"[" + settingFQN(config, HOST_SETTING) + "] must use a consistent scheme: http or https");
throw new SettingsException("[" + configKey + "] must use a consistent scheme: http or https");
}
httpHosts.add(httpHost);
}
if (logger.isDebugEnabled()) {
logger.debug("[{}] using hosts {}", settingFQN(config), hosts);
}
logger.debug("exporter [{}] using hosts {}", config.name(), hosts);
return httpHosts.toArray(new HttpHost[httpHosts.size()]);
}
@ -369,7 +400,8 @@ public class HttpExporter extends Exporter {
* @throws SettingsException if any header is {@linkplain #BLACKLISTED_HEADERS blacklisted}
*/
private static void configureHeaders(final RestClientBuilder builder, final Config config) {
final Settings headerSettings = config.settings().getAsSettings(HEADERS_SETTING);
Setting<Settings> concreteSetting = HEADERS_SETTING.getConcreteSettingForNamespace(config.name());
final Settings headerSettings = concreteSetting.get(config.settings());
final Set<String> names = headerSettings.names();
// Most users won't define headers
@ -382,14 +414,13 @@ public class HttpExporter extends Exporter {
// record and validate each header as best we can
for (final String name : names) {
if (BLACKLISTED_HEADERS.contains(name)) {
throw new SettingsException("[" + name + "] cannot be overwritten via [" + settingFQN(config, "headers") + "]");
throw new SettingsException("header cannot be overwritten via [" + concreteSetting.getKey() + name + "]");
}
final List<String> values = headerSettings.getAsList(name);
if (values.isEmpty()) {
final String settingName = settingFQN(config, "headers." + name);
throw new SettingsException("headers must have values, missing for setting [" + settingName + "]");
throw new SettingsException("headers must have values, missing for setting [" + concreteSetting.getKey() + name + "]");
}
// add each value as a separate header; they literally appear like:
@ -414,16 +445,19 @@ public class HttpExporter extends Exporter {
* @throws SettingsException if any setting causes issues
*/
private static void configureSecurity(final RestClientBuilder builder, final Config config, final SSLService sslService) {
final Settings sslSettings = config.settings().getAsSettings(SSL_SETTING);
final Settings sslSettings = SSL_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
final SSLIOSessionStrategy sslStrategy = sslService.sslIOSessionStrategy(sslSettings);
final CredentialsProvider credentialsProvider = createCredentialsProvider(config);
List<String> hostList = config.settings().getAsList(HOST_SETTING);
List<String> hostList = HOST_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());;
// sending credentials in plaintext!
if (credentialsProvider != null && hostList.stream().findFirst().orElse("").startsWith("https") == false) {
logger.warn("[" + settingFQN(config) + "] is not using https, but using user authentication with plaintext username/password!");
logger.warn("exporter [{}] is not using https, but using user authentication with plaintext " +
"username/password!", config.name());
}
builder.setHttpClientConfigCallback(new SecurityHttpClientConfigCallback(sslStrategy, credentialsProvider));
if (sslStrategy != null) {
builder.setHttpClientConfigCallback(new SecurityHttpClientConfigCallback(sslStrategy, credentialsProvider));
}
}
/**
@ -433,10 +467,10 @@ public class HttpExporter extends Exporter {
* @param config The exporter's configuration
*/
private static void configureTimeouts(final RestClientBuilder builder, final Config config) {
final Settings settings = config.settings();
final TimeValue connectTimeout = settings.getAsTime(CONNECTION_TIMEOUT_SETTING, TimeValue.timeValueMillis(6000));
final TimeValue socketTimeout = settings.getAsTime(CONNECTION_READ_TIMEOUT_SETTING,
TimeValue.timeValueMillis(connectTimeout.millis() * 10));
final TimeValue connectTimeout =
CONNECTION_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
final TimeValue socketTimeout =
CONNECTION_READ_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// if the values could ever be null, then we should only set it if they're not null
builder.setRequestConfigCallback(new TimeoutRequestConfigCallback(connectTimeout, socketTimeout));
@ -452,15 +486,15 @@ public class HttpExporter extends Exporter {
*/
@Nullable
private static CredentialsProvider createCredentialsProvider(final Config config) {
final Settings settings = config.settings();
final String username = settings.get(AUTH_USERNAME_SETTING);
final String password = settings.get(AUTH_PASSWORD_SETTING);
final String username = AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
final String password = AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// username is required for any auth
if (username == null) {
if (password != null) {
if (Strings.isNullOrEmpty(username)) {
if (Strings.isNullOrEmpty(password) == false) {
throw new SettingsException(
"[" + settingFQN(config, AUTH_PASSWORD_SETTING) + "] without [" + settingFQN(config, AUTH_USERNAME_SETTING) + "]");
"[" + AUTH_PASSWORD_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "] without [" +
AUTH_USERNAME_SETTING.getConcreteSettingForNamespace(config.name()).getKey() + "]");
}
// nothing to configure; default situation for most users
return null;
@ -479,8 +513,7 @@ public class HttpExporter extends Exporter {
* @return Never {@code null}. Can be empty.
*/
static Map<String, String> createDefaultParams(final Config config) {
final Settings settings = config.settings();
final TimeValue bulkTimeout = settings.getAsTime(BULK_TIMEOUT_SETTING, null);
final TimeValue bulkTimeout = BULK_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
final MapBuilder<String, String> params = new MapBuilder<>();
@ -489,7 +522,7 @@ public class HttpExporter extends Exporter {
}
// allow the use of ingest pipelines to be completely optional
if (settings.getAsBoolean(USE_INGEST_PIPELINE_SETTING, true)) {
if (USE_INGEST_PIPELINE_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings())) {
params.put("pipeline", MonitoringTemplateUtils.pipelineName(MonitoringTemplateUtils.TEMPLATE_VERSION));
}
@ -509,8 +542,8 @@ public class HttpExporter extends Exporter {
private static void configureTemplateResources(final Config config,
final String resourceOwnerName,
final List<HttpResource> resources) {
final Settings settings = config.settings();
final TimeValue templateTimeout = settings.getAsTime(TEMPLATE_CHECK_TIMEOUT_SETTING, null);
final TimeValue templateTimeout =
TEMPLATE_CHECK_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// add templates not managed by resolvers
for (final String templateId : MonitoringTemplateUtils.TEMPLATE_IDS) {
@ -521,7 +554,9 @@ public class HttpExporter extends Exporter {
}
// add old templates, like ".monitoring-data-2" and ".monitoring-es-2" so that other versions can continue to work
if (settings.getAsBoolean(TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING, true)) {
boolean createLegacyTemplates =
TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
if (createLegacyTemplates) {
for (final String templateId : MonitoringTemplateUtils.OLD_TEMPLATE_IDS) {
final String templateName = MonitoringTemplateUtils.oldTemplateName(templateId);
final Supplier<String> templateLoader = () -> MonitoringTemplateUtils.createEmptyTemplate(templateId);
@ -540,11 +575,10 @@ public class HttpExporter extends Exporter {
*/
private static void configurePipelineResources(final Config config, final String resourceOwnerName,
final List<HttpResource> resources) {
final Settings settings = config.settings();
// don't require pipelines if we're not using them
if (settings.getAsBoolean(USE_INGEST_PIPELINE_SETTING, true)) {
final TimeValue pipelineTimeout = settings.getAsTime(PIPELINE_CHECK_TIMEOUT_SETTING, null);
if (USE_INGEST_PIPELINE_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings())) {
final TimeValue pipelineTimeout =
PIPELINE_CHECK_TIMEOUT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
// add all pipelines
for (final String pipelineId : MonitoringTemplateUtils.PIPELINE_IDS) {
@ -567,10 +601,8 @@ public class HttpExporter extends Exporter {
*/
private static void configureClusterAlertsResources(final Config config, final String resourceOwnerName,
final List<HttpResource> resources) {
final Settings settings = config.settings();
// don't create watches if we're not using them
if (settings.getAsBoolean(CLUSTER_ALERTS_MANAGEMENT_SETTING, true)) {
if (CLUSTER_ALERTS_MANAGEMENT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings())) {
final ClusterService clusterService = config.clusterService();
final List<HttpResource> watchResources = new ArrayList<>();
final List<String> blacklist = ClusterAlertsUtil.getClusterAlertsBlacklist(config);
@ -612,7 +644,8 @@ public class HttpExporter extends Exporter {
public HttpExportBulk openBulk() {
// block until all resources are verified to exist
if (isExporterReady()) {
return new HttpExportBulk(settingFQN(config), client, defaultParams, dateTimeFormatter, threadContext);
String name = "xpack.monitoring.exporters." + config.name();
return new HttpExportBulk(name, client, defaultParams, dateTimeFormatter, threadContext);
}
return null;
@ -634,4 +667,10 @@ public class HttpExporter extends Exporter {
}
}
}
public static List<Setting.AffixSetting<?>> getSettings() {
return Arrays.asList(HOST_SETTING, TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING, AUTH_PASSWORD_SETTING, AUTH_USERNAME_SETTING,
BULK_TIMEOUT_SETTING, CONNECTION_READ_TIMEOUT_SETTING, CONNECTION_TIMEOUT_SETTING, PIPELINE_CHECK_TIMEOUT_SETTING,
PROXY_BASE_PATH_SETTING, SNIFF_ENABLED_SETTING, TEMPLATE_CHECK_TIMEOUT_SETTING, SSL_SETTING);
}
}

View File

@ -105,7 +105,7 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
this.client = client;
this.clusterService = config.clusterService();
this.licenseState = config.licenseState();
this.useIngest = config.settings().getAsBoolean(USE_INGEST_PIPELINE_SETTING, true);
this.useIngest = USE_INGEST_PIPELINE_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
this.clusterAlertBlacklist = ClusterAlertsUtil.getClusterAlertsBlacklist(config);
this.cleanerService = cleanerService;
this.dateTimeFormatter = dateTimeFormatter(config);
@ -478,8 +478,8 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
* @return {@code true} to use Cluster Alerts.
*/
private boolean canUseWatcher() {
return XPackSettings.WATCHER_ENABLED.get(config.globalSettings()) &&
config.settings().getAsBoolean(CLUSTER_ALERTS_MANAGEMENT_SETTING, true);
return XPackSettings.WATCHER_ENABLED.get(config.settings()) &&
CLUSTER_ALERTS_MANAGEMENT_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
}
@Override

View File

@ -116,12 +116,12 @@ public class ClusterAlertsUtilTests extends ESTestCase {
private Exporter.Config createConfigWithBlacklist(final String name, final List<String> blacklist) {
final Settings settings = Settings.builder()
.putList(Exporter.CLUSTER_ALERTS_BLACKLIST_SETTING, blacklist)
.putList("xpack.monitoring.exporters." + name + ".cluster_alerts.management.blacklist", blacklist)
.build();
final ClusterService clusterService = mock(ClusterService.class);
final XPackLicenseState licenseState = mock(XPackLicenseState.class);
return new Exporter.Config(name, "fake", Settings.EMPTY, settings, clusterService, licenseState);
return new Exporter.Config(name, "local", settings, clusterService, licenseState);
}
}

View File

@ -10,6 +10,7 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.service.ClusterService;
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.common.util.concurrent.AbstractRunnable;
@ -22,6 +23,7 @@ import org.elasticsearch.xpack.core.monitoring.MonitoredSystem;
import org.elasticsearch.xpack.core.monitoring.exporter.MonitoringDoc;
import org.elasticsearch.xpack.monitoring.MonitoringService;
import org.elasticsearch.xpack.monitoring.cleaner.CleanerService;
import org.elasticsearch.xpack.monitoring.exporter.http.HttpExporter;
import org.elasticsearch.xpack.monitoring.exporter.local.LocalExporter;
import org.junit.Before;
@ -33,6 +35,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
@ -72,8 +75,9 @@ public class ExportersTests extends ESTestCase {
clusterService = mock(ClusterService.class);
// default state.version() will be 0, which is "valid"
state = mock(ClusterState.class);
clusterSettings = new ClusterSettings(Settings.EMPTY,
new HashSet<>(Arrays.asList(MonitoringService.INTERVAL, Exporters.EXPORTERS_SETTINGS)));
Set<Setting<?>> settingsSet = new HashSet<>(Exporters.getSettings());
settingsSet.add(MonitoringService.INTERVAL);
clusterSettings = new ClusterSettings(Settings.EMPTY, settingsSet);
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
when(clusterService.state()).thenReturn(state);
@ -94,23 +98,23 @@ public class ExportersTests extends ESTestCase {
}
public void testInitExportersSingle() throws Exception {
factories.put("_type", TestExporter::new);
factories.put("local", TestExporter::new);
Map<String, Exporter> internalExporters = exporters.initExporters(Settings.builder()
.put("_name.type", "_type")
.put("xpack.monitoring.exporters._name.type", "local")
.build());
assertThat(internalExporters, notNullValue());
assertThat(internalExporters.size(), is(1));
assertThat(internalExporters, hasKey("_name"));
assertThat(internalExporters.get("_name"), instanceOf(TestExporter.class));
assertThat(internalExporters.get("_name").config().type(), is("_type"));
assertThat(internalExporters.get("_name").config().type(), is("local"));
}
public void testInitExportersSingleDisabled() throws Exception {
factories.put("_type", TestExporter::new);
factories.put("local", TestExporter::new);
Map<String, Exporter> internalExporters = exporters.initExporters(Settings.builder()
.put("_name.type", "_type")
.put("_name.enabled", false)
.put("xpack.monitoring.exporters._name.type", "local")
.put("xpack.monitoring.exporters._name.enabled", false)
.build());
assertThat(internalExporters, notNullValue());
@ -120,32 +124,23 @@ public class ExportersTests extends ESTestCase {
}
public void testInitExportersSingleUnknownType() throws Exception {
try {
exporters.initExporters(Settings.builder()
.put("_name.type", "unknown_type")
.build());
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), containsString("unknown exporter type [unknown_type]"));
}
SettingsException e = expectThrows(SettingsException.class, () -> exporters.initExporters(Settings.builder()
.put("xpack.monitoring.exporters._name.type", "unknown_type")
.build()));
assertThat(e.getMessage(), containsString("unknown exporter type [unknown_type]"));
}
public void testInitExportersSingleMissingExporterType() throws Exception {
try {
exporters.initExporters(Settings.builder()
.put("_name.foo", "bar")
.build());
fail("Expected SettingsException");
} catch (SettingsException e) {
assertThat(e.getMessage(), containsString("missing exporter type for [_name]"));
}
SettingsException e = expectThrows(SettingsException.class, () -> exporters.initExporters(
Settings.builder().put("xpack.monitoring.exporters._name.foo", "bar").build()));
assertThat(e.getMessage(), containsString("missing exporter type for [_name]"));
}
public void testInitExportersMultipleSameType() throws Exception {
factories.put("_type", TestExporter::new);
Map<String, Exporter> internalExporters = exporters.initExporters(Settings.builder()
.put("_name0.type", "_type")
.put("_name1.type", "_type")
.put("xpack.monitoring.exporters._name0.type", "_type")
.put("xpack.monitoring.exporters._name1.type", "_type")
.build());
assertThat(internalExporters, notNullValue());
@ -159,26 +154,27 @@ public class ExportersTests extends ESTestCase {
}
public void testInitExportersMultipleSameTypeSingletons() throws Exception {
factories.put("_type", TestSingletonExporter::new);
factories.put("local", TestSingletonExporter::new);
SettingsException e = expectThrows(SettingsException.class, () ->
exporters.initExporters(Settings.builder()
.put("_name0.type", "_type")
.put("_name1.type", "_type")
.put("xpack.monitoring.exporters._name0.type", "local")
.put("xpack.monitoring.exporters._name1.type", "local")
.build())
);
assertThat(e.getMessage(), containsString("multiple [_type] exporters are configured. there can only be one"));
assertThat(e.getMessage(), containsString("multiple [local] exporters are configured. there can only be one"));
}
public void testSettingsUpdate() throws Exception {
factories.put("_type", TestExporter::new);
factories.put("http", TestExporter::new);
factories.put("local", TestExporter::new);
final AtomicReference<Settings> settingsHolder = new AtomicReference<>();
Settings nodeSettings = Settings.builder()
.put("xpack.monitoring.exporters._name0.type", "_type")
.put("xpack.monitoring.exporters._name1.type", "_type")
.put("xpack.monitoring.exporters._name0.type", "local")
.put("xpack.monitoring.exporters._name1.type", "http")
.build();
clusterSettings = new ClusterSettings(nodeSettings, singleton(Exporters.EXPORTERS_SETTINGS));
clusterSettings = new ClusterSettings(nodeSettings, new HashSet<>(Exporters.getSettings()));
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
exporters = new Exporters(nodeSettings, factories, clusterService, licenseState, threadContext) {
@ -193,21 +189,22 @@ public class ExportersTests extends ESTestCase {
assertThat(settingsHolder.get(), notNullValue());
Settings settings = settingsHolder.get();
assertThat(settings.size(), is(2));
assertEquals(settings.get("_name0.type"), "_type");
assertEquals(settings.get("_name1.type"), "_type");
assertEquals(settings.get("xpack.monitoring.exporters._name0.type"), "local");
assertEquals(settings.get("xpack.monitoring.exporters._name1.type"), "http");
Settings update = Settings.builder()
.put("xpack.monitoring.exporters._name0.foo", "bar")
.put("xpack.monitoring.exporters._name1.foo", "bar")
.put("xpack.monitoring.exporters._name0.use_ingest", true)
.put("xpack.monitoring.exporters._name1.use_ingest", false)
.build();
clusterSettings.applySettings(update);
assertThat(settingsHolder.get(), notNullValue());
settings = settingsHolder.get();
logger.info(settings);
assertThat(settings.size(), is(4));
assertEquals(settings.get("_name0.type"), "_type");
assertEquals(settings.get("_name0.foo"), "bar");
assertEquals(settings.get("_name1.type"), "_type");
assertEquals(settings.get("_name1.foo"), "bar");
assertEquals(settings.get("xpack.monitoring.exporters._name0.type"), "local");
assertEquals(settings.get("xpack.monitoring.exporters._name0.use_ingest"), "true");
assertEquals(settings.get("xpack.monitoring.exporters._name1.type"), "http");
assertEquals(settings.get("xpack.monitoring.exporters._name1.use_ingest"), "false");
}
public void testExporterBlocksOnClusterState() {

View File

@ -115,6 +115,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
.put(super.nodeSettings(nodeOrdinal))
.put(MonitoringService.INTERVAL.getKey(), "-1")
.put("xpack.monitoring.exporters._http.type", "http")
.put("xpack.monitoring.exporters._http.ssl.truststore.password", "foobar")
.put("xpack.monitoring.exporters._http.enabled", false)
.build();
}
@ -554,9 +555,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private HttpExporter createHttpExporter(final Settings settings) throws Exception {
final Exporter.Config config =
new Exporter.Config("_http", "http",
settings, settings.getAsSettings("xpack.monitoring.exporters._http"),
clusterService(), new XPackLicenseState());
new Exporter.Config("_http", "http", settings, clusterService(), new XPackLicenseState());
return new HttpExporter(config, new SSLService(settings, environment), new ThreadContext(settings));
}
@ -627,7 +626,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
}
private String resourceVersionQueryString() {
return "filter_path=" + FILTER_PATH_RESOURCE_VERSION;
return "master_timeout=10s&filter_path=" + FILTER_PATH_RESOURCE_VERSION;
}
private String watcherCheckQueryString() {
@ -637,7 +636,7 @@ public class HttpExporterIT extends MonitoringIntegTestCase {
private String bulkQueryString() {
final String pipelineName = MonitoringTemplateUtils.pipelineName(TEMPLATE_VERSION);
return "pipeline=" + pipelineName + "&filter_path=" + "errors,items.*.error";
return "master_timeout=10s&pipeline=" + pipelineName + "&filter_path=" + "errors,items.*.error";
}
private void enqueueGetClusterVersionResponse(Version v) throws IOException {

View File

@ -34,7 +34,6 @@ import java.util.stream.Collectors;
import static org.elasticsearch.xpack.core.monitoring.exporter.MonitoringTemplateUtils.OLD_TEMPLATE_IDS;
import static org.elasticsearch.xpack.core.monitoring.exporter.MonitoringTemplateUtils.PIPELINE_IDS;
import static org.elasticsearch.xpack.core.monitoring.exporter.MonitoringTemplateUtils.TEMPLATE_IDS;
import static org.elasticsearch.xpack.monitoring.exporter.http.HttpExporter.TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING;
import static org.elasticsearch.xpack.monitoring.exporter.http.PublishableHttpResource.CheckResponse.DOES_NOT_EXIST;
import static org.elasticsearch.xpack.monitoring.exporter.http.PublishableHttpResource.CheckResponse.EXISTS;
import static org.hamcrest.Matchers.hasSize;
@ -73,11 +72,13 @@ public class HttpExporterResourceTests extends AbstractPublishableHttpResourceTe
private final List<String> pipelineNames = new ArrayList<>(EXPECTED_PIPELINES);
private final List<String> watchNames = new ArrayList<>(EXPECTED_WATCHES);
private final Settings exporterSettings = Settings.builder().put(TEMPLATE_CREATE_LEGACY_VERSIONS_SETTING, createOldTemplates).build();
private final Settings exporterSettings = Settings.builder()
.put("xpack.monitoring.exporters._http.index.template.create_legacy_templates", createOldTemplates)
.build();
private final MultiHttpResource resources =
HttpExporter.createResources(
new Exporter.Config("_http", "http", Settings.EMPTY, exporterSettings, clusterService, licenseState));
new Exporter.Config("_http", "http", exporterSettings, clusterService, licenseState));
@Before
public void setupResources() {
@ -557,7 +558,7 @@ public class HttpExporterResourceTests extends AbstractPublishableHttpResourceTe
final MultiHttpResource resources =
HttpExporter.createResources(
new Exporter.Config("_http", "http", Settings.EMPTY, exporterSettings, clusterService, licenseState));
new Exporter.Config("_http", "http", exporterSettings, clusterService, licenseState));
final int successfulGetTemplates = randomIntBetween(0, EXPECTED_TEMPLATES);
final int unsuccessfulGetTemplates = EXPECTED_TEMPLATES - successfulGetTemplates;

View File

@ -81,7 +81,7 @@ public class HttpExporterTests extends ESTestCase {
public void testExporterWithBlacklistedHeaders() {
final String blacklistedHeader = randomFrom(HttpExporter.BLACKLISTED_HEADERS);
final String expected = "[" + blacklistedHeader + "] cannot be overwritten via [xpack.monitoring.exporters._http.headers]";
final String expected = "header cannot be overwritten via [xpack.monitoring.exporters._http.headers." + blacklistedHeader + "]";
final Settings.Builder builder = Settings.builder()
.put("xpack.monitoring.exporters._http.type", HttpExporter.TYPE)
.put("xpack.monitoring.exporters._http.host", "http://localhost:9200")
@ -417,6 +417,8 @@ public class HttpExporterTests extends ESTestCase {
if (bulkTimeout != null) {
assertThat(parameters.remove("master_timeout"), equalTo(bulkTimeout.toString()));
} else {
assertThat(parameters.remove("master_timeout"), equalTo("10s"));
}
if (useIngest) {
@ -504,7 +506,7 @@ public class HttpExporterTests extends ESTestCase {
* @return Never {@code null}.
*/
private Config createConfig(final Settings settings) {
return new Config("_http", HttpExporter.TYPE, settings, settings.getAsSettings(exporterName()), clusterService, licenseState);
return new Config("_http", HttpExporter.TYPE, settings, clusterService, licenseState);
}
private static String exporterName() {

View File

@ -18,8 +18,6 @@ import org.elasticsearch.xpack.monitoring.test.MonitoringIntegTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import static org.elasticsearch.xpack.monitoring.exporter.Exporter.CLUSTER_ALERTS_MANAGEMENT_SETTING;
/**
* {@code LocalExporterIntegTestCase} offers a basis for integration tests for the {@link LocalExporter}.
*/
@ -50,7 +48,7 @@ public abstract class LocalExporterIntegTestCase extends MonitoringIntegTestCase
.put(MonitoringService.INTERVAL.getKey(), "-1")
.put("xpack.monitoring.exporters." + exporterName + ".type", LocalExporter.TYPE)
.put("xpack.monitoring.exporters." + exporterName + ".enabled", false)
.put("xpack.monitoring.exporters." + exporterName + "." + CLUSTER_ALERTS_MANAGEMENT_SETTING, false)
.put("xpack.monitoring.exporters." + exporterName + ".cluster_alerts.management.enabled", false)
.put(XPackSettings.MACHINE_LEARNING_ENABLED.getKey(), false)
.put(NetworkModule.HTTP_ENABLED.getKey(), false)
.build();
@ -78,10 +76,7 @@ public abstract class LocalExporterIntegTestCase extends MonitoringIntegTestCase
protected LocalExporter createLocalExporter() {
final Settings settings = localExporterSettings();
final XPackLicenseState licenseState = new XPackLicenseState();
final Exporter.Config config =
new Exporter.Config(exporterName, "local",
settings, settings.getAsSettings("xpack.monitoring.exporters." + exporterName),
clusterService(), licenseState);
final Exporter.Config config = new Exporter.Config(exporterName, "local", settings, clusterService(), licenseState);
final CleanerService cleanerService =
new CleanerService(settings, clusterService().getClusterSettings(), THREADPOOL, licenseState);

View File

@ -71,6 +71,7 @@ public class LocalExporterIntegTests extends LocalExporterIntegTestCase {
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(
Settings.builder().putNull(MonitoringService.INTERVAL.getKey())
.putNull("xpack.monitoring.exporters._local.enabled")
.putNull("xpack.monitoring.exporters._local.cluster_alerts.management.enabled")
.putNull("xpack.monitoring.exporters._local.index.name.time_format")));
}
@ -87,7 +88,8 @@ public class LocalExporterIntegTests extends LocalExporterIntegTestCase {
}
Settings.Builder exporterSettings = Settings.builder()
.put("xpack.monitoring.exporters._local.enabled", true);
.put("xpack.monitoring.exporters._local.enabled", true)
.put("xpack.monitoring.exporters._local.cluster_alerts.management.enabled", false);
if (indexTimeFormat != null) {
exporterSettings.put("xpack.monitoring.exporters._local.index.name.time_format", indexTimeFormat);

View File

@ -11,12 +11,15 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.ingest.PipelineConfiguration;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.xpack.core.monitoring.MonitoredSystem;
import org.elasticsearch.xpack.core.monitoring.exporter.MonitoringTemplateUtils;
import org.elasticsearch.xpack.monitoring.exporter.ClusterAlertsUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST;

View File

@ -131,7 +131,6 @@ import org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAt
import org.elasticsearch.xpack.watcher.notification.email.support.BodyPartSource;
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
import org.elasticsearch.xpack.watcher.notification.jira.JiraService;
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyAccount;
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyService;
import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
import org.elasticsearch.xpack.watcher.rest.action.RestAckWatchAction;
@ -421,11 +420,11 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin {
settings.add(Setting.simpleString("xpack.watcher.start_immediately", Setting.Property.NodeScope));
// notification services
settings.add(SlackService.SLACK_ACCOUNT_SETTING);
settings.add(EmailService.EMAIL_ACCOUNT_SETTING);
settings.add(HipChatService.HIPCHAT_ACCOUNT_SETTING);
settings.add(JiraService.JIRA_ACCOUNT_SETTING);
settings.add(PagerDutyService.PAGERDUTY_ACCOUNT_SETTING);
settings.addAll(SlackService.getSettings());
settings.addAll(EmailService.getSettings());
settings.addAll(HipChatService.getSettings());
settings.addAll(JiraService.getSettings());
settings.addAll(PagerDutyService.getSettings());
settings.add(ReportingAttachmentParser.RETRIES_SETTING);
settings.add(ReportingAttachmentParser.INTERVAL_SETTING);
@ -595,19 +594,6 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin {
return Collections.singletonList(new EncryptSensitiveDataBootstrapCheck(env));
}
@Override
public List<String> getSettingsFilter() {
List<String> filters = new ArrayList<>();
filters.add("xpack.notification.email.account.*.smtp.password");
filters.add("xpack.notification.jira.account.*.password");
filters.add("xpack.notification.slack.account.*.url");
filters.add("xpack.notification.pagerduty.account.*.url");
filters.add("xpack.notification.pagerduty." + PagerDutyAccount.SERVICE_KEY_SETTING);
filters.add("xpack.notification.pagerduty.account.*." + PagerDutyAccount.SERVICE_KEY_SETTING);
filters.add("xpack.notification.hipchat.account.*.auth_token");
return filters;
}
@Override
public List<ScriptContext> getContexts() {
return Arrays.asList(Watcher.SCRIPT_SEARCH_CONTEXT, Watcher.SCRIPT_EXECUTABLE_CONTEXT, Watcher.SCRIPT_TEMPLATE_CONTEXT);

View File

@ -23,7 +23,7 @@ public abstract class NotificationService<Account> extends AbstractComponent {
private final String type;
// both are guarded by this
private Map<String, Account> accounts;
protected Account defaultAccount;
private Account defaultAccount;
public NotificationService(Settings settings, String type) {
super(settings);
@ -59,7 +59,7 @@ public abstract class NotificationService<Account> extends AbstractComponent {
}
private <A> Tuple<Map<String, A>, A> buildAccounts(Settings settings, BiFunction<String, Settings, A> accountFactory) {
Settings accountsSettings = settings.getAsSettings("account");
Settings accountsSettings = settings.getByPrefix("xpack.notification." + type + ".").getAsSettings("account");
Map<String, A> accounts = new HashMap<>();
for (String name : accountsSettings.names()) {
Settings accountSettings = accountsSettings.getAsSettings(name);
@ -67,7 +67,7 @@ public abstract class NotificationService<Account> extends AbstractComponent {
accounts.put(name, account);
}
final String defaultAccountName = settings.get("default_account");
final String defaultAccountName = settings.get("xpack.notification." + type + ".default_account");
A defaultAccount;
if (defaultAccountName == null) {
if (accounts.isEmpty()) {

View File

@ -8,26 +8,73 @@ package org.elasticsearch.xpack.watcher.notification.email;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.core.watcher.crypto.CryptoService;
import org.elasticsearch.xpack.watcher.notification.NotificationService;
import javax.mail.MessagingException;
import java.util.Arrays;
import java.util.List;
/**
* A component to store email credentials and handle sending email notifications.
*/
public class EmailService extends NotificationService<Account> {
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.email.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_PROFILE =
Setting.affixKeySetting("xpack.notification.email.account.", "profile",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<Settings> SETTING_EMAIL_DEFAULTS =
Setting.affixKeySetting("xpack.notification.email.account.", "email_defaults",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<Boolean> SETTING_SMTP_AUTH =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.auth",
(key) -> Setting.boolSetting(key, false, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<Boolean> SETTING_SMTP_STARTTLS_ENABLE =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.starttls.enable",
(key) -> Setting.boolSetting(key, false, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_SMTP_HOST =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.host",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<Integer> SETTING_SMTP_PORT =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.port",
(key) -> Setting.intSetting(key, 587, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_SMTP_USER =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.user",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_SMTP_PASSWORD =
Setting.affixKeySetting("xpack.notification.email.account.", "smtp.password",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private final CryptoService cryptoService;
public static final Setting<Settings> EMAIL_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.email.", Setting.Property.Dynamic, Setting.Property.NodeScope);
public EmailService(Settings settings, @Nullable CryptoService cryptoService, ClusterSettings clusterSettings) {
super(settings, "email");
this.cryptoService = cryptoService;
clusterSettings.addSettingsUpdateConsumer(EMAIL_ACCOUNT_SETTING, this::setAccountSetting);
setAccountSetting(EMAIL_ACCOUNT_SETTING.get(settings));
clusterSettings.addSettingsUpdateConsumer(this::setAccountSetting, getSettings());
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PROFILE, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_EMAIL_DEFAULTS, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_AUTH, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_STARTTLS_ENABLE, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_HOST, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_PORT, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_USER, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SMTP_PASSWORD, (s, o) -> {}, (s, o) -> {});
// do an initial load
setAccountSetting(settings);
}
@Override
@ -75,4 +122,9 @@ public class EmailService extends NotificationService<Account> {
}
}
public static List<Setting<?>> getSettings() {
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_PROFILE, SETTING_EMAIL_DEFAULTS, SETTING_SMTP_AUTH, SETTING_SMTP_HOST,
SETTING_SMTP_PASSWORD, SETTING_SMTP_PORT, SETTING_SMTP_STARTTLS_ENABLE, SETTING_SMTP_USER);
}
}

View File

@ -12,26 +12,72 @@ import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
import org.elasticsearch.xpack.watcher.notification.NotificationService;
import java.util.Arrays;
import java.util.List;
/**
* A component to store hipchat credentials.
*/
public class HipChatService extends NotificationService<HipChatAccount> {
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.hipchat.default_account", Setting.Property.Dynamic, Setting.Property.NodeScope);
static final Setting<String> SETTING_DEFAULT_HOST =
Setting.simpleString("xpack.notification.hipchat.host", Setting.Property.Dynamic, Setting.Property.NodeScope);
static final Setting<Integer> SETTING_DEFAULT_PORT =
Setting.intSetting("xpack.notification.hipchat.port", 443, Setting.Property.Dynamic, Setting.Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_AUTH_TOKEN =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "auth_token",
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope, Setting.Property.Filtered));
private static final Setting.AffixSetting<String> SETTING_PROFILE =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "profile",
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_ROOM =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "room",
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_HOST =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "host",
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
private static final Setting.AffixSetting<Integer> SETTING_PORT =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "port",
(key) -> Setting.intSetting(key, 443, Setting.Property.Dynamic, Setting.Property.NodeScope));
private static final Setting.AffixSetting<Settings> SETTING_MESSAGE_DEFAULTS =
Setting.affixKeySetting("xpack.notification.hipchat.account.", "message",
(key) -> Setting.groupSetting(key + ".", Setting.Property.Dynamic, Setting.Property.NodeScope));
private final HttpClient httpClient;
public static final Setting<Settings> HIPCHAT_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.hipchat.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private HipChatServer defaultServer;
public HipChatService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings) {
super(settings, "hipchat");
this.httpClient = httpClient;
clusterSettings.addSettingsUpdateConsumer(HIPCHAT_ACCOUNT_SETTING, this::setAccountSetting);
setAccountSetting(HIPCHAT_ACCOUNT_SETTING.get(settings));
clusterSettings.addSettingsUpdateConsumer(this::setAccountSetting, getSettings());
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_HOST, (s) -> {});
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_PORT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_AUTH_TOKEN, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PROFILE, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_ROOM, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_HOST, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PORT, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_MESSAGE_DEFAULTS, (s, o) -> {}, (s, o) -> {});
setAccountSetting(settings);
}
@Override
protected synchronized void setAccountSetting(Settings settings) {
defaultServer = new HipChatServer(settings);
defaultServer = new HipChatServer(settings.getByPrefix("xpack.notification.hipchat."));
super.setAccountSetting(settings);
}
@ -43,4 +89,9 @@ public class HipChatService extends NotificationService<HipChatAccount> {
}
return profile.createAccount(name, accountSettings, defaultServer, httpClient, logger);
}
public static List<Setting<?>> getSettings() {
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_AUTH_TOKEN, SETTING_PROFILE, SETTING_ROOM, SETTING_MESSAGE_DEFAULTS,
SETTING_DEFAULT_HOST, SETTING_DEFAULT_PORT, SETTING_HOST, SETTING_PORT);
}
}

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.watcher.notification.jira;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;

View File

@ -7,10 +7,14 @@ package org.elasticsearch.xpack.watcher.notification.jira;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
import org.elasticsearch.xpack.watcher.notification.NotificationService;
import java.util.Arrays;
import java.util.List;
/**
* A component to store Atlassian's JIRA credentials.
*
@ -18,20 +22,52 @@ import org.elasticsearch.xpack.watcher.notification.NotificationService;
*/
public class JiraService extends NotificationService<JiraAccount> {
public static final Setting<Settings> JIRA_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.jira.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.jira.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<Boolean> SETTING_ALLOW_HTTP =
Setting.affixKeySetting("xpack.notification.jira.account.", "allow_http",
(key) -> Setting.boolSetting(key, false, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_URL =
Setting.affixKeySetting("xpack.notification.jira.account.", "url",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope));
private static final Setting.AffixSetting<String> SETTING_USER =
Setting.affixKeySetting("xpack.notification.jira.account.", "user",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<String> SETTING_PASSWORD =
Setting.affixKeySetting("xpack.notification.jira.account.", "password",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<Settings> SETTING_DEFAULTS =
Setting.affixKeySetting("xpack.notification.jira.account.", "issue_defaults",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope));
private final HttpClient httpClient;
public JiraService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings) {
super(settings, "jira");
this.httpClient = httpClient;
clusterSettings.addSettingsUpdateConsumer(JIRA_ACCOUNT_SETTING, this::setAccountSetting);
setAccountSetting(JIRA_ACCOUNT_SETTING.get(settings));
clusterSettings.addSettingsUpdateConsumer(this::setAccountSetting, getSettings());
// ensure logging of setting changes
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_ALLOW_HTTP, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_URL, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_USER, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_PASSWORD, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
// do an initial load
setAccountSetting(settings);
}
@Override
protected JiraAccount createAccount(String name, Settings accountSettings) {
return new JiraAccount(name, accountSettings, httpClient);
protected JiraAccount createAccount(String name, Settings settings) {
return new JiraAccount(name, settings, httpClient);
}
public static List<Setting<?>> getSettings() {
return Arrays.asList(SETTING_ALLOW_HTTP, SETTING_URL, SETTING_USER, SETTING_PASSWORD, SETTING_DEFAULTS, SETTING_DEFAULT_ACCOUNT);
}
}

View File

@ -7,29 +7,47 @@ package org.elasticsearch.xpack.watcher.notification.pagerduty;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
import org.elasticsearch.xpack.watcher.notification.NotificationService;
import java.util.Arrays;
import java.util.List;
/**
* A component to store pagerduty credentials.
*/
public class PagerDutyService extends NotificationService<PagerDutyAccount> {
public static final Setting<Settings> PAGERDUTY_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.pagerduty.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.pagerduty.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_SERVICE_API_KEY =
Setting.affixKeySetting("xpack.notification.pagerduty.account.", "service_api_key",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<Settings> SETTING_DEFAULTS =
Setting.affixKeySetting("xpack.notification.pagerduty.account.", "event_defaults",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope));
private final HttpClient httpClient;
public PagerDutyService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings) {
super(settings, "pagerduty");
this.httpClient = httpClient;
clusterSettings.addSettingsUpdateConsumer(PAGERDUTY_ACCOUNT_SETTING, this::setAccountSetting);
setAccountSetting(PAGERDUTY_ACCOUNT_SETTING.get(settings));
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_SERVICE_API_KEY, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
setAccountSetting(settings);
}
@Override
protected PagerDutyAccount createAccount(String name, Settings accountSettings) {
return new PagerDutyAccount(name, accountSettings, accountSettings, httpClient, logger);
}
public static List<Setting<?>> getSettings() {
return Arrays.asList(SETTING_SERVICE_API_KEY, SETTING_DEFAULTS, SETTING_DEFAULT_ACCOUNT);
}
}

View File

@ -7,29 +7,48 @@ package org.elasticsearch.xpack.watcher.notification.slack;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
import org.elasticsearch.xpack.watcher.notification.NotificationService;
import java.util.Arrays;
import java.util.List;
/**
* A component to store slack credentials.
*/
public class SlackService extends NotificationService<SlackAccount> {
public static final Setting<Settings> SLACK_ACCOUNT_SETTING =
Setting.groupSetting("xpack.notification.slack.", Setting.Property.Dynamic, Setting.Property.NodeScope);
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
Setting.simpleString("xpack.notification.slack.default_account", Property.Dynamic, Property.NodeScope);
private static final Setting.AffixSetting<String> SETTING_URL =
Setting.affixKeySetting("xpack.notification.slack.account.", "url",
(key) -> Setting.simpleString(key, Property.Dynamic, Property.NodeScope, Property.Filtered));
private static final Setting.AffixSetting<Settings> SETTING_DEFAULTS =
Setting.affixKeySetting("xpack.notification.slack.account.", "message_defaults",
(key) -> Setting.groupSetting(key + ".", Property.Dynamic, Property.NodeScope));
private final HttpClient httpClient;
public SlackService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings) {
super(settings, "slack");
this.httpClient = httpClient;
clusterSettings.addSettingsUpdateConsumer(SLACK_ACCOUNT_SETTING, this::setAccountSetting);
setAccountSetting(SLACK_ACCOUNT_SETTING.get(settings));
clusterSettings.addSettingsUpdateConsumer(this::setAccountSetting, getSettings());
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_URL, (s, o) -> {}, (s, o) -> {});
clusterSettings.addAffixUpdateConsumer(SETTING_DEFAULTS, (s, o) -> {}, (s, o) -> {});
setAccountSetting(settings);
}
@Override
protected SlackAccount createAccount(String name, Settings accountSettings) {
return new SlackAccount(name, accountSettings, accountSettings, httpClient, logger);
}
public static List<Setting<?>> getSettings() {
return Arrays.asList(SETTING_URL, SETTING_DEFAULT_ACCOUNT, SETTING_DEFAULTS);
}
}

View File

@ -15,9 +15,9 @@ import static org.hamcrest.Matchers.is;
public class NotificationServiceTests extends ESTestCase {
public void testSingleAccount() throws Exception {
public void testSingleAccount() {
String accountName = randomAlphaOfLength(10);
Settings settings = Settings.builder().put("account." + accountName, "bar").build();
Settings settings = Settings.builder().put("xpack.notification.test.account." + accountName, "bar").build();
TestNotificationService service = new TestNotificationService(settings);
assertThat(service.getAccount(accountName), is(accountName));
@ -25,12 +25,12 @@ public class NotificationServiceTests extends ESTestCase {
assertThat(service.getAccount("non-existing"), is(accountName));
}
public void testMultipleAccountsWithExistingDefault() throws Exception {
public void testMultipleAccountsWithExistingDefault() {
String accountName = randomAlphaOfLength(10);
Settings settings = Settings.builder()
.put("account." + accountName, "bar")
.put("account.second", "bar")
.put("default_account", accountName)
.put("xpack.notification.test.account." + accountName, "bar")
.put("xpack.notification.test.account.second", "bar")
.put("xpack.notification.test.default_account", accountName)
.build();
TestNotificationService service = new TestNotificationService(settings);
@ -39,33 +39,33 @@ public class NotificationServiceTests extends ESTestCase {
assertThat(service.getAccount("non-existing"), is(accountName));
}
public void testMultipleAccountsWithNoDefault() throws Exception {
public void testMultipleAccountsWithNoDefault() {
String accountName = randomAlphaOfLength(10);
Settings settings = Settings.builder()
.put("account." + accountName, "bar")
.put("account.second", "bar")
.put("account.third", "bar")
.put("xpack.notification.test.account." + accountName, "bar")
.put("xpack.notification.test.account.second", "bar")
.put("xpack.notification.test.account.third", "bar")
.build();
TestNotificationService service = new TestNotificationService(settings);
assertThat(service.getAccount(null), anyOf(is(accountName), is("second"), is("third")));
}
public void testMultipleAccountsUnknownDefault() throws Exception {
public void testMultipleAccountsUnknownDefault() {
String accountName = randomAlphaOfLength(10);
Settings settings = Settings.builder()
.put("account." + accountName, "bar")
.put("account.second", "bar")
.put("default_account", "non-existing")
.put("xpack.notification.test.account." + accountName, "bar")
.put("xpack.notification.test.account.second", "bar")
.put("xpack.notification.test.default_account", "non-existing")
.build();
SettingsException e = expectThrows(SettingsException.class, () -> new TestNotificationService(settings));
assertThat(e.getMessage(), is("could not find default account [non-existing]"));
}
public void testNoSpecifiedDefaultAccount() throws Exception {
public void testNoSpecifiedDefaultAccount() {
String accountName = randomAlphaOfLength(10);
Settings settings = Settings.builder().put("account." + accountName, "bar").build();
Settings settings = Settings.builder().put("xpack.notification.test.account." + accountName, "bar").build();
TestNotificationService service = new TestNotificationService(settings);
assertThat(service.getAccount(null), is(accountName));

View File

@ -16,6 +16,7 @@ import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
import org.junit.Before;
import java.util.Collections;
import java.util.HashSet;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.hipchatAction;
@ -52,7 +53,7 @@ public class HipChatActionFactoryTests extends ESTestCase {
public void testParseActionUnknownAccount() throws Exception {
hipchatService = new HipChatService(Settings.EMPTY, null, new ClusterSettings(Settings.EMPTY,
Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new HashSet<>(HipChatService.getSettings())));
factory = new HipChatActionFactory(Settings.EMPTY, mock(TextTemplateEngine.class), hipchatService);
HipChatAction action = hipchatAction("_unknown", "_body").build();
XContentBuilder jsonBuilder = jsonBuilder().value(action);

View File

@ -16,6 +16,7 @@ import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyService;
import org.junit.Before;
import java.util.Collections;
import java.util.HashSet;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.triggerPagerDutyAction;
@ -50,7 +51,7 @@ public class PagerDutyActionFactoryTests extends ESTestCase {
public void testParseActionUnknownAccount() throws Exception {
factory = new PagerDutyActionFactory(Settings.EMPTY, mock(TextTemplateEngine.class), new PagerDutyService(Settings.EMPTY, null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(PagerDutyService.PAGERDUTY_ACCOUNT_SETTING))));
new ClusterSettings(Settings.EMPTY, new HashSet<>(PagerDutyService.getSettings()))));
PagerDutyAction action = triggerPagerDutyAction("_unknown", "_body").build();
XContentBuilder jsonBuilder = jsonBuilder().value(action);
XContentParser parser = createParser(jsonBuilder);

View File

@ -16,6 +16,7 @@ import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
import org.junit.Before;
import java.util.Collections;
import java.util.HashSet;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessageTests.createRandomTemplate;
@ -49,7 +50,7 @@ public class SlackActionFactoryTests extends ESTestCase {
public void testParseActionUnknownAccount() throws Exception {
SlackService service = new SlackService(Settings.EMPTY, null, new ClusterSettings(Settings.EMPTY,
Collections.singleton(SlackService.SLACK_ACCOUNT_SETTING)));
new HashSet<>(SlackService.getSettings())));
factory = new SlackActionFactory(Settings.EMPTY, mock(TextTemplateEngine.class), service);
SlackAction action = slackAction("_unknown", createRandomTemplate()).build();
XContentBuilder jsonBuilder = jsonBuilder().value(action);

View File

@ -11,6 +11,7 @@ import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.test.ESTestCase;
import java.util.Collections;
import java.util.HashSet;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@ -23,7 +24,7 @@ public class AccountsTests extends ESTestCase {
.put("default_account", "account1");
addAccountSettings("account1", builder);
EmailService service = new EmailService(builder.build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
Account account = service.getAccount("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -36,7 +37,7 @@ public class AccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder();
addAccountSettings("account1", builder);
EmailService service = new EmailService(builder.build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
Account account = service.getAccount("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -52,7 +53,7 @@ public class AccountsTests extends ESTestCase {
addAccountSettings("account2", builder);
EmailService service = new EmailService(builder.build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
Account account = service.getAccount("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -71,7 +72,7 @@ public class AccountsTests extends ESTestCase {
addAccountSettings("account2", builder);
EmailService service = new EmailService(builder.build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
Account account = service.getAccount("account1");
assertThat(account, notNullValue());
assertThat(account.name(), equalTo("account1"));
@ -87,7 +88,7 @@ public class AccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder().put("xpack.notification.email.default_account", "unknown");
addAccountSettings("account1", builder);
addAccountSettings("account2", builder);
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING));
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings()));
SettingsException e = expectThrows(SettingsException.class, () -> new EmailService(builder.build(), null, clusterSettings));
assertThat(e.getMessage(), is("could not find default account [unknown]"));
}
@ -95,13 +96,13 @@ public class AccountsTests extends ESTestCase {
public void testNoAccount() throws Exception {
Settings.Builder builder = Settings.builder();
EmailService service = new EmailService(builder.build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
expectThrows(IllegalArgumentException.class, () -> service.getAccount(null));
}
public void testNoAccountWithDefaultAccount() throws Exception {
Settings settings = Settings.builder().put("xpack.notification.email.default_account", "unknown").build();
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING));
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings()));
SettingsException e = expectThrows(SettingsException.class, () -> new EmailService(settings, null, clusterSettings));
assertThat(e.getMessage(), is("could not find default account [unknown]"));
}

View File

@ -12,6 +12,7 @@ import org.elasticsearch.xpack.core.watcher.common.secret.Secret;
import org.junit.Before;
import java.util.Collections;
import java.util.HashSet;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -28,7 +29,7 @@ public class EmailServiceTests extends ESTestCase {
public void init() throws Exception {
account = mock(Account.class);
service = new EmailService(Settings.builder().put("xpack.notification.email.account.account1.foo", "bar").build(), null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING))) {
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings()))) {
@Override
protected Account createAccount(String name, Settings accountSettings) {
return account;

View File

@ -16,6 +16,7 @@ import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Collections;
import java.util.HashSet;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
@ -41,7 +42,7 @@ public class ProfileTests extends ESTestCase {
.build();
EmailService service = new EmailService(settings, null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
Session session = service.getAccount("foo").getConfig().createSession();
MimeMessage mimeMessage = Profile.STANDARD.toMimeMessage(email, session);

View File

@ -19,6 +19,7 @@ import org.mockito.ArgumentCaptor;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
@ -37,7 +38,7 @@ public class HipChatAccountsTests extends ESTestCase {
.put("xpack.notification.hipchat.default_account", "account1");
addAccountSettings("account1", builder);
HipChatService service = new HipChatService(builder.build(), httpClient, new ClusterSettings(Settings.EMPTY,
Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new HashSet<>(HipChatService.getSettings())));
HipChatAccount account = service.getAccount("account1");
HipChatMessage.Template template = new HipChatMessage.Template.Builder(new TextTemplate("foo"))

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.xpack.watcher.notification.hipchat;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
@ -13,6 +14,7 @@ import org.elasticsearch.xpack.watcher.common.http.HttpClient;
import org.junit.Before;
import java.util.Collections;
import java.util.HashSet;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;
@ -51,7 +53,7 @@ public class HipChatServiceTests extends ESTestCase {
}
buildMessageDefaults(accountName, settingsBuilder, defaultRoom, null, defaultFrom, defaultColor, defaultFormat, defaultNotify);
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
HipChatAccount account = service.getAccount(accountName);
assertThat(account, notNullValue());
@ -99,7 +101,7 @@ public class HipChatServiceTests extends ESTestCase {
}
buildMessageDefaults(accountName, settingsBuilder, null, null, defaultFrom, defaultColor, defaultFormat, defaultNotify);
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
HipChatAccount account = service.getAccount(accountName);
assertThat(account, notNullValue());
@ -128,7 +130,7 @@ public class HipChatServiceTests extends ESTestCase {
.put("xpack.notification.hipchat.account." + accountName + ".auth_token", "_token");
SettingsException e = expectThrows(SettingsException.class, () ->
new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING))));
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings()))));
assertThat(e.getMessage(), containsString("missing required [room] setting for [integration] account profile"));
}
@ -152,7 +154,7 @@ public class HipChatServiceTests extends ESTestCase {
}
buildMessageDefaults(accountName, settingsBuilder, defaultRoom, defaultUser, null, defaultColor, defaultFormat, defaultNotify);
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
HipChatAccount account = service.getAccount(accountName);
assertThat(account, notNullValue());
@ -213,7 +215,7 @@ public class HipChatServiceTests extends ESTestCase {
}
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
new ClusterSettings(settingsBuilder.build(), Collections.singleton(HipChatService.HIPCHAT_ACCOUNT_SETTING)));
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
for (int i = 0; i < 5; i++) {
String name = "_a" + i;

View File

@ -36,12 +36,12 @@ public class IntegrationAccountTests extends ESTestCase {
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
host = randomAlphaOfLength(10);
sb.put(HipChatServer.HOST_SETTING, host);
sb.put("host", host);
}
int port = HipChatServer.DEFAULT.port();
if (randomBoolean()) {
port = randomIntBetween(300, 400);
sb.put(HipChatServer.PORT_SETTING, port);
sb.put("port", port);
}
String room = randomAlphaOfLength(10);

View File

@ -47,12 +47,12 @@ public class UserAccountTests extends ESTestCase {
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
host = randomAlphaOfLength(10);
sb.put(HipChatServer.HOST_SETTING, host);
sb.put("host", host);
}
int port = HipChatServer.DEFAULT.port();
if (randomBoolean()) {
port = randomIntBetween(300, 400);
sb.put(HipChatServer.PORT_SETTING, port);
sb.put("port", port);
}
String[] defaultRooms = null;

View File

@ -36,12 +36,12 @@ public class V1AccountTests extends ESTestCase {
String host = HipChatServer.DEFAULT.host();
if (randomBoolean()) {
host = randomAlphaOfLength(10);
sb.put(HipChatServer.HOST_SETTING, host);
sb.put("host", host);
}
int port = HipChatServer.DEFAULT.port();
if (randomBoolean()) {
port = randomIntBetween(300, 400);
sb.put(HipChatServer.PORT_SETTING, port);
sb.put("port", port);
}
String[] defaultRooms = null;

View File

@ -23,6 +23,7 @@ import org.mockito.ArgumentCaptor;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import static java.util.Collections.emptyMap;
@ -47,7 +48,7 @@ public class JiraAccountTests extends ESTestCase {
@Before
public void init() throws Exception {
httpClient = mock(HttpClient.class);
clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.singleton(JiraService.JIRA_ACCOUNT_SETTING));
clusterSettings = new ClusterSettings(Settings.EMPTY, new HashSet<>(JiraService.getSettings()));
}
public void testJiraAccountSettings() {

View File

@ -20,7 +20,7 @@ import org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessageDe
import org.junit.Before;
import org.mockito.ArgumentCaptor;
import java.util.Collections;
import java.util.HashSet;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -40,7 +40,7 @@ public class PagerDutyAccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder().put("xpack.notification.pagerduty.default_account", "account1");
addAccountSettings("account1", builder);
PagerDutyService service = new PagerDutyService(builder.build(), httpClient, new ClusterSettings(Settings.EMPTY,
Collections.singleton(PagerDutyService.PAGERDUTY_ACCOUNT_SETTING)));
new HashSet<>(PagerDutyService.getSettings())));
PagerDutyAccount account = service.getAccount("account1");
ArgumentCaptor<HttpRequest> argumentCaptor = ArgumentCaptor.forClass(HttpRequest.class);
@ -60,7 +60,7 @@ public class PagerDutyAccountsTests extends ESTestCase {
Settings.Builder builder = Settings.builder().put("xpack.notification.pagerduty.default_account", "account1");
addAccountSettings("account1", builder);
PagerDutyService service = new PagerDutyService(builder.build(), httpClient, new ClusterSettings(Settings.EMPTY,
Collections.singleton(PagerDutyService.PAGERDUTY_ACCOUNT_SETTING)));
new HashSet<>(PagerDutyService.getSettings())));
PagerDutyAccount account = service.getAccount("account1");
ArgumentCaptor<HttpRequest> argumentCaptor = ArgumentCaptor.forClass(HttpRequest.class);

View File

@ -520,8 +520,7 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
public static class NoopEmailService extends EmailService {
public NoopEmailService() {
super(Settings.EMPTY, null,
new ClusterSettings(Settings.EMPTY, Collections.singleton(EmailService.EMAIL_ACCOUNT_SETTING)));
super(Settings.EMPTY, null, new ClusterSettings(Settings.EMPTY, new HashSet<>(EmailService.getSettings())));
}
@Override