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 638DA200BD9 for ; Fri, 9 Dec 2016 15:47:14 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 6201A160B1C; Fri, 9 Dec 2016 14:47:14 +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 1006D160B04 for ; Fri, 9 Dec 2016 15:47:12 +0100 (CET) Received: (qmail 85091 invoked by uid 500); 9 Dec 2016 14:47:12 -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 85081 invoked by uid 99); 9 Dec 2016 14:47:12 -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; Fri, 09 Dec 2016 14:47:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E6948E040F; Fri, 9 Dec 2016 14:47:11 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: dmitriusan@apache.org To: commits@ambari.apache.org Message-Id: <5751ca4f9c0b47f5b8eb2e21d90f75ba@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-18990. Auto-fix common issues found by the DB consistency checker (dlysnichenko) Date: Fri, 9 Dec 2016 14:47:11 +0000 (UTC) archived-at: Fri, 09 Dec 2016 14:47:14 -0000 Repository: ambari Updated Branches: refs/heads/trunk 66c6d5607 -> a8222ae3b AMBARI-18990. Auto-fix common issues found by the DB consistency checker (dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a8222ae3 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a8222ae3 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a8222ae3 Branch: refs/heads/trunk Commit: a8222ae3b8dd909764f90083396045c4db7dcceb Parents: 66c6d56 Author: Lisnichenko Dmitro Authored: Fri Dec 9 16:43:20 2016 +0200 Committer: Lisnichenko Dmitro Committed: Fri Dec 9 16:43:20 2016 +0200 ---------------------------------------------------------------------- .../checks/DatabaseConsistencyCheckHelper.java | 245 ++++++++++++++++++- .../checks/DatabaseConsistencyChecker.java | 1 + .../ambari/server/controller/AmbariServer.java | 3 + .../orm/entities/ClusterConfigEntity.java | 17 ++ ambari-server/src/main/python/ambari-server.py | 2 + .../src/main/python/ambari_server_main.py | 3 + .../server/controller/AmbariServerTest.java | 26 ++ 7 files changed, 293 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java ---------------------------------------------------------------------- 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 89ed987..3e4d63c 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 @@ -20,23 +20,40 @@ package org.apache.ambari.server.checks; import java.io.File; import java.io.IOException; import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; +import javax.inject.Provider; +import javax.persistence.EntityManager; +import javax.persistence.Query; + 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.ClusterDAO; +import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO; +import org.apache.ambari.server.orm.dao.HostComponentStateDAO; import org.apache.ambari.server.orm.dao.MetainfoDAO; +import org.apache.ambari.server.orm.entities.ClusterConfigEntity; +import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity; +import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.MetainfoEntity; +import org.apache.ambari.server.state.SecurityState; import org.apache.ambari.server.state.ServiceInfo; +import org.apache.ambari.server.state.State; +import org.apache.ambari.server.state.UpgradeState; import org.apache.ambari.server.utils.VersionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -46,6 +63,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.inject.Inject; import com.google.inject.Injector; +import com.google.inject.persist.Transactional; public class DatabaseConsistencyCheckHelper { @@ -103,8 +121,17 @@ public class DatabaseConsistencyCheckHelper { } } + + public static void fixDatabaseConsistency() { + fixHostComponentStatesCountEqualsHostComponentsDesiredStates(); + fixClusterConfigsNotMappedToAnyService(); + } + public static void runAllDBChecks() { LOG.info("******************************* Check database started *******************************"); + checkSchemaName(); + checkMySQLEngine(); + checkForConfigsNotMappedToService(); checkForNotMappedConfigsToCluster(); checkForConfigsSelectedMoreThanOnce(); checkForHostsWithoutState(); @@ -200,7 +227,7 @@ public class DatabaseConsistencyCheckHelper { } } - /* + /** * This method checks if any config type in clusterconfigmapping table, has * more than one versions selected. If config version is selected(in selected column = 1), * it means that this version of config is actual. So, if any config type has more @@ -260,7 +287,7 @@ public class DatabaseConsistencyCheckHelper { } } - /* + /** * This method checks if all hosts from hosts table * has related host state info in hoststate table. * If not then we are showing error. @@ -315,7 +342,7 @@ public class DatabaseConsistencyCheckHelper { } } - /* + /** * This method checks if count of host component states equals count * of desired host component states. According to ambari logic these * two tables should have the same count of rows. If not then we are @@ -410,8 +437,218 @@ public class DatabaseConsistencyCheckHelper { } + /** + * Remove configs that are not mapped to any service. + */ + @Transactional + public static void fixClusterConfigsNotMappedToAnyService() { + LOG.info("Checking for configs not mapped to any Service"); + ClusterDAO clusterDAO = injector.getInstance(ClusterDAO.class); + List notMappedClusterConfigs = getNotMappedClusterConfigsToService(); + + for (ClusterConfigEntity clusterConfigEntity : notMappedClusterConfigs){ + List types = new ArrayList<>(); + String type = clusterConfigEntity.getType(); + types.add(type); + LOG.error("Removing cluster config mapping of type {} that is not mapped to any service", type); + clusterDAO.removeClusterConfigMappingEntityByTypes(clusterConfigEntity.getClusterId(),types); + LOG.error("Removing config that is not mapped to any service", clusterConfigEntity); + clusterDAO.removeConfig(clusterConfigEntity); + } + } - /* + + /** + * Find ClusterConfigs that are not mapped to Service + * @return ClusterConfigs that are not mapped to Service + */ + private static List getNotMappedClusterConfigsToService() { + Provider entityManagerProvider = injector.getProvider(EntityManager.class); + EntityManager entityManager = entityManagerProvider.get(); + + Query query = entityManager.createNamedQuery("ClusterConfigEntity.findNotMappedClusterConfigsToService",ClusterConfigEntity.class); + + return (List) query.getResultList(); + } + + /** + * Look for configs that are not mapped to any service. + */ + public static void checkForConfigsNotMappedToService() { + LOG.info("Checking for configs that are not mapped to any service"); + List notMappedClasterConfigs = getNotMappedClusterConfigsToService(); + + if (!notMappedClasterConfigs.isEmpty()){ + LOG.error("Found configs that are not mapped to any service!"); + errorsFound = true; + } + } + + /** + * This method checks if count of host component states equals count + * of desired host component states. According to ambari logic these + * two tables should have the same count of rows. If not then we are + * adding missed host components. + */ + @Transactional + public static void fixHostComponentStatesCountEqualsHostComponentsDesiredStates() { + LOG.info("Checking that there are the same number of actual and desired host components"); + + HostComponentStateDAO hostComponentStateDAO = injector.getInstance(HostComponentStateDAO.class); + HostComponentDesiredStateDAO hostComponentDesiredStateDAO = injector.getInstance(HostComponentDesiredStateDAO.class); + + List hostComponentDesiredStates = hostComponentDesiredStateDAO.findAll(); + List hostComponentStates = hostComponentStateDAO.findAll(); + + Set missedHostComponentDesiredStates = new HashSet<>(); + missedHostComponentDesiredStates.addAll(hostComponentDesiredStates); + Set missedHostComponentStates = new HashSet<>(); + missedHostComponentStates.addAll(hostComponentStates); + + for (Iterator stateIterator = missedHostComponentStates.iterator(); stateIterator.hasNext();){ + HostComponentStateEntity hostComponentStateEntity = stateIterator.next(); + for (Iterator desiredStateIterator = missedHostComponentDesiredStates.iterator(); desiredStateIterator.hasNext();) { + HostComponentDesiredStateEntity hostComponentDesiredStateEntity = desiredStateIterator.next(); + if (hostComponentStateEntity.getComponentName().equals(hostComponentDesiredStateEntity.getComponentName()) && + hostComponentStateEntity.getServiceName().equals(hostComponentDesiredStateEntity.getServiceName()) && + hostComponentStateEntity.getHostId().equals(hostComponentDesiredStateEntity.getHostId())){ + desiredStateIterator.remove(); + stateIterator.remove(); + break; + } + } + } + + for (HostComponentDesiredStateEntity hostComponentDesiredStateEntity : missedHostComponentDesiredStates) { + HostComponentStateEntity stateEntity = new HostComponentStateEntity(); + stateEntity.setClusterId(hostComponentDesiredStateEntity.getClusterId()); + stateEntity.setComponentName(hostComponentDesiredStateEntity.getComponentName()); + stateEntity.setServiceName(hostComponentDesiredStateEntity.getServiceName()); + stateEntity.setVersion(State.UNKNOWN.toString()); + stateEntity.setHostEntity(hostComponentDesiredStateEntity.getHostEntity()); + stateEntity.setCurrentState(State.UNKNOWN); + stateEntity.setUpgradeState(UpgradeState.NONE); + stateEntity.setCurrentStack(hostComponentDesiredStateEntity.getDesiredStack()); + stateEntity.setSecurityState(SecurityState.UNKNOWN); + stateEntity.setServiceComponentDesiredStateEntity(hostComponentDesiredStateEntity.getServiceComponentDesiredStateEntity()); + + LOG.error("Trying to add missing record in hostcomponentstate: {}", stateEntity); + hostComponentStateDAO.create(stateEntity); + } + + for (HostComponentStateEntity missedHostComponentState : missedHostComponentStates) { + + HostComponentDesiredStateEntity stateEntity = new HostComponentDesiredStateEntity(); + stateEntity.setClusterId(missedHostComponentState.getClusterId()); + stateEntity.setComponentName(missedHostComponentState.getComponentName()); + stateEntity.setServiceName(missedHostComponentState.getServiceName()); + stateEntity.setHostEntity(missedHostComponentState.getHostEntity()); + stateEntity.setDesiredState(State.UNKNOWN); + stateEntity.setDesiredStack(missedHostComponentState.getCurrentStack()); + stateEntity.setServiceComponentDesiredStateEntity(missedHostComponentState.getServiceComponentDesiredStateEntity()); + + LOG.error("Trying to add missing record in hostcomponentdesiredstate: {}", stateEntity); + hostComponentDesiredStateDAO.create(stateEntity); + } + } + + /** + * This method checks db schema name for Postgres. + * */ + public static void checkSchemaName () { + Configuration conf = injector.getInstance(Configuration.class); + if(conf.getDatabaseType()!=Configuration.DatabaseType.POSTGRES) { + return; + } + LOG.info("Ensuring that the schema set for Postgres is correct"); + if (connection == null) { + if (dbAccessor == null) { + dbAccessor = injector.getInstance(DBAccessor.class); + } + connection = dbAccessor.getConnection(); + } + ResultSet rs = null; + try { + DatabaseMetaData databaseMetaData = connection.getMetaData(); + + rs = databaseMetaData.getSchemas(); + + boolean ambariSchemaPresent = false; + if (rs != null) { + while (rs.next()) { + if(StringUtils.equals(rs.getString("TABLE_SCHEM"),conf.getDatabaseSchema())){ + ambariSchemaPresent = true; + break; + } + } + } + if (!ambariSchemaPresent){ + LOG.error("The schema %s defined for Ambari from ambari.properties has not been found in the database. " + + "This means that the Ambari tables are stored under the public schema which can lead to problems.", conf.getDatabaseSchema()); + warningsFound = true; + } + + } catch (SQLException e) { + LOG.error("Exception occurred during checking db schema name.: ", e); + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("Exception occurred during result set closing procedure: ", e); + } + } + } + } + + /** + * This method checks tables engine type to be innodb for MySQL. + * */ + public static void checkMySQLEngine () { + Configuration conf = injector.getInstance(Configuration.class); + if(conf.getDatabaseType()!=Configuration.DatabaseType.MYSQL) { + return; + } + LOG.info("Checking to ensure that the MySQL DB engine type is set to InnoDB"); + if (connection == null) { + if (dbAccessor == null) { + dbAccessor = injector.getInstance(DBAccessor.class); + } + connection = dbAccessor.getConnection(); + } + + String GET_INNODB_ENGINE_SUPPORT = "select TABLE_NAME, ENGINE from information_schema.tables where TABLE_SCHEMA = '%s' and LOWER(ENGINE) != 'innodb';"; + + ResultSet rs = null; + Statement statement; + + try { + statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + rs = statement.executeQuery(String.format(GET_INNODB_ENGINE_SUPPORT, conf.getDatabaseSchema())); + if (rs != null) { + List tablesInfo = new ArrayList<>(); + while (rs.next()) { + errorsFound = true; + tablesInfo.add(rs.getString("TABLE_NAME")); + } + if (!tablesInfo.isEmpty()){ + LOG.error("Found tables with engine type that is not InnoDB : %s", StringUtils.join(tablesInfo, ',')); + } + } + } catch (SQLException e) { + LOG.error("Exception occurred during checking MySQL engine to be innodb: ", e); + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + LOG.error("Exception occurred during result set closing procedure: ", e); + } + } + } + } + + /** * This method checks several potential problems for services: * 1) Check if we have services in cluster which doesn't have service config id(not available in serviceconfig table). * 2) Check if service has no mapped configs to it's service config id. http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java index d2b7c52..2aaaadd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java @@ -137,6 +137,7 @@ public class DatabaseConsistencyChecker { if (DatabaseConsistencyCheckHelper.ifErrorsFound()) { System.out.print(String.format("DB configs consistency check failed. Run \"ambari-server start --skip-database-check\" to skip. " + + "You may try --auto-fix-database flag to attempt to fix issues automatically. " + "If you use this \"--skip-database-check\" option, do not make any changes to your cluster topology " + "or perform a cluster upgrade until you correct the database consistency issues. See \"%s\" " + "for more details on the consistency issues.", ambariDBConsistencyCheckLog)); http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java index 16fe58a..fccf9a8 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java @@ -682,6 +682,9 @@ public class AmbariServer { System.out.println("Database consistency check started"); Logger DB_CHECK_LOG = LoggerFactory.getLogger(DatabaseConsistencyCheckHelper.class); try{ + if (System.getProperty("fixDatabaseConsistency") != null ){ + DatabaseConsistencyCheckHelper.fixDatabaseConsistency(); + } DatabaseConsistencyCheckHelper.runAllDBChecks(); } catch(Throwable e) { System.out.println("Database consistency check: failed"); http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java index 937e872..f96db60 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.orm.entities; +import com.google.common.base.Objects; + import java.util.Collection; import javax.persistence.Basic; @@ -52,6 +54,7 @@ import javax.persistence.UniqueConstraint; @NamedQuery(name = "ClusterConfigEntity.findNextConfigVersion", query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId"), @NamedQuery(name = "ClusterConfigEntity.findAllConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.stack=:stack"), @NamedQuery(name = "ClusterConfigEntity.findLatestConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.timestamp = (SELECT MAX(clusterConfig2.timestamp) FROM ClusterConfigEntity clusterConfig2 WHERE clusterConfig2.clusterId=:clusterId AND clusterConfig2.stack=:stack AND clusterConfig2.type = clusterConfig.type)"), + @NamedQuery(name = "ClusterConfigEntity.findNotMappedClusterConfigsToService", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.serviceConfigEntities IS EMPTY AND clusterConfig.type != 'cluster-env'"), @NamedQuery(name = "ClusterConfigEntity.findClusterConfigMappingsByStack", query = "SELECT mapping FROM ClusterConfigMappingEntity mapping " + "JOIN ClusterConfigEntity config ON mapping.typeName = config.type AND mapping.tag = config.tag " + @@ -266,4 +269,18 @@ public class ClusterConfigEntity { public void setServiceConfigEntities(Collection serviceConfigEntities) { this.serviceConfigEntities = serviceConfigEntities; } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("clusterId", clusterId) + .add("type", type) + .add("version", version) + .add("tag", tag) + .add("timestamp", timestamp) + .toString(); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/python/ambari-server.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py index 21bd0bb..dff4fc3 100755 --- a/ambari-server/src/main/python/ambari-server.py +++ b/ambari-server/src/main/python/ambari-server.py @@ -400,6 +400,7 @@ def init_parser_options(parser): help="Specifies the path to the JDBC driver JAR file") parser.add_option('--skip-properties-validation', action="store_true", default=False, help="Skip properties file validation", dest="skip_properties_validation") parser.add_option('--skip-database-check', action="store_true", default=False, help="Skip database consistency check", dest="skip_database_check") + parser.add_option('--auto-fix-database', action="store_true", default=False, help="Automatically fix database consistency issues", dest="fix_database_consistency") add_parser_options('--mpack', default=None, help="Specify the path for management pack to be installed/upgraded", @@ -501,6 +502,7 @@ def init_parser_options(parser): parser.add_option('--version-display-name', default=None, help="Display name of desired repo version", dest="desired_repo_version") parser.add_option('--skip-properties-validation', action="store_true", default=False, help="Skip properties file validation", dest="skip_properties_validation") parser.add_option('--skip-database-check', action="store_true", default=False, help="Skip database consistency check", dest="skip_database_check") + parser.add_option('--auto-fix-database', action="store_true", default=False, help="Automatically fix database consistency issues", dest="fix_database_consistency") parser.add_option('--force-version', action="store_true", default=False, help="Force version to current", dest="force_repo_version") parser.add_option('--version', dest="stack_versions", default=None, action="append", type="string", help="Specify stack version that needs to be enabled. All other stacks versions will be disabled") http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/main/python/ambari_server_main.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/python/ambari_server_main.py b/ambari-server/src/main/python/ambari_server_main.py index dbcafa4..11958cb 100644 --- a/ambari-server/src/main/python/ambari_server_main.py +++ b/ambari-server/src/main/python/ambari_server_main.py @@ -243,6 +243,7 @@ def wait_for_server_start(pidFile, scmStatus): if 'Database consistency check: failed' in open(configDefaults.SERVER_OUT_FILE).read(): print "DB configs consistency check failed. Run \"ambari-server start --skip-database-check\" to skip. " \ + "You may try --auto-fix-database flag to attempt to fix issues automatically. " \ "If you use this \"--skip-database-check\" option, do not make any changes to your cluster topology " \ "or perform a cluster upgrade until you correct the database consistency issues. See " + \ configDefaults.DB_CHECK_LOG + " for more details on the consistency issues." @@ -350,6 +351,8 @@ def server_process_main(options, scmStatus=None): properties.process_pair(CHECK_DATABASE_SKIPPED_PROPERTY, "true") else: print "Ambari database consistency check started..." + if options.fix_database_consistency: + jvm_args += " -DfixDatabaseConsistency" properties.process_pair(CHECK_DATABASE_SKIPPED_PROPERTY, "false") update_properties(properties) http://git-wip-us.apache.org/repos/asf/ambari/blob/a8222ae3/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java index 45e319a..d8af35a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java @@ -19,12 +19,15 @@ package org.apache.ambari.server.controller; import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.TypedQuery; import javax.servlet.DispatcherType; import javax.servlet.SessionCookieConfig; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.partialMockBuilder; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; @@ -34,6 +37,7 @@ import java.net.PasswordAuthentication; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; +import java.util.ArrayList; import java.util.EnumSet; import org.apache.ambari.server.AmbariException; @@ -220,6 +224,16 @@ public class AmbariServerTest { AmbariServer ambariServer = new AmbariServer(); + final Configuration mockConfiguration = partialMockBuilder(Configuration.class).withConstructor() + .addMockedMethod("getDatabaseType").createMock(); + final TypedQuery mockQuery = easyMockSupport.createNiceMock(TypedQuery.class); + + expect(mockConfiguration.getDatabaseType()).andReturn(null).anyTimes(); + expect(mockEntityManager.createNamedQuery(anyString(),anyObject(Class.class))).andReturn(mockQuery); + expect(mockQuery.getResultList()).andReturn(new ArrayList()); + + replay(mockConfiguration); + final Injector mockInjector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { @@ -229,6 +243,7 @@ public class AmbariServerTest { bind(OsFamily.class).toInstance(mockOSFamily); bind(EntityManager.class).toInstance(mockEntityManager); bind(Clusters.class).toInstance(mockClusters); + bind(Configuration.class).toInstance(mockConfiguration); } }); @@ -281,6 +296,16 @@ public class AmbariServerTest { AmbariServer ambariServer = new AmbariServer(); + final Configuration mockConfiguration = partialMockBuilder(Configuration.class).withConstructor() + .addMockedMethod("getDatabaseType").createMock(); + final TypedQuery mockQuery = easyMockSupport.createNiceMock(TypedQuery.class); + + expect(mockConfiguration.getDatabaseType()).andReturn(null).anyTimes(); + expect(mockEntityManager.createNamedQuery(anyString(),anyObject(Class.class))).andReturn(mockQuery); + expect(mockQuery.getResultList()).andReturn(new ArrayList()); + + replay(mockConfiguration); + final Injector mockInjector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { @@ -290,6 +315,7 @@ public class AmbariServerTest { bind(OsFamily.class).toInstance(mockOSFamily); bind(EntityManager.class).toInstance(mockEntityManager); bind(Clusters.class).toInstance(mockClusters); + bind(Configuration.class).toInstance(mockConfiguration); } });