You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by vb...@apache.org on 2016/02/11 14:58:45 UTC
ambari git commit: AMBARI-14948. Config consistency
checker.(vbrodetskyi)
Repository: ambari
Updated Branches:
refs/heads/branch-2.2 7ce5a0072 -> 58b0b5014
AMBARI-14948. Config consistency checker.(vbrodetskyi)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/58b0b501
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/58b0b501
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/58b0b501
Branch: refs/heads/branch-2.2
Commit: 58b0b5014ee3753230782b9e97c52662c25ceed2
Parents: 7ce5a00
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Thu Feb 11 01:10:42 2016 +0200
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Thu Feb 11 01:10:42 2016 +0200
----------------------------------------------------------------------
ambari-server/sbin/ambari-server | 6 +-
.../server/checks/CheckDatabaseHelper.java | 473 +++++++++++++++++++
ambari-server/src/main/python/ambari-server.py | 9 +-
.../main/python/ambari_server/checkDatabase.py | 80 ++++
.../main/python/ambari_server/setupActions.py | 1 +
.../server/checks/CheckDatabaseHelperTest.java | 292 ++++++++++++
.../src/test/python/TestAmbariServer.py | 37 ++
7 files changed, 894 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/sbin/ambari-server
----------------------------------------------------------------------
diff --git a/ambari-server/sbin/ambari-server b/ambari-server/sbin/ambari-server
index 72d94ed..e676cbc 100755
--- a/ambari-server/sbin/ambari-server
+++ b/ambari-server/sbin/ambari-server
@@ -138,9 +138,13 @@ case "$1" in
echo -e "Updating host names"
$PYTHON /usr/sbin/ambari-server.py $@
;;
+ check-database)
+ echo -e "Checking database"
+ $PYTHON /usr/sbin/ambari-server.py $@
+ ;;
*)
echo "Usage: /usr/sbin/ambari-server
- {start|stop|restart|setup|setup-jce|upgrade|status|upgradestack|setup-ldap|sync-ldap|set-current|setup-security|refresh-stack-hash|backup|restore|update-host-names} [options]
+ {start|stop|restart|setup|setup-jce|upgrade|status|upgradestack|setup-ldap|sync-ldap|set-current|setup-security|refresh-stack-hash|backup|restore|update-host-names|check-database} [options]
Use usr/sbin/ambari-server <action> --help to get details on options available.
Or, simply invoke ambari-server.py --help to print the options."
exit 1
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDatabaseHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDatabaseHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDatabaseHelper.java
new file mode 100644
index 0000000..a078c8a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDatabaseHelper.java
@@ -0,0 +1,473 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.checks;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.ControllerModule;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.utils.EventBusSynchronizer;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+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.List;
+import java.util.Map;
+import java.util.Set;
+
+/*
+* Class for database validation.
+* Here we will check configs, services, components and etc.
+*/
+public class CheckDatabaseHelper {
+ private static final Logger LOG = LoggerFactory.getLogger
+ (CheckDatabaseHelper.class);
+
+ private static final String AUTHENTICATED_USER_NAME = "ambari-check-database";
+
+ private PersistService persistService;
+ private DBAccessor dbAccessor;
+ private Connection connection;
+ private AmbariMetaInfo ambariMetaInfo;
+ private Injector injector;
+
+ @Inject
+ public CheckDatabaseHelper(DBAccessor dbAccessor,
+ Injector injector,
+ PersistService persistService) {
+ this.dbAccessor = dbAccessor;
+ this.injector = injector;
+ this.persistService = persistService;
+ }
+
+ /**
+ * Extension of main controller module
+ */
+ public static class CheckHelperModule extends ControllerModule {
+
+ public CheckHelperModule() throws Exception {
+ }
+
+ @Override
+ protected void configure() {
+ super.configure();
+ EventBusSynchronizer.synchronizeAmbariEventPublisher(binder());
+ }
+ }
+
+ /*
+ * init method to create connection
+ * */
+ protected void init() {
+ connection = dbAccessor.getConnection();
+ ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ }
+
+ /*
+ * method to close connection
+ * */
+ private void closeConnection() {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during connection close procedure: ", e);
+ }
+ }
+
+ public void startPersistenceService() {
+ persistService.start();
+ }
+
+ public void stopPersistenceService() {
+ persistService.stop();
+ }
+
+ /*
+ * This method checks if all configurations that we have in clusterconfig table
+ * have at least one mapping in clusterconfigmapping table. If we found not mapped config
+ * then we are showing warning message for user.
+ * */
+ protected void checkForNotMappedConfigsToCluster() {
+ String GET_NOT_MAPPED_CONFIGS_QUERY = "select type_name from clusterconfig where type_name not in (select type_name from clusterconfigmapping)";
+ Set<String> nonSelectedConfigs = new HashSet<>();
+ ResultSet rs = null;
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+ rs = statement.executeQuery(GET_NOT_MAPPED_CONFIGS_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ nonSelectedConfigs.add(rs.getString("type_name"));
+ }
+ }
+ if (!nonSelectedConfigs.isEmpty()) {
+ LOG.warn("You have config(s) that is(are) not mapped to any cluster: " + StringUtils.join(nonSelectedConfigs, ","));
+ }
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during check for not mapped configs to cluster procedure: ", e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during result set closing procedure: ", e);
+ }
+ }
+ }
+ }
+
+ /*
+ * 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
+ * than one selected version it's a bug and we are showing error message for user.
+ * */
+ protected void checkForConfigsSelectedMoreThanOnce() {
+ String GET_CONFIGS_SELECTED_MORE_THAN_ONCE_QUERY = "select type_name from clusterconfigmapping group by type_name having sum(selected) > 1";
+ Set<String> configsSelectedMoreThanOnce = new HashSet<>();
+ ResultSet rs = null;
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+ rs = statement.executeQuery(GET_CONFIGS_SELECTED_MORE_THAN_ONCE_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ configsSelectedMoreThanOnce.add(rs.getString("type_name"));
+ }
+ }
+ if (!configsSelectedMoreThanOnce.isEmpty()) {
+ LOG.error("You have config(s) that is(are) selected more than once in clusterconfigmapping: " + StringUtils.join(configsSelectedMoreThanOnce, ","));
+ }
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during check for config selected more than ones procedure: ", e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during result set closing procedure: ", e);
+ }
+ }
+ }
+ }
+
+ /*
+ * This method checks if all hosts from hosts table
+ * has related host state info in hoststate table.
+ * If not then we are showing error.
+ * */
+ protected void checkForHostsWithoutState() {
+ String GET_HOSTS_WITHOUT_STATUS_QUERY = "select host_name from hosts where host_id not in (select host_id from hoststate)";
+ Set<String> hostsWithoutStatus = new HashSet<>();
+ ResultSet rs = null;
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+ rs = statement.executeQuery(GET_HOSTS_WITHOUT_STATUS_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ LOG.error(rs.getString("host_name"));
+ LOG.error(rs.getString("HOST_NAME"));
+ System.out.println("ERROR" + rs.getString("HOST_NAME"));
+ System.out.println("ERROR" + rs.getString("host_name"));
+ hostsWithoutStatus.add(rs.getString("host_name"));
+ }
+ }
+
+ if (!hostsWithoutStatus.isEmpty()) {
+ LOG.error("You have host(s) without status: " + StringUtils.join(hostsWithoutStatus, ","));
+ }
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during check for host without state procedure: ", e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during result set closing procedure: ", e);
+ }
+ }
+ }
+ }
+
+ /*
+ * 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
+ * showing error for user.
+ * */
+ protected void checkHostComponentStatesCountEqualsHostComponentsDesiredStates() {
+ String GET_HOST_COMPONENT_STATE_COUNT_QUERY = "select count(*) from hostcomponentstate";
+ String GET_HOST_COMPONENT_DESIRED_STATE_COUNT_QUERY = "select count(*) from hostcomponentdesiredstate";
+ String GET_MERGED_TABLE_ROW_COUNT_QUERY = "select count(*) FROM hostcomponentstate hcs " +
+ "JOIN hostcomponentdesiredstate hcds ON hcs.service_name = hcds.service_name AND hcs.component_name = hcds.component_name AND hcs.host_id = hcds.host_id";
+ int hostComponentStateCount = 0;
+ int hostComponentDesiredStateCount = 0;
+ int mergedCount = 0;
+ ResultSet rs = null;
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+
+ rs = statement.executeQuery(GET_HOST_COMPONENT_STATE_COUNT_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ hostComponentStateCount = rs.getInt(1);
+ }
+ }
+
+ rs = statement.executeQuery(GET_HOST_COMPONENT_DESIRED_STATE_COUNT_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ hostComponentDesiredStateCount = rs.getInt(1);
+ }
+ }
+
+ rs = statement.executeQuery(GET_MERGED_TABLE_ROW_COUNT_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ mergedCount = rs.getInt(1);
+ }
+ }
+
+ if (hostComponentStateCount != hostComponentDesiredStateCount || hostComponentStateCount != mergedCount) {
+ LOG.error("Your host component state count not equals host component desired state count!");
+ }
+
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during check for same count of host component states and host component desired states: ", 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.
+ * 3) Check if service has all required configs mapped to it.
+ * 4) Check if service has config which is not selected(has no actual config version) in clusterconfigmapping table.
+ * If any issue was discovered, we are showing error message for user.
+ * */
+ protected void checkServiceConfigs() {
+ String GET_SERVICES_WITHOUT_CONFIGS_QUERY = "select service_name from clusterservices where service_name not in (select service_name from serviceconfig where group_id is null)";
+ String GET_SERVICE_CONFIG_WITHOUT_MAPPING_QUERY = "select service_name from serviceconfig where service_config_id not in (select service_config_id from serviceconfigmapping) and group_id is null";
+ String GET_STACK_NAME_VERSION_QUERY = "select s.stack_name, s.stack_version from clusters c join stack s on c.desired_stack_id = s.stack_id";
+ String GET_SERVICES_WITH_CONFIGS_QUERY = "select cs.service_name, type_name, sc.version from clusterservices cs " +
+ "join serviceconfig sc on cs.service_name=sc.service_name " +
+ "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
+ "join clusterconfig cc on scm.config_id=cc.config_id " +
+ "where sc.group_id is null " +
+ "group by cs.service_name, type_name, sc.version";
+ String GET_NOT_SELECTED_SERVICE_CONFIGS_QUERY = "select cs.service_name,cc.type_name from clusterservices cs " +
+ "join serviceconfig sc on cs.service_name=sc.service_name " +
+ "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
+ "join clusterconfig cc on scm.config_id=cc.config_id " +
+ "join clusterconfigmapping ccm on cc.type_name=ccm.type_name and cc.version_tag=ccm.version_tag " +
+ "where sc.group_id is null and sc.service_config_id = (select max(service_config_id) from serviceconfig sc2 where sc2.service_name=sc.service_name) " +
+ "group by cs.service_name,cc.type_name " +
+ "having sum(ccm.selected) < 1";
+ String stackName = null, stackVersion = null;
+ Set<String> servicesWithoutConfigs = new HashSet<>();
+ Set<String> servicesWithoutMappedConfigs = new HashSet<>();
+ Map<String, List<String>> notSelectedServiceConfigs = new HashMap<>();
+ ResultSet rs = null;
+
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+
+ rs = statement.executeQuery(GET_SERVICES_WITHOUT_CONFIGS_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ servicesWithoutConfigs.add(rs.getString("service_name"));
+ }
+ }
+
+ if (!servicesWithoutConfigs.isEmpty()) {
+ LOG.error("You have services without configs at all: " + StringUtils.join(servicesWithoutConfigs, ","));
+ }
+
+ rs = statement.executeQuery(GET_SERVICE_CONFIG_WITHOUT_MAPPING_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ servicesWithoutMappedConfigs.add(rs.getString("service_name"));
+ }
+ }
+
+ if (!servicesWithoutMappedConfigs.isEmpty()) {
+ LOG.error("You have services without mapped configs: " + StringUtils.join(servicesWithoutMappedConfigs, ","));
+ }
+
+ rs = statement.executeQuery(GET_STACK_NAME_VERSION_QUERY);
+ if (rs != null) {
+ while (rs.next()) {
+ stackName = rs.getString("stack_name");
+ stackVersion = rs.getString("stack_version");
+ }
+ }
+
+ if (stackName != null && stackVersion != null) {
+ Set<String> serviceNames = new HashSet<>();
+ Map<Integer, Multimap<String, String>> dbServiceVersionConfigs = new HashMap<>();
+ Multimap<String, String> stackServiceConfigs = HashMultimap.create();
+
+ rs = statement.executeQuery(GET_SERVICES_WITH_CONFIGS_QUERY);
+ if (rs != null) {
+ String serviceName = null, configType = null;
+ Integer serviceVersion = null;
+ while (rs.next()) {
+ serviceName = rs.getString("service_name");
+ configType = rs.getString("type_name");
+ serviceVersion = rs.getInt("version");
+
+ serviceNames.add(serviceName);
+
+ if (dbServiceVersionConfigs.get(serviceVersion) == null) {
+ Multimap<String, String> dbServiceConfigs = HashMultimap.create();
+ dbServiceConfigs.put(serviceName, configType);
+ dbServiceVersionConfigs.put(serviceVersion, dbServiceConfigs);
+ } else {
+ dbServiceVersionConfigs.get(serviceVersion).put(serviceName, configType);
+ }
+ }
+ }
+
+
+ Map<String, ServiceInfo> serviceInfoMap = ambariMetaInfo.getServices(stackName, stackVersion);
+ for (String serviceName : serviceNames) {
+ ServiceInfo serviceInfo = serviceInfoMap.get(serviceName);
+ Set<String> configTypes = serviceInfo.getConfigTypeAttributes().keySet();
+ for (String configType : configTypes) {
+ stackServiceConfigs.put(serviceName, configType);
+ }
+ }
+
+ for (Integer serviceVersion : dbServiceVersionConfigs.keySet()) {
+ Multimap<String, String> dbServiceConfigs = dbServiceVersionConfigs.get(serviceVersion);
+ for (String serviceName : dbServiceConfigs.keySet()) {
+ Collection<String> serviceConfigsFromStack = stackServiceConfigs.get(serviceName);
+ Collection<String> serviceConfigsFromDB = dbServiceConfigs.get(serviceName);
+ if (serviceConfigsFromDB != null && serviceConfigsFromStack != null) {
+ serviceConfigsFromStack.removeAll(serviceConfigsFromDB);
+ if (!serviceConfigsFromStack.isEmpty()) {
+ LOG.error(String.format("Required config(s): %s is(are) not available for service %s with service config version %s",
+ StringUtils.join(serviceConfigsFromStack, ","), serviceName, Integer.toString(serviceVersion)));
+ }
+ }
+ }
+ }
+ }
+
+ rs = statement.executeQuery(GET_NOT_SELECTED_SERVICE_CONFIGS_QUERY);
+ if (rs != null) {
+ String serviceName = null, configType = null;
+ while (rs.next()) {
+ serviceName = rs.getString("service_name");
+ configType = rs.getString("type_name");
+
+ if (notSelectedServiceConfigs.get(serviceName) != null) {
+ notSelectedServiceConfigs.get(serviceName).add(configType);
+ } else {
+ List<String> configTypes = new ArrayList<>();
+ configTypes.add(configType);
+ notSelectedServiceConfigs.put(serviceName, configTypes);
+ }
+ }
+ }
+
+ for (String serviceName : notSelectedServiceConfigs.keySet()) {
+ LOG.error(String.format("You have non selected configs: %s for service %s.", StringUtils.join(notSelectedServiceConfigs.get(serviceName), ","), serviceName));
+ }
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during complex service check procedure: ", e);
+ } catch (AmbariException e) {
+ LOG.error("Exception occurred during complex service check procedure: ", e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ LOG.error("Exception occurred during result set closing procedure: ", e);
+ }
+ }
+ }
+
+ }
+
+ /*
+ * Main method from which we are calling all checks
+ * */
+ public static void main(String[] args) throws Exception {
+ CheckDatabaseHelper checkDatabaseHelper = null;
+ try {
+ LOG.info("******************************* Check database started *******************************");
+
+ Injector injector = Guice.createInjector(new CheckHelperModule());
+ checkDatabaseHelper = injector.getInstance(CheckDatabaseHelper.class);
+
+ checkDatabaseHelper.startPersistenceService();
+
+ checkDatabaseHelper.init();
+
+ checkDatabaseHelper.checkForNotMappedConfigsToCluster();
+
+ checkDatabaseHelper.checkForConfigsSelectedMoreThanOnce();
+
+ checkDatabaseHelper.checkForHostsWithoutState();
+
+ checkDatabaseHelper.checkHostComponentStatesCountEqualsHostComponentsDesiredStates();
+
+ checkDatabaseHelper.checkServiceConfigs();
+
+ checkDatabaseHelper.stopPersistenceService();
+
+ LOG.info("******************************* Check database completed *******************************");
+ } catch (Throwable e) {
+ if (e instanceof AmbariException) {
+ LOG.error("Exception occurred during database check:", e);
+ throw (AmbariException)e;
+ }else{
+ LOG.error("Unexpected error, database check failed", e);
+ throw new Exception("Unexpected error, database check failed", e);
+ }
+ } finally {
+ if (checkDatabaseHelper != null) {
+ checkDatabaseHelper.closeConnection();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/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 8be79a5..38bf11f 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -37,10 +37,12 @@ from ambari_server.serverSetup import reset, setup, setup_jce_policy
from ambari_server.serverUpgrade import upgrade, upgrade_stack, set_current
from ambari_server.setupHttps import setup_https, setup_truststore
from ambari_server.hostUpdate import update_host_names
+from ambari_server.checkDatabase import check_database
from ambari_server.setupActions import BACKUP_ACTION, LDAP_SETUP_ACTION, LDAP_SYNC_ACTION, PSTART_ACTION, \
- REFRESH_STACK_HASH_ACTION, RESET_ACTION, RESTORE_ACTION, UPDATE_HOST_NAMES_ACTION, SETUP_ACTION, SETUP_SECURITY_ACTION, \
- START_ACTION, STATUS_ACTION, STOP_ACTION, UPGRADE_ACTION, UPGRADE_STACK_ACTION, SETUP_JCE_ACTION, SET_CURRENT_ACTION
+ REFRESH_STACK_HASH_ACTION, RESET_ACTION, RESTORE_ACTION, UPDATE_HOST_NAMES_ACTION, CHECK_DATABASE_ACTION, \
+ SETUP_ACTION, SETUP_SECURITY_ACTION,START_ACTION, STATUS_ACTION, STOP_ACTION, UPGRADE_ACTION, UPGRADE_STACK_ACTION, \
+ SETUP_JCE_ACTION, SET_CURRENT_ACTION
from ambari_server.setupSecurity import setup_ldap, sync_ldap, setup_master_key, setup_ambari_krb5_jaas
from ambari_server.userInput import get_validated_string_input
@@ -523,7 +525,8 @@ def create_user_action_map(args, options):
REFRESH_STACK_HASH_ACTION: UserAction(refresh_stack_hash_action),
BACKUP_ACTION: UserActionPossibleArgs(backup, [1, 2], args),
RESTORE_ACTION: UserActionPossibleArgs(restore, [1, 2], args),
- UPDATE_HOST_NAMES_ACTION: UserActionPossibleArgs(update_host_names, [2], args, options)
+ UPDATE_HOST_NAMES_ACTION: UserActionPossibleArgs(update_host_names, [2], args, options),
+ CHECK_DATABASE_ACTION: UserAction(check_database, options)
}
return action_map
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/src/main/python/ambari_server/checkDatabase.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/checkDatabase.py b/ambari-server/src/main/python/ambari_server/checkDatabase.py
new file mode 100644
index 0000000..af1d74f
--- /dev/null
+++ b/ambari-server/src/main/python/ambari_server/checkDatabase.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+import os
+import sys
+
+from ambari_commons.exceptions import FatalException
+from ambari_server import serverConfiguration
+from ambari_server import dbConfiguration
+from ambari_server import setupSecurity
+from ambari_commons import os_utils
+from ambari_server import userInput
+from ambari_server import serverUtils
+from ambari_server.serverConfiguration import configDefaults, get_java_exe_path, get_ambari_properties, read_ambari_user, \
+ parse_properties_file, JDBC_DATABASE_PROPERTY
+from ambari_commons.logging_utils import print_info_msg, print_warning_msg, print_error_msg
+from ambari_server.dbConfiguration import ensure_jdbc_driver_is_installed, LINUX_DBMS_KEYS_LIST
+from ambari_server.serverClassPath import ServerClassPath
+from ambari_server.setupSecurity import ensure_can_start_under_current_user, generate_env
+from ambari_commons.os_utils import run_os_command
+from ambari_server.serverUtils import is_server_runing
+from ambari_server.userInput import get_YN_input
+
+CHECK_DATABASE_HELPER_CMD = "{0} -cp {1} " + \
+ "org.apache.ambari.server.checks.CheckDatabaseHelper" + \
+ " > " + configDefaults.SERVER_LOG_FILE + " 2>&1"
+
+def check_database(options):
+
+ jdk_path = serverConfiguration.get_java_exe_path()
+
+ if jdk_path is None:
+ print_error_msg("No JDK found, please run the \"setup\" "
+ "command to install a JDK automatically or install any "
+ "JDK manually to " + configDefaults.JDK_INSTALL_DIR)
+ sys.exit(1)
+
+ properties = serverConfiguration.get_ambari_properties()
+ serverConfiguration.parse_properties_file(options)
+ options.database_index = LINUX_DBMS_KEYS_LIST.index(properties[JDBC_DATABASE_PROPERTY])
+
+ dbConfiguration.ensure_jdbc_driver_is_installed(options, serverConfiguration.get_ambari_properties())
+
+ serverClassPath = ServerClassPath(serverConfiguration.get_ambari_properties(), options)
+ class_path = serverClassPath.get_full_ambari_classpath_escaped_for_shell()
+
+ command = CHECK_DATABASE_HELPER_CMD.format(jdk_path, class_path)
+
+ ambari_user = serverConfiguration.read_ambari_user()
+ current_user = setupSecurity.ensure_can_start_under_current_user(ambari_user)
+ environ = setupSecurity.generate_env(options, ambari_user, current_user)
+
+ (retcode, stdout, stderr) = os_utils.run_os_command(command, env=environ)
+ print_info_msg("Return code from check database command, retcode = " + str(retcode))
+
+ if retcode > 0:
+ print_error_msg("Database check failed to complete. Please check ambari-server.log for problem.")
+ raise FatalException(1, 'Database check failed.')
+ else:
+ print_info_msg('Check database completed successfully. Please check ambari-server.log for results.')
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/src/main/python/ambari_server/setupActions.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/setupActions.py b/ambari-server/src/main/python/ambari_server/setupActions.py
index 686ac9a..324ef69 100644
--- a/ambari-server/src/main/python/ambari_server/setupActions.py
+++ b/ambari-server/src/main/python/ambari_server/setupActions.py
@@ -36,6 +36,7 @@ SETUP_GANGLIA_HTTPS_ACTION = "setup-ganglia-https"
ENCRYPT_PASSWORDS_ACTION = "encrypt-passwords"
SETUP_SECURITY_ACTION = "setup-security"
UPDATE_HOST_NAMES_ACTION = "update-host-names"
+CHECK_DATABASE_ACTION = "check-database"
BACKUP_ACTION = "backup"
RESTORE_ACTION = "restore"
SETUP_JCE_ACTION = "setup-jce"
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/src/test/java/org/apache/ambari/server/checks/CheckDatabaseHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/CheckDatabaseHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/CheckDatabaseHelperTest.java
new file mode 100644
index 0000000..e329ab7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/CheckDatabaseHelperTest.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.checks;
+
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.stack.StackManagerFactory;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.EasyMockSupport;
+import org.junit.Test;
+
+import javax.persistence.EntityManager;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.expect;
+
+public class CheckDatabaseHelperTest {
+
+ @Test
+ public void testCheckForNotMappedConfigs() throws Exception {
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+ final AmbariMetaInfo mockAmbariMetainfo = easyMockSupport.createNiceMock(AmbariMetaInfo.class);
+ final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
+ final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
+ final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final Statement mockStatement = easyMockSupport.createNiceMock(Statement.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(AmbariMetaInfo.class).toInstance(mockAmbariMetainfo);
+ 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);
+ }
+ });
+
+
+ expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection);
+ expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
+ expect(mockStatement.executeQuery("select type_name from clusterconfig where type_name not in (select type_name from clusterconfigmapping)")).andReturn(mockResultSet);
+
+ CheckDatabaseHelper checkDatabaseHelper = new CheckDatabaseHelper(mockDBDbAccessor, mockInjector, null);
+
+
+ easyMockSupport.replayAll();
+
+ mockAmbariMetainfo.init();
+ checkDatabaseHelper.init();
+ checkDatabaseHelper.checkForNotMappedConfigsToCluster();
+
+ easyMockSupport.verifyAll();
+ }
+
+ @Test
+ public void testCheckForConfigsSelectedMoreThanOnce() throws Exception {
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+ final AmbariMetaInfo mockAmbariMetainfo = easyMockSupport.createNiceMock(AmbariMetaInfo.class);
+ final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
+ final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
+ final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final Statement mockStatement = easyMockSupport.createNiceMock(Statement.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(AmbariMetaInfo.class).toInstance(mockAmbariMetainfo);
+ 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);
+ }
+ });
+
+
+ expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection);
+ expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
+ expect(mockStatement.executeQuery("select type_name from clusterconfigmapping group by type_name having sum(selected) > 1")).andReturn(mockResultSet);
+
+ CheckDatabaseHelper checkDatabaseHelper = new CheckDatabaseHelper(mockDBDbAccessor, mockInjector, null);
+
+
+ easyMockSupport.replayAll();
+
+ mockAmbariMetainfo.init();
+ checkDatabaseHelper.init();
+ checkDatabaseHelper.checkForConfigsSelectedMoreThanOnce();
+
+ easyMockSupport.verifyAll();
+ }
+
+ @Test
+ public void testCheckForHostsWithoutState() throws Exception {
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+ final AmbariMetaInfo mockAmbariMetainfo = easyMockSupport.createNiceMock(AmbariMetaInfo.class);
+ final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
+ final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
+ final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final Statement mockStatement = easyMockSupport.createNiceMock(Statement.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(AmbariMetaInfo.class).toInstance(mockAmbariMetainfo);
+ 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);
+ }
+ });
+
+
+ expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection);
+ expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
+ expect(mockStatement.executeQuery("select host_name from hosts where host_id not in (select host_id from hoststate)")).andReturn(mockResultSet);
+
+ CheckDatabaseHelper checkDatabaseHelper = new CheckDatabaseHelper(mockDBDbAccessor, mockInjector, null);
+
+
+ easyMockSupport.replayAll();
+
+ mockAmbariMetainfo.init();
+ checkDatabaseHelper.init();
+ checkDatabaseHelper.checkForHostsWithoutState();
+
+ easyMockSupport.verifyAll();
+ }
+
+ @Test
+ public void testCheckHostComponentStatesCountEqualsHostComponentsDesiredStates() throws Exception {
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+ final AmbariMetaInfo mockAmbariMetainfo = easyMockSupport.createNiceMock(AmbariMetaInfo.class);
+ final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
+ final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
+ final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final Statement mockStatement = easyMockSupport.createNiceMock(Statement.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(AmbariMetaInfo.class).toInstance(mockAmbariMetainfo);
+ 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);
+ }
+ });
+
+
+ expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection);
+ expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
+ expect(mockStatement.executeQuery("select count(*) from hostcomponentstate")).andReturn(mockResultSet);
+ expect(mockStatement.executeQuery("select count(*) from hostcomponentdesiredstate")).andReturn(mockResultSet);
+ expect(mockStatement.executeQuery("select count(*) FROM hostcomponentstate hcs " +
+ "JOIN hostcomponentdesiredstate hcds ON hcs.service_name = hcds.service_name AND " +
+ "hcs.component_name = hcds.component_name AND hcs.host_id = hcds.host_id")).andReturn(mockResultSet);
+
+ CheckDatabaseHelper checkDatabaseHelper = new CheckDatabaseHelper(mockDBDbAccessor, mockInjector, null);
+
+
+ easyMockSupport.replayAll();
+
+ mockAmbariMetainfo.init();
+ checkDatabaseHelper.init();
+ checkDatabaseHelper.checkHostComponentStatesCountEqualsHostComponentsDesiredStates();
+
+ easyMockSupport.verifyAll();
+ }
+
+ @Test
+ public void testCheckServiceConfigs() throws Exception {
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+ final AmbariMetaInfo mockAmbariMetainfo = easyMockSupport.createNiceMock(AmbariMetaInfo.class);
+ final DBAccessor mockDBDbAccessor = easyMockSupport.createNiceMock(DBAccessor.class);
+ final Connection mockConnection = easyMockSupport.createNiceMock(Connection.class);
+ final ResultSet mockResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final ResultSet stackResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final ResultSet serviceConfigResultSet = easyMockSupport.createNiceMock(ResultSet.class);
+ final Statement mockStatement = easyMockSupport.createNiceMock(Statement.class);
+ final ServiceInfo mockHDFSServiceInfo = easyMockSupport.createNiceMock(ServiceInfo.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(AmbariMetaInfo.class).toInstance(mockAmbariMetainfo);
+ 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);
+ }
+ });
+
+ Map<String, ServiceInfo> services = new HashMap<>();
+ services.put("HDFS", mockHDFSServiceInfo);
+
+ Map<String, Map<String, Map<String, String>>> configAttributes = new HashMap<>();
+ configAttributes.put("core-site", new HashMap<String, Map<String, String>>());
+
+ expect(mockHDFSServiceInfo.getConfigTypeAttributes()).andReturn(configAttributes);
+ expect(mockAmbariMetainfo.getServices("HDP", "2.2")).andReturn(services);
+ expect(serviceConfigResultSet.next()).andReturn(true);
+ expect(serviceConfigResultSet.getString("service_name")).andReturn("HDFS");
+ expect(serviceConfigResultSet.getString("type_name")).andReturn("core-site");
+ expect(stackResultSet.next()).andReturn(true);
+ expect(stackResultSet.getString("stack_name")).andReturn("HDP");
+ expect(stackResultSet.getString("stack_version")).andReturn("2.2");
+ expect(mockDBDbAccessor.getConnection()).andReturn(mockConnection);
+ expect(mockConnection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)).andReturn(mockStatement);
+ expect(mockStatement.executeQuery("select service_name from clusterservices where service_name not in (select service_name from serviceconfig where group_id is null)")).andReturn(mockResultSet);
+ expect(mockStatement.executeQuery("select service_name from serviceconfig where service_config_id not in (select service_config_id from serviceconfigmapping) and group_id is null")).andReturn(mockResultSet);
+ expect(mockStatement.executeQuery("select s.stack_name, s.stack_version from clusters c join stack s on c.desired_stack_id = s.stack_id")).andReturn(stackResultSet);
+ expect(mockStatement.executeQuery("select cs.service_name, type_name, sc.version from clusterservices cs " +
+ "join serviceconfig sc on cs.service_name=sc.service_name " +
+ "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
+ "join clusterconfig cc on scm.config_id=cc.config_id " +
+ "where sc.group_id is null " +
+ "group by cs.service_name, type_name, sc.version")).andReturn(serviceConfigResultSet);
+ expect(mockStatement.executeQuery("select cs.service_name,cc.type_name from clusterservices cs " +
+ "join serviceconfig sc on cs.service_name=sc.service_name " +
+ "join serviceconfigmapping scm on sc.service_config_id=scm.service_config_id " +
+ "join clusterconfig cc on scm.config_id=cc.config_id " +
+ "join clusterconfigmapping ccm on cc.type_name=ccm.type_name and cc.version_tag=ccm.version_tag " +
+ "where sc.group_id is null and sc.service_config_id = (select max(service_config_id) from serviceconfig sc2 where sc2.service_name=sc.service_name) " +
+ "group by cs.service_name,cc.type_name " +
+ "having sum(ccm.selected) < 1")).andReturn(mockResultSet);
+
+ CheckDatabaseHelper checkDatabaseHelper = new CheckDatabaseHelper(mockDBDbAccessor, mockInjector, null);
+
+
+ easyMockSupport.replayAll();
+
+ mockAmbariMetainfo.init();
+ checkDatabaseHelper.init();
+ checkDatabaseHelper.checkServiceConfigs();
+
+ easyMockSupport.verifyAll();
+ }
+
+
+}
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/58b0b501/ambari-server/src/test/python/TestAmbariServer.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index fdc375b..511700b 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -94,6 +94,7 @@ with patch("platform.linux_distribution", return_value = os_distro_value):
from ambari_server_main import get_ulimit_open_files, ULIMIT_OPEN_FILES_KEY, ULIMIT_OPEN_FILES_DEFAULT
from ambari_server.serverClassPath import ServerClassPath
from ambari_server.hostUpdate import update_host_names
+ from ambari_server.checkDatabase import check_database
CURR_AMBARI_VERSION = "2.0.0"
@@ -6816,6 +6817,42 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
pass
+ @patch.object(ServerClassPath, "get_full_ambari_classpath_escaped_for_shell", new = MagicMock(return_value = 'test' + os.pathsep + 'path12'))
+ @patch("ambari_server.serverUtils.is_server_runing")
+ @patch("ambari_commons.os_utils.run_os_command")
+ @patch("ambari_server.setupSecurity.generate_env")
+ @patch("ambari_server.setupSecurity.ensure_can_start_under_current_user")
+ @patch("ambari_server.serverConfiguration.read_ambari_user")
+ @patch("ambari_server.dbConfiguration.ensure_jdbc_driver_is_installed")
+ @patch("ambari_server.serverConfiguration.parse_properties_file")
+ @patch("ambari_server.serverConfiguration.get_ambari_properties")
+ @patch("ambari_server.serverConfiguration.get_java_exe_path")
+ def test_check_database(self, getJavaExePathMock,
+ getAmbariPropertiesMock, parsePropertiesFileMock, ensureDriverInstalledMock, readAmbariUserMock,
+ ensureCanStartUnderCurrentUserMock, generateEnvMock, runOSCommandMock, isServerRunningMock):
+ properties = Properties()
+ properties.process_pair("server.jdbc.database", "embedded")
+
+ getJavaExePathMock.return_value = "/path/to/java"
+ getAmbariPropertiesMock.return_value = properties
+ readAmbariUserMock.return_value = "test_user"
+ ensureCanStartUnderCurrentUserMock.return_value = "test_user"
+ generateEnvMock.return_value = {}
+ runOSCommandMock.return_value = (0, "", "")
+ isServerRunningMock.return_value = (False, 1)
+
+ check_database(properties)
+
+ self.assertTrue(getJavaExePathMock.called)
+ self.assertTrue(readAmbariUserMock.called)
+ self.assertTrue(ensureCanStartUnderCurrentUserMock.called)
+ self.assertTrue(generateEnvMock.called)
+
+ self.assertEquals(runOSCommandMock.call_args[0][0], '/path/to/java -cp test:path12 org.apache.ambari.server.checks.CheckDatabaseHelper'
+ ' > /var/log/ambari-server/ambari-server.log 2>&1')
+
+ pass
+
@not_for_platform(PLATFORM_WINDOWS)
@patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = os_distro_value))
@patch.object(_ambari_server_, "is_server_runing")