This is an automated email from the ASF dual-hosted git repository. mpapirkovskyy pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 6d413e3 AMBARI-23862. STOMP alert update was not sent when maintenance mode changed. (#1289) 6d413e3 is described below commit 6d413e39ca4ab43f48feba785f08c1638b847b62 Author: Myroslav Papirkovskyi <mpapirkovs...@apache.org> AuthorDate: Thu May 17 15:58:32 2018 +0300 AMBARI-23862. STOMP alert update was not sent when maintenance mode changed. (#1289) * AMBARI-23862. STOMP alert update was not sent when maintenance mode changed. (mpapirkovskyy) * AMBARI-23862. STOMP alert update was not sent when maintenance mode changed. (mpapirkovskyy) --- .../server/agent/stomp/AlertDefinitionsHolder.java | 2 +- .../alerts/AlertMaintenanceModeListener.java | 35 +++++++++--- .../upgrade/AlertMaintenanceModeListenerTest.java | 63 ++++++++++++++++++++-- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java index c20d6a4..703cd82 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AlertDefinitionsHolder.java @@ -125,7 +125,7 @@ public class AlertDefinitionsHolder extends AgentHostDataHolder<AlertDefinitions LOG.info("Unknown clusters in update, perhaps cluster was removed previously"); } for (Map.Entry<Long, AlertCluster> e : updateClusters.entrySet()) { - if (CollectionUtils.isEmpty(e.getValue().getAlertDefinitions())) { + if (update.getEventType().equals(DELETE) && CollectionUtils.isEmpty(e.getValue().getAlertDefinitions())) { existingClusters.remove(e.getKey()); changed = true; } else { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java index f73d7c9..167e8ad 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java @@ -17,14 +17,19 @@ */ package org.apache.ambari.server.events.listeners.alerts; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.ambari.server.EagerSingleton; +import org.apache.ambari.server.api.query.render.AlertSummaryGroupedRenderer; import org.apache.ambari.server.events.AggregateAlertRecalculateEvent; import org.apache.ambari.server.events.AlertEvent; +import org.apache.ambari.server.events.AlertUpdateEvent; import org.apache.ambari.server.events.MaintenanceModeEvent; import org.apache.ambari.server.events.publishers.AlertEventPublisher; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; +import org.apache.ambari.server.events.publishers.STOMPUpdatePublisher; import org.apache.ambari.server.orm.dao.AlertsDAO; import org.apache.ambari.server.orm.entities.AlertCurrentEntity; import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; @@ -74,6 +79,9 @@ public class AlertMaintenanceModeListener { @Inject private AggregateDefinitionMapping m_aggregateMapping; + @Inject + private STOMPUpdatePublisher STOMPUpdatePublisher; + private long clusterId = -1; /** @@ -107,7 +115,7 @@ public class AlertMaintenanceModeListener { if (event.getMaintenanceState() != MaintenanceState.OFF) { newMaintenanceState = MaintenanceState.ON; } - + Map<Long, Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary>> alertUpdates = new HashMap<>(); for( AlertCurrentEntity currentAlert : currentAlerts ){ AlertHistoryEntity history = currentAlert.getAlertHistory(); @@ -124,7 +132,7 @@ public class AlertMaintenanceModeListener { if( null != host ){ String hostName = host.getHostName(); if( hostName.equals( alertHostName ) ){ - if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState)) + if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState, alertUpdates)) recalculateAggregateAlert = true; continue; } @@ -132,7 +140,7 @@ public class AlertMaintenanceModeListener { // service level maintenance String serviceName = service.getName(); if( serviceName.equals(alertServiceName)){ - if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState)) + if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState, alertUpdates)) recalculateAggregateAlert = true; continue; } @@ -145,7 +153,7 @@ public class AlertMaintenanceModeListener { // match on all 3 for a service component if (hostName.equals(alertHostName) && serviceName.equals(alertServiceName) && componentName.equals(alertComponentName)) { - if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState)) + if (updateMaintenanceStateAndRecalculateAggregateAlert(history, currentAlert, newMaintenanceState, alertUpdates)) recalculateAggregateAlert = true; continue; } @@ -157,6 +165,10 @@ public class AlertMaintenanceModeListener { } } + if (!alertUpdates.isEmpty()) { + STOMPUpdatePublisher.publish(new AlertUpdateEvent(alertUpdates)); + } + if (recalculateAggregateAlert) { // publish the event to recalculate aggregates m_alertEventPublisher.publish(new AggregateAlertRecalculateEvent(clusterId)); @@ -178,12 +190,14 @@ public class AlertMaintenanceModeListener { * {@link MaintenanceState#OFF} or {@link MaintenanceState#ON}. */ private boolean updateMaintenanceStateAndRecalculateAggregateAlert (AlertHistoryEntity historyAlert, - AlertCurrentEntity currentAlert, MaintenanceState maintenanceState) { + AlertCurrentEntity currentAlert, MaintenanceState maintenanceState, Map<Long, Map<String, + AlertSummaryGroupedRenderer.AlertDefinitionSummary>> alertUpdates) { + AlertDefinitionEntity definitionEntity = currentAlert.getAlertHistory().getAlertDefinition(); // alerts only care about OFF or ON if (maintenanceState != MaintenanceState.OFF && maintenanceState != MaintenanceState.ON) { LOG.warn("Unable to set invalid maintenance state of {} on the alert {}", maintenanceState, - currentAlert.getAlertHistory().getAlertDefinition().getDefinitionName()); + definitionEntity.getDefinitionName()); return false; } @@ -198,6 +212,15 @@ public class AlertMaintenanceModeListener { AlertState alertState = historyAlert.getAlertState(); + if (!alertUpdates.containsKey(historyAlert.getClusterId())) { + alertUpdates.put(historyAlert.getClusterId(), new HashMap<>()); + } + Map<String, AlertSummaryGroupedRenderer.AlertDefinitionSummary> summaries = alertUpdates.get(historyAlert.getClusterId()); + + // alert history doesn't change when MM is turned on/off, so timestamp and text should be empty + AlertSummaryGroupedRenderer.updateSummary(summaries, definitionEntity.getDefinitionId(), + definitionEntity.getDefinitionName(), alertState, -1L, maintenanceState, ""); + if (AlertState.RECALCULATE_AGGREGATE_ALERT_STATES.contains(alertState)){ clusterId = historyAlert.getClusterId(); String alertName = historyAlert.getAlertDefinition().getDefinitionName(); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/AlertMaintenanceModeListenerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/AlertMaintenanceModeListenerTest.java index 33a1565..bedb0e2 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/AlertMaintenanceModeListenerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/AlertMaintenanceModeListenerTest.java @@ -24,13 +24,16 @@ import java.util.List; import javax.persistence.EntityManager; +import org.apache.ambari.server.events.AlertUpdateEvent; import org.apache.ambari.server.events.MaintenanceModeEvent; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; +import org.apache.ambari.server.events.publishers.STOMPUpdatePublisher; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; import org.apache.ambari.server.orm.dao.AlertsDAO; import org.apache.ambari.server.orm.entities.AlertCurrentEntity; +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.Cluster; @@ -40,7 +43,9 @@ import org.apache.ambari.server.state.MaintenanceState; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponentHost; import org.apache.ambari.server.utils.EventBusSynchronizer; +import org.easymock.Capture; import org.easymock.EasyMock; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -59,6 +64,8 @@ public class AlertMaintenanceModeListenerTest { private static final String HOSTNAME = "c6401.ambari.apache.org"; private static final String SERVICE = "HDFS"; private static final String COMPONENT = "NAMENODE"; + private static final Long CLUSTER_ID = 1L; + private static final String DEFINITION_NAME = "definition_name"; @Inject private AmbariEventPublisher m_eventPublisher; @@ -103,12 +110,24 @@ public class AlertMaintenanceModeListenerTest { Host host = EasyMock.createNiceMock(Host.class); EasyMock.expect(host.getHostName()).andReturn(HOSTNAME).atLeastOnce(); - EasyMock.replay(hostAlert, serviceAlert, componentAlert, host, m_alertsDAO); + STOMPUpdatePublisher stompUpdatePublisher = injector.getInstance(STOMPUpdatePublisher.class); + Capture<AlertUpdateEvent> alertUpdateEventCapture = EasyMock.newCapture(); + stompUpdatePublisher.publish(EasyMock.capture(alertUpdateEventCapture)); + + EasyMock.replay(hostAlert, serviceAlert, componentAlert, host, m_alertsDAO, stompUpdatePublisher); MaintenanceModeEvent hostEvent = new MaintenanceModeEvent(MaintenanceState.ON, 1 /* cluster id */, host); m_eventPublisher.publish(hostEvent); EasyMock.verify(hostAlert, serviceAlert, componentAlert, host, m_alertsDAO); + + AlertUpdateEvent alertUpdateEvent = alertUpdateEventCapture.getValue(); + Assert.assertNotNull(alertUpdateEvent); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().containsKey(CLUSTER_ID)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().get(CLUSTER_ID).containsKey(DEFINITION_NAME)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).get(DEFINITION_NAME).State.Ok.MaintenanceCount); } /** @@ -131,12 +150,24 @@ public class AlertMaintenanceModeListenerTest { Service service = EasyMock.createNiceMock(Service.class); EasyMock.expect(service.getName()).andReturn(SERVICE).atLeastOnce(); - EasyMock.replay(hostAlert, serviceAlert, componentAlert, service, m_alertsDAO); + STOMPUpdatePublisher stompUpdatePublisher = injector.getInstance(STOMPUpdatePublisher.class); + Capture<AlertUpdateEvent> alertUpdateEventCapture = EasyMock.newCapture(); + stompUpdatePublisher.publish(EasyMock.capture(alertUpdateEventCapture)); + + EasyMock.replay(hostAlert, serviceAlert, componentAlert, service, m_alertsDAO, stompUpdatePublisher); MaintenanceModeEvent serviceEvent = new MaintenanceModeEvent(MaintenanceState.ON, service); m_eventPublisher.publish(serviceEvent); EasyMock.verify(hostAlert, serviceAlert, componentAlert, service, m_alertsDAO); + + AlertUpdateEvent alertUpdateEvent = alertUpdateEventCapture.getValue(); + Assert.assertNotNull(alertUpdateEvent); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().containsKey(CLUSTER_ID)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().get(CLUSTER_ID).containsKey(DEFINITION_NAME)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).get(DEFINITION_NAME).State.Ok.MaintenanceCount); } @Test @@ -158,7 +189,11 @@ public class AlertMaintenanceModeListenerTest { EasyMock.expect(serviceComponentHost.getServiceName()).andReturn(SERVICE).atLeastOnce(); EasyMock.expect(serviceComponentHost.getServiceComponentName()).andReturn(COMPONENT).atLeastOnce(); - EasyMock.replay(hostAlert, serviceAlert, componentAlert, serviceComponentHost, m_alertsDAO); + STOMPUpdatePublisher stompUpdatePublisher = injector.getInstance(STOMPUpdatePublisher.class); + Capture<AlertUpdateEvent> alertUpdateEventCapture = EasyMock.newCapture(); + stompUpdatePublisher.publish(EasyMock.capture(alertUpdateEventCapture)); + + EasyMock.replay(hostAlert, serviceAlert, componentAlert, serviceComponentHost, m_alertsDAO, stompUpdatePublisher); MaintenanceModeEvent serviceComponentHostEvent = new MaintenanceModeEvent(MaintenanceState.ON, serviceComponentHost); @@ -166,6 +201,14 @@ public class AlertMaintenanceModeListenerTest { m_eventPublisher.publish(serviceComponentHostEvent); EasyMock.verify(hostAlert, serviceAlert, componentAlert, serviceComponentHost, m_alertsDAO); + + AlertUpdateEvent alertUpdateEvent = alertUpdateEventCapture.getValue(); + Assert.assertNotNull(alertUpdateEvent); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().containsKey(CLUSTER_ID)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).size()); + Assert.assertTrue(alertUpdateEvent.getSummaries().get(CLUSTER_ID).containsKey(DEFINITION_NAME)); + Assert.assertEquals(1, alertUpdateEvent.getSummaries().get(CLUSTER_ID).get(DEFINITION_NAME).State.Ok.MaintenanceCount); } private List<AlertCurrentEntity> getMockAlerts(String testType) { @@ -177,6 +220,8 @@ public class AlertMaintenanceModeListenerTest { AlertHistoryEntity serviceHistory = EasyMock.createStrictMock(AlertHistoryEntity.class); AlertHistoryEntity componentHistory = EasyMock.createStrictMock(AlertHistoryEntity.class); + AlertDefinitionEntity alertDefinition = EasyMock.createStrictMock(AlertDefinitionEntity.class); + EasyMock.expect(hostAlert.getAlertHistory()).andReturn(hostHistory).atLeastOnce(); EasyMock.expect(serviceAlert.getAlertHistory()).andReturn(serviceHistory).atLeastOnce(); EasyMock.expect(componentAlert.getAlertHistory()).andReturn(componentHistory).atLeastOnce(); @@ -184,12 +229,19 @@ public class AlertMaintenanceModeListenerTest { EasyMock.expect(hostHistory.getHostName()).andReturn(HOSTNAME).atLeastOnce(); EasyMock.expect(hostHistory.getServiceName()).andReturn(null).atLeastOnce(); EasyMock.expect(hostHistory.getComponentName()).andReturn(null).atLeastOnce(); + EasyMock.expect(hostHistory.getAlertDefinition()).andReturn(alertDefinition).atLeastOnce(); EasyMock.expect(hostHistory.getAlertState()).andReturn(AlertState.OK).atLeastOnce(); + EasyMock.expect(hostHistory.getClusterId()).andReturn(CLUSTER_ID).atLeastOnce(); EasyMock.expect(serviceHistory.getHostName()).andReturn(null).atLeastOnce(); EasyMock.expect(serviceHistory.getServiceName()).andReturn(SERVICE).atLeastOnce(); EasyMock.expect(serviceHistory.getComponentName()).andReturn(null).atLeastOnce(); + EasyMock.expect(serviceHistory.getAlertDefinition()).andReturn(alertDefinition).atLeastOnce(); EasyMock.expect(serviceHistory.getAlertState()).andReturn(AlertState.OK).atLeastOnce(); + EasyMock.expect(serviceHistory.getClusterId()).andReturn(CLUSTER_ID).atLeastOnce(); + + EasyMock.expect(alertDefinition.getDefinitionId()).andReturn(1L).atLeastOnce(); + EasyMock.expect(alertDefinition.getDefinitionName()).andReturn(DEFINITION_NAME).atLeastOnce(); if (testType.equals("SCH")) { EasyMock.expect(componentHistory.getHostName()).andReturn(HOSTNAME).atLeastOnce(); @@ -200,7 +252,9 @@ public class AlertMaintenanceModeListenerTest { EasyMock.expect(componentHistory.getServiceName()).andReturn(null).atLeastOnce(); EasyMock.expect(componentHistory.getComponentName()).andReturn(COMPONENT).atLeastOnce(); } + EasyMock.expect(componentHistory.getAlertDefinition()).andReturn(alertDefinition).atLeastOnce(); EasyMock.expect(componentHistory.getAlertState()).andReturn(AlertState.OK).atLeastOnce(); + EasyMock.expect(componentHistory.getClusterId()).andReturn(CLUSTER_ID).atLeastOnce(); List<AlertCurrentEntity> currentAlerts = new ArrayList<>(); currentAlerts.add(hostAlert); @@ -209,7 +263,7 @@ public class AlertMaintenanceModeListenerTest { EasyMock.expect(m_alertsDAO.findCurrent()).andReturn(currentAlerts).atLeastOnce(); - EasyMock.replay(hostHistory, serviceHistory, componentHistory); + EasyMock.replay(hostHistory, serviceHistory, componentHistory, alertDefinition); return currentAlerts; } @@ -229,6 +283,7 @@ public class AlertMaintenanceModeListenerTest { binder.bind(AlertDefinitionDAO.class).toInstance(createNiceMock(AlertDefinitionDAO.class)); binder.bind(AlertsDAO.class).toInstance(createNiceMock(AlertsDAO.class)); binder.bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class)); + binder.bind(STOMPUpdatePublisher.class).toInstance(createNiceMock(STOMPUpdatePublisher.class)); } } } -- To stop receiving notification emails like this one, please contact mpapirkovs...@apache.org.