|
@@ -24,13 +24,16 @@ import static org.junit.Assert.assertNotNull;
|
|
|
import static org.junit.Assert.assertNull;
|
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.EnumSet;
|
|
|
+import java.util.LinkedList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.TimeZone;
|
|
|
import java.util.UUID;
|
|
|
+import java.util.Vector;
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
|
|
import org.apache.ambari.server.api.services.AmbariMetaInfo;
|
|
@@ -38,6 +41,7 @@ import org.apache.ambari.server.notifications.DispatchFactory;
|
|
|
import org.apache.ambari.server.notifications.Notification;
|
|
|
import org.apache.ambari.server.notifications.NotificationDispatcher;
|
|
|
import org.apache.ambari.server.notifications.TargetConfigurationResult;
|
|
|
+import org.apache.ambari.server.notifications.dispatchers.AmbariSNMPDispatcher;
|
|
|
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
|
|
|
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
|
|
|
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
|
|
@@ -48,10 +52,24 @@ import org.apache.ambari.server.state.AlertState;
|
|
|
import org.apache.ambari.server.state.NotificationState;
|
|
|
import org.apache.ambari.server.state.alert.Scope;
|
|
|
import org.apache.ambari.server.state.alert.SourceType;
|
|
|
+import org.apache.ambari.server.state.alert.TargetType;
|
|
|
import org.easymock.EasyMock;
|
|
|
import org.junit.Assert;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
+import org.snmp4j.CommandResponder;
|
|
|
+import org.snmp4j.CommandResponderEvent;
|
|
|
+import org.snmp4j.PDU;
|
|
|
+import org.snmp4j.Snmp;
|
|
|
+import org.snmp4j.TransportMapping;
|
|
|
+import org.snmp4j.mp.SnmpConstants;
|
|
|
+import org.snmp4j.smi.Address;
|
|
|
+import org.snmp4j.smi.GenericAddress;
|
|
|
+import org.snmp4j.smi.Integer32;
|
|
|
+import org.snmp4j.smi.OID;
|
|
|
+import org.snmp4j.smi.OctetString;
|
|
|
+import org.snmp4j.smi.VariableBinding;
|
|
|
+import org.snmp4j.transport.DefaultUdpTransportMapping;
|
|
|
|
|
|
import com.google.inject.Binder;
|
|
|
import com.google.inject.Guice;
|
|
@@ -240,10 +258,10 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
* @throws Exception
|
|
|
*/
|
|
|
@Test
|
|
|
- public void testSingleDispatch() throws Exception {
|
|
|
+ public void testSingleSnmpDispatch() throws Exception {
|
|
|
MockSnmpDispatcher dispatcher = new MockSnmpDispatcher();
|
|
|
|
|
|
- List<AlertNoticeEntity> notices = getSnmpMockNotices();
|
|
|
+ List<AlertNoticeEntity> notices = getSnmpMockNotices("SNMP");
|
|
|
AlertNoticeEntity notice1 = notices.get(0);
|
|
|
AlertNoticeEntity notice2 = notices.get(1);
|
|
|
|
|
@@ -268,6 +286,105 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
assertEquals(2, notifications.size());
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Tests a digest dispatch for Ambari SNMP.
|
|
|
+ *
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testAmbariSnmpSingleDispatch() throws Exception {
|
|
|
+ MockAmbariSnmpDispatcher dispatcher = new MockAmbariSnmpDispatcher();
|
|
|
+
|
|
|
+ List<AlertNoticeEntity> notices = getSnmpMockNotices("AMBARI_SNMP");
|
|
|
+ AlertNoticeEntity notice1 = notices.get(0);
|
|
|
+ AlertNoticeEntity notice2 = notices.get(1);
|
|
|
+
|
|
|
+ EasyMock.expect(m_dao.findPendingNotices()).andReturn(notices).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice1)).andReturn(notice1).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice2)).andReturn(notice2).once();
|
|
|
+ EasyMock.expect(m_dispatchFactory.getDispatcher("AMBARI_SNMP")).andReturn(dispatcher).atLeastOnce();
|
|
|
+
|
|
|
+ EasyMock.replay(m_dao, m_dispatchFactory);
|
|
|
+
|
|
|
+ // "startup" the service so that its initialization is done
|
|
|
+ AlertNoticeDispatchService service = m_injector.getInstance(AlertNoticeDispatchService.class);
|
|
|
+ service.startUp();
|
|
|
+
|
|
|
+ // service trigger with mock executor that blocks
|
|
|
+ service.setExecutor(new MockExecutor());
|
|
|
+ service.runOneIteration();
|
|
|
+
|
|
|
+ EasyMock.verify(m_dao, m_dispatchFactory);
|
|
|
+
|
|
|
+ List<Notification> notifications = dispatcher.getNotifications();
|
|
|
+ assertEquals(2, notifications.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Tests a real dispatch for Ambari SNMP.
|
|
|
+ *
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testAmbariSnmpRealDispatch() throws Exception {
|
|
|
+ AmbariSNMPDispatcher dispatcher = new AmbariSNMPDispatcher(8081);
|
|
|
+
|
|
|
+ List<AlertNoticeEntity> notices = getSnmpMockNotices("AMBARI_SNMP");
|
|
|
+ AlertNoticeEntity notice1 = notices.get(0);
|
|
|
+ AlertNoticeEntity notice2 = notices.get(1);
|
|
|
+
|
|
|
+ EasyMock.expect(m_dao.findPendingNotices()).andReturn(notices).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice1)).andReturn(notice1).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice2)).andReturn(notice2).once();
|
|
|
+ EasyMock.expect(m_dispatchFactory.getDispatcher("AMBARI_SNMP")).andReturn(dispatcher).once();
|
|
|
+ EasyMock.expect(m_dao.findNoticeByUuid(ALERT_NOTICE_UUID_1)).andReturn(notice1).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice1)).andReturn(notice1).once();
|
|
|
+ EasyMock.expect(m_dao.findNoticeByUuid(ALERT_NOTICE_UUID_2)).andReturn(notice2).once();
|
|
|
+ EasyMock.expect(m_dao.merge(notice2)).andReturn(notice2).once();
|
|
|
+ EasyMock.replay(m_dao, m_dispatchFactory);
|
|
|
+
|
|
|
+ // "startup" the service so that its initialization is done
|
|
|
+ AlertNoticeDispatchService service = m_injector.getInstance(AlertNoticeDispatchService.class);
|
|
|
+ service.startUp();
|
|
|
+
|
|
|
+ // service trigger with mock executor that blocks
|
|
|
+ service.setExecutor(new MockExecutor());
|
|
|
+ SnmpReceiver snmpReceiver = new SnmpReceiver();
|
|
|
+
|
|
|
+ service.runOneIteration();
|
|
|
+ Thread.sleep(1000);
|
|
|
+
|
|
|
+ EasyMock.verify(m_dao, m_dispatchFactory);
|
|
|
+
|
|
|
+ List<Vector> expectedTrapVectors = new LinkedList<>();
|
|
|
+ Vector firstVector = new Vector();
|
|
|
+ firstVector.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(AmbariSNMPDispatcher.AMBARI_ALERT_TRAP_OID)));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_ID_OID), new Integer32(new BigDecimal(1L).intValueExact())));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_NAME_OID), new OctetString("alert-definition-1")));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_DEFINITION_HASH_OID), new OctetString("1")));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_NAME_OID), new OctetString("Alert Definition 1")));
|
|
|
+
|
|
|
+ Vector secondVector = new Vector(firstVector);
|
|
|
+
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_TEXT_OID), new OctetString(ALERT_UNIQUE_TEXT)));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_STATE_OID), new Integer32(0)));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_HOST_NAME_OID), new OctetString("null")));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_SERVICE_NAME_OID), new OctetString("HDFS")));
|
|
|
+ firstVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_COMPONENT_NAME_OID), new OctetString("null")));
|
|
|
+
|
|
|
+ secondVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_TEXT_OID), new OctetString(ALERT_UNIQUE_TEXT + " CRITICAL")));
|
|
|
+ secondVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_STATE_OID), new Integer32(3)));
|
|
|
+ secondVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_HOST_NAME_OID), new OctetString("null")));
|
|
|
+ secondVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_SERVICE_NAME_OID), new OctetString("HDFS")));
|
|
|
+ secondVector.add(new VariableBinding(new OID(AmbariSNMPDispatcher.AMBARI_ALERT_COMPONENT_NAME_OID), new OctetString("null")));
|
|
|
+
|
|
|
+ expectedTrapVectors.add(firstVector);
|
|
|
+ expectedTrapVectors.add(secondVector);
|
|
|
+ assertNotNull(snmpReceiver.receivedTrapsVectors);
|
|
|
+ assertTrue(snmpReceiver.receivedTrapsVectors.size() == 2);
|
|
|
+ assertEquals(expectedTrapVectors, snmpReceiver.receivedTrapsVectors);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Tests that a failed dispatch invokes the callback to mark the UUIDs of the
|
|
|
* notices as FAILED.
|
|
@@ -384,11 +501,11 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Gets 2 PENDING notices for SNMP.
|
|
|
+ * Gets 2 PENDING notices for SNMP or AMBARI_SNMP notificationType.
|
|
|
*
|
|
|
* @return
|
|
|
*/
|
|
|
- private List<AlertNoticeEntity> getSnmpMockNotices() {
|
|
|
+ private List<AlertNoticeEntity> getSnmpMockNotices(String notificationType) {
|
|
|
AlertDefinitionEntity definition = new AlertDefinitionEntity();
|
|
|
definition.setDefinitionId(1L);
|
|
|
definition.setDefinitionName("alert-definition-1");
|
|
@@ -417,9 +534,10 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
target.setAlertStates(EnumSet.allOf(AlertState.class));
|
|
|
target.setTargetName("Alert Target");
|
|
|
target.setDescription("Mock Target");
|
|
|
- target.setNotificationType("SNMP");
|
|
|
+ target.setNotificationType(notificationType);
|
|
|
|
|
|
- String properties = "{ \"foo\" : \"bar\" }";
|
|
|
+ String properties = "{ \"ambari.dispatch.snmp.version\": \"SNMPv1\", \"ambari.dispatch.snmp.port\": \"8000\"," +
|
|
|
+ " \"ambari.dispatch.recipients\": [\"127.0.0.1\"],\"ambari.dispatch.snmp.community\":\"\" }";
|
|
|
target.setProperties(properties);
|
|
|
|
|
|
AlertNoticeEntity notice1 = new AlertNoticeEntity();
|
|
@@ -493,7 +611,7 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
/**
|
|
|
* A mock dispatcher that captures the {@link Notification}.
|
|
|
*/
|
|
|
- private static final class MockSnmpDispatcher implements
|
|
|
+ private static class MockSnmpDispatcher implements
|
|
|
NotificationDispatcher {
|
|
|
|
|
|
private List<Notification> m_notifications = new ArrayList<Notification>();
|
|
@@ -541,6 +659,11 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static final class MockAmbariSnmpDispatcher extends MockSnmpDispatcher {
|
|
|
+ @Override
|
|
|
+ public String getType() { return TargetType.AMBARI_SNMP.name();}
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* A mock dispatcher that captures the {@link Notification}.
|
|
|
*/
|
|
@@ -624,4 +747,26 @@ public class AlertNoticeDispatchServiceTest extends AlertNoticeDispatchService {
|
|
|
EasyMock.replay(m_metaInfo);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private class SnmpReceiver {
|
|
|
+ private Snmp snmp = null;
|
|
|
+ private Address targetAddress = GenericAddress.parse("udp:127.0.0.1/8000");
|
|
|
+ private TransportMapping transport = null;
|
|
|
+ public List<Vector> receivedTrapsVectors = null;
|
|
|
+ public SnmpReceiver() throws Exception{
|
|
|
+ transport = new DefaultUdpTransportMapping();
|
|
|
+ snmp = new Snmp(transport);
|
|
|
+ receivedTrapsVectors = new LinkedList<>();
|
|
|
+
|
|
|
+ CommandResponder trapPrinter = new CommandResponder() {
|
|
|
+ public synchronized void processPdu(CommandResponderEvent e){
|
|
|
+ PDU command = e.getPDU();
|
|
|
+ if (command != null) {
|
|
|
+ receivedTrapsVectors.add(command.getVariableBindings());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ snmp.addNotificationListener(targetAddress, trapPrinter);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|