This is an automated email from the ASF dual-hosted git repository. swagle pushed a commit to branch branch-2.7 in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-2.7 by this push: new ef51fd9 [AMBARI-23057] Upgrade fails because of Stale alert definitions (apappu) (#2885) ef51fd9 is described below commit ef51fd9e8ec8f7bb90687ff7abb04d233504e191 Author: amarnathreddy pappu <apa...@hortonworks.com> AuthorDate: Wed Apr 3 10:47:25 2019 -0700 [AMBARI-23057] Upgrade fails because of Stale alert definitions (apappu) (#2885) --- .../checks/DatabaseConsistencyCheckHelper.java | 108 ++++++++++++++++++++- .../checks/DatabaseConsistencyCheckHelperTest.java | 49 ++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java index 375bcd9..e2e8b0b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java @@ -48,6 +48,7 @@ import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.orm.DBAccessor; +import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.dao.ExecutionCommandDAO; import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO; @@ -55,6 +56,7 @@ import org.apache.ambari.server.orm.dao.HostComponentStateDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.MetainfoDAO; import org.apache.ambari.server.orm.dao.StageDAO; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; import org.apache.ambari.server.orm.entities.ClusterConfigEntity; import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity; import org.apache.ambari.server.orm.entities.HostComponentStateEntity; @@ -93,6 +95,7 @@ public class DatabaseConsistencyCheckHelper { private static Injector injector; private static MetainfoDAO metainfoDAO; + private static AlertDefinitionDAO alertDefinitionDAO; private static Connection connection; private static AmbariMetaInfo ambariMetaInfo; private static DBAccessor dbAccessor; @@ -160,6 +163,7 @@ public class DatabaseConsistencyCheckHelper { closeConnection(); connection = null; metainfoDAO = null; + alertDefinitionDAO = null; ambariMetaInfo = null; dbAccessor = null; } @@ -191,6 +195,7 @@ public class DatabaseConsistencyCheckHelper { fixConfigGroupHostMappings(); fixConfigGroupsForDeletedServices(); fixConfigsSelectedMoreThanOnce(); + fixAlertsForDeletedServices(); } checkSchemaName(); checkMySQLEngine(); @@ -203,6 +208,7 @@ public class DatabaseConsistencyCheckHelper { checkConfigGroupsHasServiceName(); checkConfigGroupHostMapping(true); checkConfigGroupsForDeletedServices(true); + checkForStalealertdefs(); LOG.info("******************************* Check database completed *******************************"); return checkResult; } @@ -218,7 +224,9 @@ public class DatabaseConsistencyCheckHelper { if (metainfoDAO == null) { metainfoDAO = injector.getInstance(MetainfoDAO.class); } - + if (alertDefinitionDAO == null) { + alertDefinitionDAO = injector.getInstance(AlertDefinitionDAO.class); + } MetainfoEntity schemaVersionEntity = metainfoDAO.findByKey(Configuration.SERVER_VERSION_KEY); String schemaVersion = null; @@ -810,7 +818,54 @@ public class DatabaseConsistencyCheckHelper { } } - /** + + /** + * This method checks for stale alert definitions.. + * */ + static Map<String, String> checkForStalealertdefs () { + Configuration conf = injector.getInstance(Configuration.class); + Map<String, String> alertInfo = new HashMap<>(); + LOG.info("Checking to ensure there is no stale alert definitions"); + + ensureConnection(); + + String STALE_ALERT_DEFINITIONS = "select definition_name, service_name from alert_definition where service_name not in " + + "(select service_name from clusterservices) and service_name not in ('AMBARI')"; + + ResultSet rs = null; + Statement statement; + + try { + statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + rs = statement.executeQuery(STALE_ALERT_DEFINITIONS); + if (rs != null) { + while (rs.next()) { + alertInfo.put(rs.getString("definition_name"),rs.getString("service_name")); + } + if (!alertInfo.isEmpty()){ + String alertInfoStr = ""; + for (Map.Entry<String, String> entry : alertInfo.entrySet()) { + alertInfoStr = entry.getKey() + "(" + entry.getValue() + ")" ; + } + warning("You have Alerts that are not mapped with any services : {}.Run --auto-fix-database to fix " + + "this automatically. Please backup Ambari Server database before running --auto-fix-database.", alertInfoStr); + } + } + } catch (SQLException e) { + warning("Exception occurred during checking for stale alert definitions: ", e); + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("Exception occurred during checking for stale alert definitions: ", e); + } + } + } + return alertInfo; + } + + /** * Fix inconsistencies found by {@code checkForConfigsSelectedMoreThanOnce} * selecting latest one by selectedTimestamp */ @@ -1234,6 +1289,55 @@ public class DatabaseConsistencyCheckHelper { } } + @Transactional + static void fixAlertsForDeletedServices() { + + Configuration conf = injector.getInstance(Configuration.class); + + LOG.info("fixAlertsForDeletedServices stale alert definitions for deleted services"); + + ensureConnection(); + + String SELECT_STALE_ALERT_DEFINITIONS = "select definition_id from alert_definition where service_name not in " + + "(select service_name from clusterservices) and service_name not in ('AMBARI')"; + + int recordsCount = 0; + Statement statement = null; + ResultSet rs = null; + List<Integer> alertIds = new ArrayList<Integer>(); + try { + statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + rs = statement.executeQuery(SELECT_STALE_ALERT_DEFINITIONS); + while (rs.next()) { + alertIds.add(rs.getInt("definition_id")); + } + + } catch (SQLException e) { + warning("Exception occurred during fixing stale alert definitions: ", e); + } finally { + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + LOG.error("Exception occurred during fixing stale alert definitions: ", e); + } + } + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("Exception occurred during fixing stale alert definitions: ", e); + } + } + } + + for(Integer alertId : alertIds) { + final AlertDefinitionEntity entity = alertDefinitionDAO.findById(alertId.intValue()); + alertDefinitionDAO.remove(entity); + } + warning("fixAlertsForDeletedServices - {} Stale alerts were deleted", alertIds.size()); + + } /** * This method checks if there are any ConfigGroup host mappings with hosts * that are not longer a part of the cluster. diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java index 2817661..c99c968 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelperTest.java @@ -56,6 +56,7 @@ import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceInfo; +import org.apache.ambari.server.state.alert.AlertDefinition; import org.apache.ambari.server.state.configgroup.ConfigGroup; import org.apache.ambari.server.state.stack.OsFamily; import org.apache.ambari.server.testutils.PartialNiceMockBinder; @@ -669,6 +670,54 @@ public class DatabaseConsistencyCheckHelperTest { } @Test + public void testCheckForStalealertdefs() throws Exception { + EasyMockSupport easyMockSupport = new EasyMockSupport(); + final AlertDefinition alertDefinition = easyMockSupport.createNiceMock(AlertDefinition.class); + final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class); + final StackManagerFactory mockStackManagerFactory = easyMockSupport.createNiceMock(StackManagerFactory.class); + final EntityManager mockEntityManager = easyMockSupport.createNiceMock(EntityManager.class); + final Clusters mockClusters = easyMockSupport.createNiceMock(Clusters.class); + final OsFamily mockOSFamily = easyMockSupport.createNiceMock(OsFamily.class); + + final Injector mockInjector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(AlertDefinition.class).toInstance(alertDefinition); + bind(StackManagerFactory.class).toInstance(mockStackManagerFactory); + bind(EntityManager.class).toInstance(mockEntityManager); + bind(DBAccessor.class).toInstance(mockDBDbAccessor); + bind(Clusters.class).toInstance(mockClusters); + bind(OsFamily.class).toInstance(mockOSFamily); + } + }); + final ResultSet staleAlertResultSet = easyMockSupport.createNiceMock(ResultSet.class); + expect(staleAlertResultSet.next()).andReturn(true).once(); + expect(staleAlertResultSet.getString("definition_name")).andReturn("ALERT-NAME").atLeastOnce(); + expect(staleAlertResultSet.getString("service_name")).andReturn("SERVICE-DELETED").atLeastOnce(); + final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class); + final Statement mockStatement = easyMockSupport.createNiceMock(Statement.class); + + expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection); + expect(mockDBDbAccessor.getDbType()).andReturn(DBAccessor.DbType.MYSQL); + expect(mockDBDbAccessor.getDbSchema()).andReturn("test_schema"); + + expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement).anyTimes(); + expect(mockStatement.executeQuery("select definition_name, service_name from alert_definition where service_name not in " + + "(select service_name from clusterservices) and service_name not in ('AMBARI')")).andReturn(staleAlertResultSet); + + expect(alertDefinition.getDefinitionId()).andReturn(1L); + expect(alertDefinition.getName()).andReturn("AlertTest"); + + DatabaseConsistencyCheckHelper.setInjector(mockInjector); + + easyMockSupport.replayAll(); + + Map<String, String> stalealertdefs1 = DatabaseConsistencyCheckHelper.checkForStalealertdefs(); + + Assert.assertEquals(1, stalealertdefs1.size()); + } + + @Test public void testCollectConfigGroupsWithoutServiceName() throws Exception { EasyMockSupport easyMockSupport = new EasyMockSupport();