You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by am...@apache.org on 2017/10/17 14:59:03 UTC
[47/50] ambari git commit: AMBARI-22115. Alerts for OneFS mpack
(amagyar)
AMBARI-22115. Alerts for OneFS mpack (amagyar)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b552da9e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b552da9e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b552da9e
Branch: refs/heads/branch-feature-AMBARI-22008
Commit: b552da9e100d2c94eb74a5634ce08c16ad9656e7
Parents: 7eb5cd4
Author: Attila Magyar <am...@hortonworks.com>
Authored: Thu Oct 12 15:21:13 2017 +0200
Committer: Attila Magyar <am...@hortonworks.com>
Committed: Tue Oct 17 16:52:56 2017 +0200
----------------------------------------------------------------------
ambari-server/docs/configuration/index.md | 1 +
.../server/alerts/JmxServerSideAlert.java | 104 +++++++++++++++++++
.../apache/ambari/server/alerts/Threshold.java | 73 +++++++++++++
.../server/configuration/Configuration.java | 11 ++
.../server/controller/ControllerModule.java | 1 +
.../server/controller/jmx/JMXMetricHolder.java | 27 +++++
.../org/apache/ambari/server/state/Alert.java | 1 +
.../ambari/server/state/alert/AlertUri.java | 41 ++++++++
.../ambari/server/state/alert/MetricSource.java | 7 ++
.../ambari/server/state/alert/Reporting.java | 43 ++++++++
.../ambari/server/state/alert/ServerSource.java | 15 +++
.../services/AmbariServerAlertService.java | 7 +-
.../ambari/server/alerts/ThresholdTest.java | 90 ++++++++++++++++
.../controller/jmx/JMXMetricHolderTest.java | 61 +++++++++++
.../ambari/server/state/alert/AlertUriTest.java | 60 +++++++++++
15 files changed, 541 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/docs/configuration/index.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/configuration/index.md b/ambari-server/docs/configuration/index.md
index 9dbe9c4..8f1531b 100644
--- a/ambari-server/docs/configuration/index.md
+++ b/ambari-server/docs/configuration/index.md
@@ -57,6 +57,7 @@ The following are the properties which can be used to configure Ambari.
| alerts.execution.scheduler.threadpool.size.core | The core number of threads used to process incoming alert events. The value should be increased as the size of the cluster increases. |`2` |
| alerts.execution.scheduler.threadpool.size.max | The number of threads used to handle alerts received from the Ambari Agents. The value should be increased as the size of the cluster increases. |`2` |
| alerts.execution.scheduler.threadpool.worker.size | The number of queued alerts allowed before discarding old alerts which have not been handled. The value should be increased as the size of the cluster increases. |`2000` |
+| alerts.server.side.scheduler.threadpool.size.core | The core pool size of the executor service that runs server side alerts. |`4` |
| alerts.snmp.dispatcher.udp.port | The UDP port to use when binding the SNMP dispatcher on Ambari Server startup. If no port is specified, then a random port will be used. | |
| alerts.template.file | The full path to the XML file that describes the different alert templates. | |
| ambari.display.url | The URL to use when creating messages which should include the Ambari Server URL.<br/><br/>The following are examples of valid values:<ul><li>`http://ambari.apache.org:8080`</ul> | |
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/alerts/JmxServerSideAlert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/alerts/JmxServerSideAlert.java b/ambari-server/src/main/java/org/apache/ambari/server/alerts/JmxServerSideAlert.java
new file mode 100644
index 0000000..a4b86f8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/JmxServerSideAlert.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.alerts;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+import org.apache.ambari.server.controller.jmx.JMXMetricHolder;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.apache.ambari.server.state.alert.MetricSource;
+import org.apache.ambari.server.state.alert.Reporting;
+import org.apache.ambari.server.state.alert.ServerSource;
+import org.apache.ambari.server.state.services.MetricsRetrievalService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+/**
+ * I represent a "SERVER" {@link org.apache.ambari.server.state.alert.SourceType} alert
+ * which can pull JMX metrics from a remote cluster.
+ */
+public class JmxServerSideAlert extends AlertRunnable {
+ private final static Logger LOG = LoggerFactory.getLogger(JmxServerSideAlert.class);
+ @Inject
+ private AlertDefinitionFactory definitionFactory;
+ @Inject
+ private MetricsRetrievalService metricsRetrievalService;
+ @Inject
+ private ConfigHelper configHelper;
+
+ public JmxServerSideAlert(String definitionName) {
+ super(definitionName);
+ }
+
+ @Override
+ List<Alert> execute(Cluster cluster, AlertDefinitionEntity entity) throws AmbariException {
+ AlertDefinition alertDef = definitionFactory.coerce(entity);
+ ServerSource serverSource = (ServerSource) alertDef.getSource();
+ URI jmxUrl = jmxUrl(cluster, serverSource);
+ JMXMetricHolder metricHolder = jmxMetric(serverSource, jmxUrl);
+ return metricHolder == null
+ ? emptyList()
+ : alerts(alertDef, serverSource.getJmxInfo(), metricHolder, serverSource.getReporting());
+ }
+
+ private URI jmxUrl(Cluster cluster, ServerSource serverSource) throws AmbariException {
+ return serverSource.getUri().resolve(config(cluster)).resolve(serverSource.getJmxInfo().getUrlSuffix());
+ }
+
+ private Map<String, Map<String, String>> config(Cluster cluster) throws AmbariException {
+ return configHelper.getEffectiveConfigProperties(cluster, configHelper.getEffectiveDesiredTags(cluster, null));
+ }
+
+ private JMXMetricHolder jmxMetric(ServerSource serverSource, URI jmxUri) {
+ URLStreamProvider streamProvider = new URLStreamProvider(
+ serverSource.getUri().getConnectionTimeoutMsec(),
+ serverSource.getUri().getReadTimeoutMsec(),
+ ComponentSSLConfiguration.instance());
+ metricsRetrievalService.submitRequest(MetricsRetrievalService.MetricSourceType.JMX, streamProvider, jmxUri.toString());
+ return metricsRetrievalService.getCachedJMXMetric(jmxUri.toString());
+ }
+
+ private List<Alert> alerts(AlertDefinition alertDef, MetricSource.JmxInfo jmxInfo, JMXMetricHolder jmxMetricHolder, Reporting reporting) throws AmbariException {
+ List<Object> metrics = jmxMetricHolder.findAll(jmxInfo.getPropertyList());
+ if (metrics.isEmpty()) {
+ return emptyList();
+ }
+ if (metrics.get(0) instanceof Number) {
+ Alert alert = reporting.alert(((Number) metrics.get(0)).doubleValue(), metrics, alertDef);
+ return singletonList(alert);
+ } else {
+ LOG.info("Unsupported metrics value: {} when running alert: {}", metrics.get(0), alertDef);
+ return emptyList();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/alerts/Threshold.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/alerts/Threshold.java b/ambari-server/src/main/java/org/apache/ambari/server/alerts/Threshold.java
new file mode 100644
index 0000000..ae33eeb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/Threshold.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.alerts;
+
+import javax.annotation.Nullable;
+
+import org.apache.ambari.server.state.AlertState;
+
+/**
+ * I'm a 3 level threshold where each level corresponds to ok, warn and critical levels.
+ * The levels are either increasing or decreasing numerical sequences.
+ * My main responsibility is to map incoming values to {@link AlertState} based on the threshold levels.
+ */
+public class Threshold {
+ private final Double okValue;
+ private final double warnValue;
+ private final double critValue;
+
+ public Threshold(@Nullable Double okValue, double warnValue, double critValue) {
+ this.okValue = okValue;
+ this.warnValue = warnValue;
+ this.critValue = critValue;
+ }
+
+ public AlertState state(double value) {
+ return directionUp() ? stateWhenDirectionUp(value) : stateWhenDirectionDown(value);
+ }
+
+ private boolean directionUp() {
+ return critValue >= warnValue;
+ }
+
+ private AlertState stateWhenDirectionUp(double value) {
+ if (value >= critValue) {
+ return AlertState.CRITICAL;
+ }
+ if (value >= warnValue) {
+ return AlertState.WARNING;
+ }
+ if (okValue == null || value >= okValue) {
+ return AlertState.OK;
+ }
+ return AlertState.UNKNOWN;
+ }
+
+ private AlertState stateWhenDirectionDown(double value) {
+ if (value <= critValue) {
+ return AlertState.CRITICAL;
+ }
+ if (value <= warnValue) {
+ return AlertState.WARNING;
+ }
+ if (okValue == null || value <= okValue) {
+ return AlertState.OK;
+ }
+ return AlertState.UNKNOWN;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 1b4d741..8bc8cbf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -2764,6 +2764,13 @@ public class Configuration {
public static final ConfigurationProperty<String> DISPATCH_PROPERTY_SCRIPT_DIRECTORY = new ConfigurationProperty<>(
"notification.dispatch.alert.script.directory",AmbariPath.getPath("/var/lib/ambari-server/resources/scripts"));
+ /**
+ * The core pool size of the executor service that runs server side alerts.
+ */
+ @Markdown(description = "The core pool size of the executor service that runs server side alerts.")
+ public static final ConfigurationProperty<Integer> SERVER_SIDE_ALERTS_CORE_POOL_SIZE = new ConfigurationProperty<>(
+ "alerts.server.side.scheduler.threadpool.size.core", 4);
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
@@ -6193,4 +6200,8 @@ public class Configuration {
public String getAutoGroupCreation() {
return getProperty(AUTO_GROUP_CREATION);
}
+
+ public int getAlertServiceCorePoolSize() {
+ return Integer.parseInt(getProperty(SERVER_SIDE_ALERTS_CORE_POOL_SIZE));
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index dc97871..76cd22e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -358,6 +358,7 @@ public class ControllerModule extends AbstractModule {
// So it's an "additional time", given to stage to finish execution before
// it is considered as timed out
bindConstant().annotatedWith(Names.named("actionTimeout")).to(600000L);
+ bindConstant().annotatedWith(Names.named("alertServiceCorePoolSize")).to(configuration.getAlertServiceCorePoolSize());
bindConstant().annotatedWith(Names.named("dbInitNeeded")).to(dbInitNeeded);
bindConstant().annotatedWith(Names.named("statusCheckInterval")).to(5000L);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetricHolder.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetricHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetricHolder.java
index 81d72fb..f6ae54f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetricHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXMetricHolder.java
@@ -18,13 +18,18 @@
package org.apache.ambari.server.controller.jmx;
+import static java.util.stream.Collectors.toList;
+
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
/**
*
*/
public final class JMXMetricHolder {
+ private static final String NAME_KEY = "name";
private List<Map<String, Object>> beans;
@@ -47,4 +52,26 @@ public final class JMXMetricHolder {
}
return stringBuilder.toString();
}
+
+ public List<Object> findAll(List<String> properties) {
+ return properties.stream()
+ .map(this::find)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(toList());
+ }
+
+ public Optional<Object> find(String property) {
+ String propertyName = property.split("/")[0];
+ String propertyValue = property.split("/")[1];
+ return beans.stream()
+ .filter(each -> propertyName.equals(name(each)))
+ .map(each -> each.get(propertyValue))
+ .filter(Objects::nonNull)
+ .findFirst();
+ }
+
+ private String name(Map<String, Object> bean) {
+ return bean.containsKey(NAME_KEY) ? (String) bean.get(NAME_KEY) : null;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
index 5d2ecc6..49bd5d2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
@@ -56,6 +56,7 @@ public class Alert {
component = componentName;
this.hostName = hostName;
state = alertState;
+ timestamp = System.currentTimeMillis();
}
public Alert() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertUri.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertUri.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertUri.java
index 93801d5..b3ef2de 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertUri.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertUri.java
@@ -17,8 +17,13 @@
*/
package org.apache.ambari.server.state.alert;
+import java.net.URI;
+import java.util.Map;
import java.util.Set;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.kerberos.VariableReplacementHelper;
+
import com.google.gson.annotations.SerializedName;
/**
@@ -87,6 +92,13 @@ public class AlertUri {
@SerializedName("connection_timeout")
private float m_connectionTimeout = 5.0f;
+
+ /**
+ * An optional read timeout value for connections.
+ */
+ @SerializedName("read_timeout")
+ private float readTimeout = 15.0f;
+
/**
* If present, then the component supports HA mode and the properties
* contained within need to be checked to see if an HA URI is required to be
@@ -117,6 +129,18 @@ public class AlertUri {
m_httpUri = httpUri;
}
+ public void setHttpsUri(String httpsUri) {
+ this.m_httpsUri = httpsUri;
+ }
+
+ public void setHttpsPropertyValue(String m_httpsPropertyValue) {
+ this.m_httpsPropertyValue = m_httpsPropertyValue;
+ }
+
+ public void setHttpsProperty(String m_httpsProperty) {
+ this.m_httpsProperty = m_httpsProperty;
+ }
+
/**
* Gets the default port to use on the host running the alert if none of the
* http properties are available.
@@ -276,6 +300,23 @@ public class AlertUri {
}
}
+ public URI resolve(Map<String, Map<String, String>> config) throws AmbariException {
+ VariableReplacementHelper variableReplacer = new VariableReplacementHelper();
+ String httpsProperty = variableReplacer.replaceVariables(m_httpsProperty, config);
+ String httpsPropertyValue = variableReplacer.replaceVariables(m_httpsPropertyValue, config);
+ return httpsProperty == null || !httpsProperty.equals(httpsPropertyValue)
+ ? URI.create(String.format("http://%s", variableReplacer.replaceVariables(m_httpUri, config)))
+ : URI.create(String.format("https://%s", variableReplacer.replaceVariables(m_httpsUri, config)));
+ }
+
+ public int getConnectionTimeoutMsec() {
+ return (int) m_connectionTimeout * 1000;
+ }
+
+ public int getReadTimeoutMsec() {
+ return (int) readTimeout * 1000;
+ }
+
/**
* {@inheritDoc}
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
index 11eee05..d7283fe 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
@@ -129,6 +129,9 @@ public class MetricSource extends Source {
private String value;
+ @SerializedName("url_suffix")
+ private String urlSuffix = "/jmx";
+
public List<String> getPropertyList() {
return propertyList;
}
@@ -152,5 +155,9 @@ public class MetricSource extends Source {
return list1.equals(list2);
}
+
+ public String getUrlSuffix() {
+ return urlSuffix;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Reporting.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Reporting.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Reporting.java
index 4aeba45..51d074e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Reporting.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Reporting.java
@@ -17,6 +17,15 @@
*/
package org.apache.ambari.server.state.alert;
+import static org.apache.ambari.server.state.alert.Reporting.ReportingType.PERCENT;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import org.apache.ambari.server.alerts.Threshold;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+
import com.google.gson.annotations.SerializedName;
/**
@@ -200,6 +209,40 @@ public class Reporting {
}
/**
+ * Map the incoming value to {@link AlertState} and generate an alert with that state.
+ */
+ public Alert alert(double value, List<Object> args, AlertDefinition alertDef) {
+ Alert alert = new Alert(alertDef.getName(), null, alertDef.getServiceName(), alertDef.getComponentName(), null, state(value));
+ alert.setText(MessageFormat.format(message(value), args.toArray()));
+ return alert;
+ }
+
+ private AlertState state(double value) {
+ return getThreshold().state(PERCENT == getType() ? value * 100 : value);
+ }
+
+ private Threshold getThreshold() {
+ return new Threshold(getOk().getValue(), getWarning().getValue(), getCritical().getValue());
+ }
+
+ private String message(double value) {
+ switch (state(value)) {
+ case OK:
+ return getOk().getText();
+ case WARNING:
+ return getWarning().getText();
+ case CRITICAL:
+ return getCritical().getText();
+ case UNKNOWN:
+ return "Unknown";
+ case SKIPPED:
+ return "Skipped";
+ default:
+ throw new IllegalStateException("Invalid alert state: " + state(value));
+ }
+ }
+
+ /**
* The {@link ReportTemplate} class is used to pair a label and threshhold
* value.
* <p/>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/alert/ServerSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/ServerSource.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/ServerSource.java
index c58867a..765bdea 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/ServerSource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/ServerSource.java
@@ -28,6 +28,13 @@ public class ServerSource extends ParameterizedSource {
@SerializedName("class")
private String m_class;
+ @SerializedName("uri")
+ private AlertUri uri = null;
+
+ @SerializedName("jmx")
+ private MetricSource.JmxInfo jmxInfo = null;
+
+
/**
* Gets the fully qualified classname specified in the source.
*/
@@ -35,6 +42,14 @@ public class ServerSource extends ParameterizedSource {
return m_class;
}
+ public MetricSource.JmxInfo getJmxInfo() {
+ return jmxInfo;
+ }
+
+ public AlertUri getUri() {
+ return uri;
+ }
+
/**
* {@inheritDoc}
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
index d3237a9..d235631 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
@@ -45,6 +45,7 @@ import com.google.common.util.concurrent.AbstractScheduledService;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
+import com.google.inject.name.Named;
/**
* The {@link AmbariServerAlertService} is used to manage the dynamically loaded
@@ -87,7 +88,7 @@ public class AmbariServerAlertService extends AbstractScheduledService {
/**
* The executor to use to run all {@link Runnable} alert classes.
*/
- private final ScheduledExecutorService m_scheduledExecutorService = Executors.newScheduledThreadPool(3);
+ private ScheduledExecutorService m_scheduledExecutorService;
/**
* A map of all of the definition names to {@link ScheduledFuture}s.
@@ -101,6 +102,10 @@ public class AmbariServerAlertService extends AbstractScheduledService {
public AmbariServerAlertService() {
}
+ @Inject
+ public void initExecutor(@Named("alertServiceCorePoolSize") int alertServiceCorePoolSize) {
+ this.m_scheduledExecutorService = Executors.newScheduledThreadPool(alertServiceCorePoolSize);
+ }
/**
* {@inheritDoc}
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/test/java/org/apache/ambari/server/alerts/ThresholdTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/alerts/ThresholdTest.java b/ambari-server/src/test/java/org/apache/ambari/server/alerts/ThresholdTest.java
new file mode 100644
index 0000000..07bfa03
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/alerts/ThresholdTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.alerts;
+
+import static org.apache.ambari.server.state.AlertState.CRITICAL;
+import static org.apache.ambari.server.state.AlertState.OK;
+import static org.apache.ambari.server.state.AlertState.UNKNOWN;
+import static org.apache.ambari.server.state.AlertState.WARNING;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import org.apache.ambari.server.state.AlertState;
+import org.junit.Test;
+
+public class ThresholdTest {
+ @Test
+ public void testBetweenOkAndWarnIsOk_dirUp() throws Exception {
+ Threshold threshold = new Threshold(10.0, 20.0, 30.0);
+ assertState(threshold, OK, 10, 15, 19);
+ }
+
+ @Test
+ public void testBetweenWarnAndCritIsWarn_dirUp() throws Exception {
+ Threshold threshold = new Threshold(10.0, 20.0, 30.0);
+ assertState(threshold, WARNING, 20, 25, 29);
+ }
+
+ @Test
+ public void testAboveCritIsCrit_dirUp() throws Exception {
+ Threshold threshold = new Threshold(10.0, 20.0, 30.0);
+ assertState(threshold, CRITICAL, 30, 40, 99999);
+ }
+
+ @Test
+ public void testBelowOkIsUnknown_dirUp() throws Exception {
+ Threshold threshold = new Threshold(10.0, 20, 30);
+ assertState(threshold, UNKNOWN, 9, 2, -99999);
+ }
+
+ @Test
+ public void testBelowCritIsCrit_dirDown() throws Exception {
+ Threshold threshold = new Threshold(40.0, 30.0, 20.0);
+ assertState(threshold, CRITICAL, 20, 15, 2, -99999);
+ }
+
+ @Test
+ public void testBetweenWarnAndCritIsWarn_dirDown() throws Exception {
+ Threshold threshold = new Threshold(40.0, 30.0, 20.0);
+ assertState(threshold, WARNING, 30, 25, 21);
+ }
+
+ @Test
+ public void testBetweenOkAndWarnIsOk_dirDown() throws Exception {
+ Threshold threshold = new Threshold(40.0, 30.0, 20.0);
+ assertState(threshold, OK, 40, 35, 31);
+ }
+
+ @Test
+ public void testAboveOkIsUnknown_dirDown() throws Exception {
+ Threshold threshold = new Threshold(40.0, 30.0, 20.0);
+ assertState(threshold, UNKNOWN, 41, 50, 9999);
+ }
+
+ @Test
+ public void testOkIsOptional() throws Exception {
+ Threshold threshold = new Threshold(null, 20.0, 30.0);
+ assertState(threshold, OK, 10, 15, 19);
+ }
+
+ private void assertState(Threshold threshold, AlertState expectedState, int... values) {
+ for (int value: values) {
+ assertThat(expectedState, is(threshold.state(value)));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/test/java/org/apache/ambari/server/controller/jmx/JMXMetricHolderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/jmx/JMXMetricHolderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/jmx/JMXMetricHolderTest.java
new file mode 100644
index 0000000..61d5bae
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/jmx/JMXMetricHolderTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.jmx;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class JMXMetricHolderTest {
+ private JMXMetricHolder metrics = new JMXMetricHolder();
+
+ @Before
+ public void setUp() {
+ metrics.setBeans(asList(
+ new HashMap<String, Object>() {{
+ put("name", "bean1");
+ put("value", "val1");
+ }},
+ new HashMap<String, Object>() {{
+ put("name", "bean2");
+ put("value", "val2");
+ }}
+ ));
+ }
+
+ @Test
+ public void testFindSingleBeanByName() throws Exception {
+ assertThat(metrics.find("bean1/value"), is(Optional.of("val1")));
+ assertThat(metrics.find("bean2/value"), is(Optional.of("val2")));
+ assertThat(metrics.find("bean3/notfound"), is(Optional.empty()));
+ }
+
+ @Test
+ public void testFindMultipleBeansByName() throws Exception {
+ List<Object> result = metrics.findAll(asList("bean1/value", "bean2/value", "bean3/notfound"));
+ assertThat(result, hasItems("val1", "val2"));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/b552da9e/ambari-server/src/test/java/org/apache/ambari/server/state/alert/AlertUriTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alert/AlertUriTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alert/AlertUriTest.java
new file mode 100644
index 0000000..295e364
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alert/AlertUriTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.state.alert;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.junit.Test;
+
+public class AlertUriTest {
+ @Test
+ public void testChoosesHttpByDefault() throws Exception {
+ AlertUri uri = new AlertUri();
+ uri.setHttpUri("${config1/http-host}/path");
+ assertThat(resolved(uri), is("http://http-host/path"));
+ }
+
+ @Test
+ public void testChoosesHttpsBasedOnProperties() throws Exception {
+ AlertUri uri = new AlertUri();
+ uri.setHttpUri("${config1/http-host}/path");
+ uri.setHttpsUri("${config1/https-host}/path");
+ uri.setHttpsProperty("${config1/use-http}");
+ uri.setHttpsPropertyValue("YES");
+ assertThat(resolved(uri), is("https://https-host/path"));
+ }
+
+ private Map<String, Map<String, String>> config() {
+ return new HashMap<String, Map<String, String>>() {{
+ put("config1", new HashMap<String, String>() {{
+ put("http-host", "http-host");
+ put("https-host", "https-host");
+ put("use-http", "YES");
+ }});
+ }};
+ }
+
+ private String resolved(AlertUri uri) throws AmbariException {
+ return uri.resolve(config()).toString();
+ }
+}
\ No newline at end of file