Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0699E200BBB for ; Thu, 10 Nov 2016 11:34:16 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 0524E160B01; Thu, 10 Nov 2016 10:34:16 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 5283B160AF6 for ; Thu, 10 Nov 2016 11:34:14 +0100 (CET) Received: (qmail 91288 invoked by uid 500); 10 Nov 2016 10:34:13 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 91279 invoked by uid 99); 10 Nov 2016 10:34:13 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 10 Nov 2016 10:34:13 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 64C43E00E5; Thu, 10 Nov 2016 10:34:13 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: dsen@apache.org To: commits@ambari.apache.org Message-Id: <265b4a5714a847c6b114552831b104d3@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-18833 Add Support For Self-Contained Ambari SNMP (dsen) Date: Thu, 10 Nov 2016 10:34:13 +0000 (UTC) archived-at: Thu, 10 Nov 2016 10:34:16 -0000 Repository: ambari Updated Branches: refs/heads/trunk 03f6398fc -> db2013a47 AMBARI-18833 Add Support For Self-Contained Ambari SNMP (dsen) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/db2013a4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/db2013a4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/db2013a4 Branch: refs/heads/trunk Commit: db2013a4750425fdbdfeb7b597350ea0b446e62d Parents: 03f6398 Author: Dmytro Sen Authored: Thu Nov 10 12:33:59 2016 +0200 Committer: Dmytro Sen Committed: Thu Nov 10 12:33:59 2016 +0200 ---------------------------------------------------------------------- ambari-server/docs/configuration/index.md | 5 +- .../server/configuration/Configuration.java | 16 + .../server/controller/ControllerModule.java | 5 +- .../dispatchers/AmbariSNMPDispatcher.java | 150 +++++ .../dispatchers/SNMPDispatcher.java | 25 +- .../server/orm/entities/AlertHistoryEntity.java | 3 + .../ambari/server/state/alert/TargetType.java | 7 +- .../services/AlertNoticeDispatchService.java | 19 + .../dispatchers/AmbariSNMPDispatcherTest.java | 553 +++++++++++++++++++ 9 files changed, 772 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/docs/configuration/index.md ---------------------------------------------------------------------- diff --git a/ambari-server/docs/configuration/index.md b/ambari-server/docs/configuration/index.md index 9d793ff..2fc6b26 100644 --- a/ambari-server/docs/configuration/index.md +++ b/ambari-server/docs/configuration/index.md @@ -53,7 +53,8 @@ The following are the properties which can be used to configure Ambari. | alerts.cache.size | The size of the alert cache.

This property is related to `alerts.cache.enabled`. |`50000` | | alerts.execution.scheduler.maxThreads | 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.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. | | +| alerts.ambari.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.

The following are examples of valid values:
  • `http://ambari.apache.org:8080`
| | | ambari.ldap.isConfigured | An internal property used for unit testing and development purposes. |`false` | | ambari.python.wrap | The name of the shell script used to wrap all invocations of Python by Ambari. |`ambari-python-wrap` | @@ -312,4 +313,4 @@ EclipseLink properties can also be configured using a prefix of `server.persiste ``` server.persistence.properties.eclipselink.jdbc.batch-writing.size=25 server.persistence.properties.eclipselink.profiler=QueryMonitor -``` \ No newline at end of file +``` http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/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 83e8dac..9d2243b 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 @@ -2375,6 +2375,13 @@ public class Configuration { "alerts.snmp.dispatcher.udp.port", null); /** + * The UDP port to use when binding the Ambari SNMP dispatcher on Ambari Server startup. + */ + @Markdown(description = "The UDP port to use when binding the Ambari SNMP dispatcher on Ambari Server startup. If no port is specified, then a random port will be used.") + public static final ConfigurationProperty ALERTS_AMBARI_SNMP_DISPATCH_UDP_PORT = new ConfigurationProperty<>( + "alerts.ambari.snmp.dispatcher.udp.port", null); + + /** * The amount of time, in {@link TimeUnit#MINUTES}, that the * {@link MetricsRetrievalService} will cache retrieved metric data. */ @@ -5029,6 +5036,15 @@ public class Configuration { return StringUtils.isEmpty(udpPort) ? null : Integer.parseInt(udpPort); } + /** + * Customized UDP port for Ambari SNMP dispatcher + * @return Integer if property exists else null + */ + public Integer getAmbariSNMPUdpBindPort() { + String udpPort = getProperty(ALERTS_AMBARI_SNMP_DISPATCH_UDP_PORT); + return StringUtils.isEmpty(udpPort) ? null : Integer.parseInt(udpPort); + } + public boolean isLdapAlternateUserSearchEnabled() { return Boolean.parseBoolean(getProperty(LDAP_ALT_USER_SEARCH_ENABLED)); } http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/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 e32e653..412c45f 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 @@ -83,6 +83,7 @@ import org.apache.ambari.server.metrics.system.MetricsService; import org.apache.ambari.server.metrics.system.impl.MetricsServiceImpl; import org.apache.ambari.server.notifications.DispatchFactory; import org.apache.ambari.server.notifications.NotificationDispatcher; +import org.apache.ambari.server.notifications.dispatchers.AmbariSNMPDispatcher; import org.apache.ambari.server.notifications.dispatchers.SNMPDispatcher; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.DBAccessorImpl; @@ -605,7 +606,9 @@ public class ControllerModule extends AbstractModule { try { NotificationDispatcher dispatcher; - if (clazz.equals(SNMPDispatcher.class)) { + if (clazz.equals(AmbariSNMPDispatcher.class)) { + dispatcher = (NotificationDispatcher) clazz.getConstructor(Integer.class).newInstance(configuration.getAmbariSNMPUdpBindPort()); + } else if (clazz.equals(SNMPDispatcher.class)) { dispatcher = (NotificationDispatcher) clazz.getConstructor(Integer.class).newInstance(configuration.getSNMPUdpBindPort()); } else { dispatcher = (NotificationDispatcher) clazz.newInstance(); http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcher.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcher.java new file mode 100644 index 0000000..77e55a4 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcher.java @@ -0,0 +1,150 @@ +/** + * 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.notifications.dispatchers; + +import com.google.inject.Singleton; +import org.apache.ambari.server.notifications.Notification; +import org.apache.ambari.server.state.alert.AlertNotification; +import org.apache.ambari.server.state.alert.TargetType; +import org.apache.ambari.server.state.services.AlertNoticeDispatchService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.snmp4j.PDU; +import org.snmp4j.Snmp; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.smi.OID; +import org.snmp4j.smi.OctetString; +import org.snmp4j.smi.VariableBinding; +import org.snmp4j.util.DefaultPDUFactory; + +import java.io.IOException; +import java.util.*; + +/** + * The {@link AmbariSNMPDispatcher} class is used to dispatch {@link AlertNotification} via SNMP using predefined Ambari OIDs. + * + *
The base OID for Ambari is 1.3.6.1.4.1.18060.16. Off of this, we define the following:
+ * .0 - apacheAmbariTraps
+ * .1 - apacheAmbariAlerts
+ * From these two roots, we define other bindings:
+ * .1.1 - apacheAmbariAlertTable
+ * .1.1.1 - apacheAmbariAlertEntry
+ * .1.1.1.2 - alertDefinitionName
+ * 
+ */ + +@Singleton +public class AmbariSNMPDispatcher extends SNMPDispatcher { + + private static final Logger LOG = LoggerFactory.getLogger(AmbariSNMPDispatcher.class); + + public static final String BASE_AMBARI_OID = "1.3.6.1.4.1.18060.16"; + public static final String APACHE_AMBARI_TRAPS_OID = BASE_AMBARI_OID + ".0"; + public static final String AMBARI_ALERTS_OID = BASE_AMBARI_OID + ".1"; + public static final String AMBARI_ALERT_TABLE_OID = AMBARI_ALERTS_OID + ".1"; + public static final String AMBARI_ALERT_ENTRY_OID = AMBARI_ALERT_TABLE_OID + ".1"; + //ALERT_ENTRY fields + public static final String AMBARI_ALERT_DEFINITION_ID_OID = AMBARI_ALERT_ENTRY_OID + ".1"; + public static final String AMBARI_ALERT_DEFINITION_NAME_OID = AMBARI_ALERT_ENTRY_OID + ".2"; + public static final String AMBARI_ALERT_DEFINITION_HASH_OID = AMBARI_ALERT_ENTRY_OID + ".3"; + public static final String AMBARI_ALERT_NAME_OID = AMBARI_ALERT_ENTRY_OID + ".4"; + public static final String AMBARI_ALERT_TEXT_OID = AMBARI_ALERT_ENTRY_OID + ".5"; + public static final String AMBARI_ALERT_STATE_OID = AMBARI_ALERT_ENTRY_OID + ".6"; + public static final String AMBARI_ALERT_HOST_NAME_OID = AMBARI_ALERT_ENTRY_OID + ".7"; + public static final String AMBARI_ALERT_SERVICE_NAME_OID = AMBARI_ALERT_ENTRY_OID + ".8"; + public static final String AMBARI_ALERT_COMPONENT_NAME_OID = AMBARI_ALERT_ENTRY_OID + ".9"; + + protected AmbariSNMPDispatcher(Snmp snmp) { + super(snmp); + } + + public AmbariSNMPDispatcher(Integer port) throws IOException { + super(port); + } + + /** + * {@inheritDoc} + */ + @Override + public String getType() { + return TargetType.AMBARI_SNMP.name(); + } + + /** + * {@inheritDoc} + * Uses default Ambari OIDs + */ + protected PDU prepareTrap(Notification notification, SnmpVersion snmpVersion) throws InvalidSnmpConfigurationException { + AlertNotification alertNotification; + PDU pdu = DefaultPDUFactory.createPDU(snmpVersion.getTargetVersion()); + + if (Notification.Type.ALERT.equals(notification.getType())) { + try { + alertNotification = (AlertNotification) notification; + } catch (ClassCastException e) { + LOG.error("Notification wasn't casted to AlertNotification. Returning empty Protocol data unit", e); + return pdu; + } + } else { + LOG.error("Notification for AmbariSNMPDispatcher should be of type AlertNotification, but it wasn't. Returning empty Protocol data unit"); + return pdu; + } + + pdu.setType(snmpVersion.getTrapType()); + // Set trap oid for PDU + pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(APACHE_AMBARI_TRAPS_OID))); + // Set notification body and subject for PDU objects with identifiers specified in dispatch properties. + AlertNoticeDispatchService.AlertInfo alertInfo = alertNotification.getAlertInfo(); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_DEFINITION_ID_OID, alertInfo.getAlertDefinitionId()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_DEFINITION_NAME_OID, alertInfo.getAlertDefinition().getDefinitionName()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_DEFINITION_HASH_OID, alertInfo.getAlertDefinitionHash()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_NAME_OID, alertInfo.getAlertName()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_TEXT_OID, alertInfo.getAlertText()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_STATE_OID, alertInfo.getAlertState()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_HOST_NAME_OID, alertInfo.getHostName()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_SERVICE_NAME_OID, alertInfo.getServiceName()); + addVariableBindingCheckForNull(pdu, AMBARI_ALERT_COMPONENT_NAME_OID, alertInfo.getComponentName()); + + return pdu; + } + + /** + * {@inheritDoc} + */ + @Override + protected Set getSetOfDefaultNeededPropertyNames() { + return new HashSet<>(Collections.singletonList(PORT_PROPERTY)); + } + + /** + * Adds new {@link VariableBinding} using provided {@link OID} and value to {@link PDU} + * if val is null than adds {@link OctetString} with "null" value; + * @param pdu + * @param oid + * @param val + */ + private void addVariableBindingCheckForNull(PDU pdu, String oid, Object val) { + if (val == null) { + pdu.add(new VariableBinding(new OID(oid), new OctetString("null"))); + } else { + pdu.add(new VariableBinding(new OID(oid), + new OctetString(String.valueOf(val)))); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/SNMPDispatcher.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/SNMPDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/SNMPDispatcher.java index 22a78ef..575f17b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/SNMPDispatcher.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/SNMPDispatcher.java @@ -22,6 +22,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.HashSet; import org.apache.ambari.server.notifications.Notification; import org.apache.ambari.server.notifications.NotificationDispatcher; @@ -174,10 +176,11 @@ public class SNMPDispatcher implements NotificationDispatcher { stringValuesConfig.put(propertyEntry.getKey(), propertyEntry.getValue().toString()); } try { - getDispatchProperty(stringValuesConfig, BODY_OID_PROPERTY); - getDispatchProperty(stringValuesConfig, SUBJECT_OID_PROPERTY); - getDispatchProperty(stringValuesConfig, TRAP_OID_PROPERTY); - getDispatchProperty(stringValuesConfig, PORT_PROPERTY); + + for (String property : getSetOfDefaultNeededPropertyNames()) { + getDispatchProperty(stringValuesConfig, property); + } + SnmpVersion snmpVersion = getSnmpVersion(stringValuesConfig); switch (snmpVersion) { case SNMPv3: @@ -205,6 +208,14 @@ public class SNMPDispatcher implements NotificationDispatcher { } /** + * @return Set that contains names of properties that are needed for all SNMP configurations. + */ + protected Set getSetOfDefaultNeededPropertyNames() { + return new HashSet<>(Arrays.asList(BODY_OID_PROPERTY, SUBJECT_OID_PROPERTY, + TRAP_OID_PROPERTY, PORT_PROPERTY)); + } + + /** * Creates protocol data unit (PDU) with corresponding SNMP version for alert notification. * @param notification alert notification to dispatch * @param snmpVersion SNMP version @@ -376,7 +387,7 @@ public class SNMPDispatcher implements NotificationDispatcher { * @return property value * @throws InvalidSnmpConfigurationException if property with such key does not exist */ - private static String getDispatchProperty(Map dispatchProperties, String key) throws InvalidSnmpConfigurationException { + protected static String getDispatchProperty(Map dispatchProperties, String key) throws InvalidSnmpConfigurationException { if (dispatchProperties == null || !dispatchProperties.containsKey(key)) { throw new InvalidSnmpConfigurationException(String.format("Property \"%s\" should be set.", key)); } @@ -389,7 +400,7 @@ public class SNMPDispatcher implements NotificationDispatcher { * @return corresponding SnmpVersion instance * @throws InvalidSnmpConfigurationException if dispatch properties doesn't contain required property */ - private SnmpVersion getSnmpVersion(Map dispatchProperties) throws InvalidSnmpConfigurationException { + protected SnmpVersion getSnmpVersion(Map dispatchProperties) throws InvalidSnmpConfigurationException { String snmpVersion = getDispatchProperty(dispatchProperties, SNMP_VERSION_PROPERTY); try { return SnmpVersion.valueOf(snmpVersion); @@ -406,7 +417,7 @@ public class SNMPDispatcher implements NotificationDispatcher { * @return corresponding TrapSecurity instance * @throws InvalidSnmpConfigurationException if dispatch properties doesn't contain required property */ - private TrapSecurity getSecurityLevel(Map dispatchProperties) throws InvalidSnmpConfigurationException { + protected TrapSecurity getSecurityLevel(Map dispatchProperties) throws InvalidSnmpConfigurationException { String securityLevel = getDispatchProperty(dispatchProperties, SECURITY_LEVEL_PROPERTY); try { return TrapSecurity.valueOf(securityLevel); http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java index 958740a..5eb9c27 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java @@ -441,4 +441,7 @@ public class AlertHistoryEntity { return buffer.toString(); } + public int getAlertDefinitionHash() { + return this.getAlertDefinition().hashCode(); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java index 53be9e1..f1e5f50 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java @@ -30,11 +30,16 @@ public enum TargetType { EMAIL, /** - * Alerts will be distributed via SNMP. + * Alerts will be distributed via SNMP with custom OIDs. */ SNMP, /** + * Alerts will be distributed via SNMP with ambari OIDs + */ + AMBARI_SNMP, + + /** * Alerts will be distributed to a logger. */ LOG, http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java index 9e424f7..174f31f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java @@ -777,6 +777,25 @@ public class AlertNoticeDispatchService extends AbstractScheduledService { } /** + * Gets the definition id of the alert. + * + * @return + */ + public Long getAlertDefinitionId() { + return m_history.getAlertDefinitionId(); + } + + /** + * Gets the hash of alert definition entity. + * + * @return + */ + public int getAlertDefinitionHash() { + return m_history.getAlertDefinitionHash(); + } + + + /** * Gets the descriptive name of the alert. * * @return http://git-wip-us.apache.org/repos/asf/ambari/blob/db2013a4/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcherTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcherTest.java new file mode 100644 index 0000000..fa02f17 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AmbariSNMPDispatcherTest.java @@ -0,0 +1,553 @@ +/** + * 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.notifications.dispatchers; + +import org.apache.ambari.server.notifications.TargetConfigurationResult; +import org.apache.ambari.server.notifications.DispatchCallback; +import org.apache.ambari.server.notifications.Notification; +import org.apache.ambari.server.notifications.NotificationDispatcher; +import org.apache.ambari.server.notifications.Recipient; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; +import org.apache.ambari.server.orm.entities.AlertHistoryEntity; +import org.apache.ambari.server.state.AlertState; +import org.apache.ambari.server.state.alert.AlertNotification; +import org.apache.ambari.server.state.services.AlertNoticeDispatchService; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.snmp4j.PDU; +import org.snmp4j.Snmp; +import org.snmp4j.Target; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.smi.VariableBinding; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class AmbariSNMPDispatcherTest { + + private static final int DEFAULT_SNMP_PORT = 31444; + + + public static final String DEFINITION_NAME = "definition name"; + public static final String ALERT_LABEL = "alert name"; + public static final String ALERT_TEXT = "alert text"; + public static final String ALERT_HOSTNAME = "hostname"; + public static final String ALERT_SERVICE_NAME = "service name"; + public static final String ALERT_COMPONENT_NAME = "component name"; + public static final Long DEFINITION_ID = 1L; + public static final AlertState ALERT_STATE = AlertState.OK; + + @Test + public void testDispatch_nullProperties() throws Exception { + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatchUdpTransportMappingCrash() throws Exception { + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT)); + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv1; + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + notification.DispatchProperties = properties; + notification.Recipients = Arrays.asList(new Recipient()); + doThrow(new IOException()).when(dispatcher).sendTraps(notification, snmpVersion); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + assertNull(dispatcher.getTransportMapping()); + } + + @Test + public void testDispatch_notDefinedProperties() throws Exception { + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + notification.DispatchProperties = new HashMap(); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_nullRecipients() throws Exception { + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = getAlertNotification(true); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + notification.DispatchProperties = properties; + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_noRecipients() throws Exception { + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = getAlertNotification(true); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + notification.DispatchProperties = properties; + notification.Recipients = new ArrayList(); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_sendTrapError() throws Exception { + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT)); + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + notification.DispatchProperties = properties; + notification.Recipients = Arrays.asList(new Recipient()); + doThrow(new RuntimeException()).when(dispatcher).sendTraps(eq(notification), any(AmbariSNMPDispatcher.SnmpVersion.class)); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_incorrectSnmpVersion() throws Exception { + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT)); + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv11"); + notification.DispatchProperties = properties; + notification.Recipients = Arrays.asList(new Recipient()); + dispatcher.dispatch(notification); + verify(notification.Callback).onFailure(notification.CallbackIds); + verify(notification.Callback, never()).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_successful_v1() throws Exception { + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT)); + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv1; + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + notification.DispatchProperties = properties; + notification.Recipients = Arrays.asList(new Recipient()); + doNothing().when(dispatcher).sendTraps(notification, snmpVersion); + dispatcher.dispatch(notification); + verify(notification.Callback, never()).onFailure(notification.CallbackIds); + verify(notification.Callback).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_successful_v2() throws Exception { + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT)); + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv2c; + Notification notification = mock(AlertNotification.class); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "3"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "4"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv2c"); + notification.DispatchProperties = properties; + notification.Recipients = Arrays.asList(new Recipient()); + doNothing().when(dispatcher).sendTraps(notification, snmpVersion); + dispatcher.dispatch(notification); + verify(notification.Callback, never()).onFailure(notification.CallbackIds); + verify(notification.Callback).onSuccess(notification.CallbackIds); + } + + @Test + public void testDispatch_successful_v3() throws Exception { + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = getAlertNotification(true); + notification.Callback = mock(DispatchCallback.class); + notification.CallbackIds = mock(List.class); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_PRIV_PASSPHRASE_PROPERTY, "PASSPHRASE2"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_NOPRIV"); + notification.DispatchProperties = properties; + Recipient recipient = new Recipient(); + recipient.Identifier = "192.168.0.2"; + notification.Recipients = Arrays.asList(recipient); + dispatcher.dispatch(notification); + verify(notification.Callback, never()).onFailure(notification.CallbackIds); + verify(notification.Callback).onSuccess(notification.CallbackIds); + } + + @Test + public void testPrepareTrap_v1() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv1; + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = getAlertNotification(true); + PDU pdu = dispatcher.prepareTrap(notification, snmpVersion); + assertEquals(PDU.V1TRAP, pdu.getType()); + Map variableBindings = new HashMap(); + for (VariableBinding variableBinding : pdu.toArray()) { + variableBindings.put(variableBinding.getOid().toString(), variableBinding); + } + assertEquals(10, variableBindings.size()); + assertEquals(AmbariSNMPDispatcher.APACHE_AMBARI_TRAPS_OID, variableBindings.get(SnmpConstants.snmpTrapOID.toString()).toValueString()); + assertEquals(String.valueOf(DEFINITION_ID), variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_ID_OID).toValueString()); + assertEquals(DEFINITION_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_NAME_OID).toValueString()); + assertEquals(ALERT_LABEL, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_NAME_OID).toValueString()); + assertEquals(ALERT_TEXT, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_TEXT_OID).toValueString()); + assertEquals(String.valueOf(ALERT_STATE), variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_STATE_OID).toValueString()); + assertEquals(ALERT_HOSTNAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_HOST_NAME_OID).toValueString()); + assertEquals(ALERT_SERVICE_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_SERVICE_NAME_OID).toValueString()); + assertEquals(ALERT_COMPONENT_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_COMPONENT_NAME_OID).toValueString()); + } + + @Test + public void testPrepareTrapNull() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv1; + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + AlertNotification notification = (AlertNotification) getAlertNotification(false); + PDU pdu = dispatcher.prepareTrap(notification, snmpVersion); + assertEquals(PDU.V1TRAP, pdu.getType()); + Map variableBindings = new HashMap(); + for (VariableBinding variableBinding : pdu.toArray()) { + variableBindings.put(variableBinding.getOid().toString(), variableBinding); + } + assertEquals(10, variableBindings.size()); + assertEquals("null", variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_COMPONENT_NAME_OID).toValueString()); + } + + + @Test + public void testPrepareTrap_v2c() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv2c; + AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + Notification notification = getAlertNotification(true); + PDU pdu = dispatcher.prepareTrap(notification, snmpVersion); + assertEquals(PDU.TRAP, pdu.getType()); + Map variableBindings = new HashMap(); + for (VariableBinding variableBinding : pdu.toArray()) { + variableBindings.put(variableBinding.getOid().toString(), variableBinding); + } + + assertEquals(10, variableBindings.size()); + assertEquals(AmbariSNMPDispatcher.APACHE_AMBARI_TRAPS_OID, variableBindings.get(SnmpConstants.snmpTrapOID.toString()).toValueString()); + assertEquals(String.valueOf(DEFINITION_ID), variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_ID_OID).toValueString()); + assertEquals(DEFINITION_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_NAME_OID).toValueString()); + assertEquals(ALERT_LABEL, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_NAME_OID).toValueString()); + assertEquals(ALERT_TEXT, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_TEXT_OID).toValueString()); + assertEquals(String.valueOf(ALERT_STATE), variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_STATE_OID).toValueString()); + assertEquals(ALERT_HOSTNAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_HOST_NAME_OID).toValueString()); + assertEquals(ALERT_SERVICE_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_SERVICE_NAME_OID).toValueString()); + assertEquals(ALERT_COMPONENT_NAME, variableBindings.get(AmbariSNMPDispatcher.AMBARI_ALERT_COMPONENT_NAME_OID).toValueString()); + } + + @Test + public void testSendTraps_v1() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv1; + Snmp snmp = mock(Snmp.class); + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(snmp)); + PDU trap = mock(PDU.class); + Notification notification = new AlertNotification(); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + notification.DispatchProperties = properties; + Recipient rec1 = new Recipient(); + rec1.Identifier = "192.168.0.2"; + notification.Recipients = Arrays.asList(rec1); + doReturn(trap).when(dispatcher).prepareTrap(notification, snmpVersion); + dispatcher.sendTraps(notification, snmpVersion); + ArgumentCaptor argument = ArgumentCaptor.forClass(Target.class); + verify(snmp, times(1)).send(eq(trap), argument.capture()); + assertEquals("192.168.0.2/162", argument.getValue().getAddress().toString()); + assertEquals(SnmpConstants.version1, argument.getValue().getVersion()); + } + + @Test + public void testSendTraps_v2() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv2c; + Snmp snmp = mock(Snmp.class); + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(snmp)); + PDU trap = mock(PDU.class); + Notification notification = new AlertNotification(); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + notification.DispatchProperties = properties; + Recipient rec1 = new Recipient(); + rec1.Identifier = "192.168.0.2"; + notification.Recipients = Arrays.asList(rec1); + doReturn(trap).when(dispatcher).prepareTrap(notification, snmpVersion); + dispatcher.sendTraps(notification, snmpVersion); + ArgumentCaptor argument = ArgumentCaptor.forClass(Target.class); + verify(snmp, times(1)).send(eq(trap), argument.capture()); + assertEquals("192.168.0.2/162", argument.getValue().getAddress().toString()); + assertEquals(SnmpConstants.version2c, argument.getValue().getVersion()); + } + + @Test + public void testSendTraps_v3() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv3; + Snmp snmp = mock(Snmp.class); + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(snmp)); + PDU trap = mock(PDU.class); + Notification notification = new AlertNotification(); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_PRIV_PASSPHRASE_PROPERTY, "PASSPHRASE2"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_NOPRIV"); + notification.DispatchProperties = properties; + Recipient rec1 = new Recipient(); + rec1.Identifier = "192.168.0.2"; + notification.Recipients = Arrays.asList(rec1); + doReturn(trap).when(dispatcher).prepareTrap(notification, snmpVersion); + dispatcher.sendTraps(notification, snmpVersion); + ArgumentCaptor argument = ArgumentCaptor.forClass(Target.class); + verify(snmp, times(1)).send(eq(trap), argument.capture()); + assertEquals("192.168.0.2/162", argument.getValue().getAddress().toString()); + assertEquals(SnmpConstants.version3, argument.getValue().getVersion()); + } + + @Test(expected = AmbariSNMPDispatcher.InvalidSnmpConfigurationException.class) + public void testSendTraps_v3_incorrectSecurityLevelVersion() throws Exception { + AmbariSNMPDispatcher.SnmpVersion snmpVersion = AmbariSNMPDispatcher.SnmpVersion.SNMPv3; + Snmp snmp = mock(Snmp.class); + AmbariSNMPDispatcher dispatcher = spy(new AmbariSNMPDispatcher(snmp)); + PDU trap = mock(PDU.class); + Notification notification = new AlertNotification(); + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_PRIV_PASSPHRASE_PROPERTY, "PASSPHRASE2"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "INCORRECT"); + notification.DispatchProperties = properties; + Recipient rec1 = new Recipient(); + rec1.Identifier = "192.168.0.2"; + notification.Recipients = Arrays.asList(rec1); + doReturn(trap).when(dispatcher).prepareTrap(notification, snmpVersion); + dispatcher.sendTraps(notification, snmpVersion); + } + + @Test + public void testValidateAlertValidation_SNMPv1() throws Exception { + Map properties = new HashMap(); + properties.put(SNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.VALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_incorrectSNMPversion() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv4"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv1_invalid_noPort() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv1"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv2c() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv2c"); + properties.put(AmbariSNMPDispatcher.COMMUNITY_PROPERTY, "public"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.VALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv2c_invalid() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv2c"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_incorrectSecurityLevel() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_PRIV_PASSPHRASE_PROPERTY, "PASSPHRASE2"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "INCORRECT"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_noAuthNoPriv() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "NOAUTH_NOPRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.VALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_AuthNoPriv_valid() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_NOPRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.VALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_AuthNoPriv_invalid() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_NOPRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_AuthPriv_valid() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_PRIV_PASSPHRASE_PROPERTY, "PASSPHRASE2"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_PRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.VALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_AuthPriv_noPassphrases() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_PRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + @Test + public void testValidateAlertValidation_SNMPv3_AuthPriv_onlyAuthPassphrase() throws Exception { + Map properties = new HashMap(); + properties.put(AmbariSNMPDispatcher.PORT_PROPERTY, "162"); + properties.put(AmbariSNMPDispatcher.SNMP_VERSION_PROPERTY, "SNMPv3"); + properties.put(AmbariSNMPDispatcher.SECURITY_USERNAME_PROPERTY, "USER"); + properties.put(AmbariSNMPDispatcher.SECURITY_AUTH_PASSPHRASE_PROPERTY, "PASSPHRASE1"); + properties.put(AmbariSNMPDispatcher.SECURITY_LEVEL_PROPERTY, "AUTH_PRIV"); + NotificationDispatcher dispatcher = new AmbariSNMPDispatcher(DEFAULT_SNMP_PORT); + TargetConfigurationResult configValidationResult = dispatcher.validateTargetConfig(properties); + assertEquals(TargetConfigurationResult.Status.INVALID, configValidationResult.getStatus()); + } + + private Notification getAlertNotification(boolean hasComponent) { + AlertNotification notification = new AlertNotification(); + AlertDefinitionEntity alertDefinitionEntity = new AlertDefinitionEntity(); + alertDefinitionEntity.setDefinitionName(DEFINITION_NAME); + alertDefinitionEntity.setLabel(ALERT_LABEL); + alertDefinitionEntity.setDefinitionId(DEFINITION_ID); + AlertHistoryEntity alertHistoryEntity = new AlertHistoryEntity(); + alertHistoryEntity.setAlertDefinition(alertDefinitionEntity); + alertHistoryEntity.setAlertLabel(ALERT_LABEL); + alertHistoryEntity.setAlertState(ALERT_STATE); + alertHistoryEntity.setAlertText(ALERT_TEXT); + alertHistoryEntity.setHostName(ALERT_HOSTNAME); + alertHistoryEntity.setServiceName(ALERT_SERVICE_NAME); + if (hasComponent) { + alertHistoryEntity.setComponentName(ALERT_COMPONENT_NAME); + } + AlertNoticeDispatchService.AlertInfo alertInfo = new AlertNoticeDispatchService.AlertInfo(alertHistoryEntity); + notification.setAlertInfo(alertInfo); + return notification; + } +}