This is an automated email from the ASF dual-hosted git repository. swagle 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 604c82e [AMBARI-23057] Upgrade fails because of Stale alert definitions (ap… (#2884) 604c82e is described below commit 604c82e3cd49e71643a870dd9ca77576cc2268c9 Author: amarnathreddy pappu <apa...@hortonworks.com> AuthorDate: Wed Apr 3 10:51:08 2019 -0700 [AMBARI-23057] Upgrade fails because of Stale alert definitions (ap… (#2884) --- .../checks/DatabaseConsistencyCheckHelper.java | 105 ++++++++++++++++++++- .../checks/DatabaseConsistencyCheckHelperTest.java | 49 ++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) 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 7f52b66..3d8b4e9 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; @@ -91,6 +93,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; @@ -158,6 +161,7 @@ public class DatabaseConsistencyCheckHelper { closeConnection(); connection = null; metainfoDAO = null; + alertDefinitionDAO = null; ambariMetaInfo = null; dbAccessor = null; } @@ -189,6 +193,7 @@ public class DatabaseConsistencyCheckHelper { fixConfigGroupHostMappings(); fixConfigGroupsForDeletedServices(); fixConfigsSelectedMoreThanOnce(); + fixAlertsForDeletedServices(); } checkSchemaName(); checkMySQLEngine(); @@ -201,6 +206,7 @@ public class DatabaseConsistencyCheckHelper { checkConfigGroupsHasServiceName(); checkConfigGroupHostMapping(true); checkConfigGroupsForDeletedServices(true); + checkForStalealertdefs(); LOG.info("******************************* Check database completed *******************************"); return checkResult; } @@ -216,7 +222,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; @@ -807,6 +815,52 @@ 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 */ @@ -1350,6 +1404,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()); + + } /** * Fix inconsistencies found by @checkConfigGroupHostMapping */ 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 bddff1a..aa89e4d 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 @@ -66,6 +66,7 @@ import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceFactory; import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackId; +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; @@ -689,6 +690,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();