You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2016/12/02 21:24:42 UTC

[01/24] ambari git commit: AMBARI-18929. Yarn service check fails when either resource manager is down in HA enabled cluster (Weiwei Yang via alejandro)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-18456 087de8b78 -> a58c39c9c


AMBARI-18929. Yarn service check fails when either resource manager is down in HA enabled cluster (Weiwei Yang via alejandro)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/88e0c29e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/88e0c29e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/88e0c29e

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 88e0c29e0617f05c0ecb72a75e74b2bb3def6bac
Parents: 6100be6
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Thu Dec 1 09:45:56 2016 -0800
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Thu Dec 1 09:45:56 2016 -0800

----------------------------------------------------------------------
 .../2.1.0.2.0/package/scripts/service_check.py  |  66 +++++++----
 .../2.0.6/YARN/test_yarn_service_check.py       | 111 ++++++++++---------
 2 files changed, 100 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/88e0c29e/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/service_check.py
index c0bd480..b934767 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/service_check.py
@@ -130,34 +130,56 @@ class ServiceCheckDefault(ServiceCheck):
       if "application" in item:
         application_name = item
 
-    for rm_webapp_address in params.rm_webapp_addresses_list:
-      info_app_url = params.scheme + "://" + rm_webapp_address + "/ws/v1/cluster/apps/" + application_name
+    # Find out the active RM from RM list
+    # Raise an exception if the active rm cannot be determined
+    active_rm_webapp_address = self.get_active_rm_webapp_address()
+    Logger.info("Active Resource Manager web app address is : " + active_rm_webapp_address);
 
-      get_app_info_cmd = "curl --negotiate -u : -ks --location-trusted --connect-timeout " + CURL_CONNECTION_TIMEOUT + " " + info_app_url
+    # Verify job state from active resource manager via rest api
+    info_app_url = params.scheme + "://" + active_rm_webapp_address + "/ws/v1/cluster/apps/" + application_name
+    get_app_info_cmd = "curl --negotiate -u : -ks --location-trusted --connect-timeout " + CURL_CONNECTION_TIMEOUT + " " + info_app_url
 
-      return_code, stdout, _ = get_user_call_output(get_app_info_cmd,
-                                            user=params.smokeuser,
-                                            path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
-                                            )
+    return_code, stdout, _ = get_user_call_output(get_app_info_cmd,
+                                                  user=params.smokeuser,
+                                                  path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
+                                                  )
 
-      # Handle HDP<2.2.8.1 where RM doesn't do automatic redirection from standby to active
-      if stdout.startswith("This is standby RM. Redirecting to the current active RM:"):
-        Logger.info(format("Skipped checking of {rm_webapp_address} since returned '{stdout}'"))
-        continue
+    try:
+      json_response = json.loads(stdout)
+    except Exception as e:
+      raise Fail(format("Response from YARN API was not a valid JSON. Response: {stdout}"))
 
-      try:
-        json_response = json.loads(stdout)
-      except Exception as e:
-        raise Fail(format("Response from YARN API was not a valid JSON. Response: {stdout}"))
-      
-      if json_response is None or 'app' not in json_response or \
-              'state' not in json_response['app'] or 'finalStatus' not in json_response['app']:
-        raise Fail("Application " + app_url + " returns invalid data.")
-
-      if json_response['app']['state'] != "FINISHED" or json_response['app']['finalStatus'] != "SUCCEEDED":
-        raise Fail("Application " + app_url + " state/status is not valid. Should be FINISHED/SUCCEEDED.")
+    if json_response is None or 'app' not in json_response or \
+            'state' not in json_response['app'] or 'finalStatus' not in json_response['app']:
+      raise Fail("Application " + app_url + " returns invalid data.")
 
+    if json_response['app']['state'] != "FINISHED" or json_response['app']['finalStatus'] != "SUCCEEDED":
+      raise Fail("Application " + app_url + " state/status is not valid. Should be FINISHED/SUCCEEDED.")
 
+  def get_active_rm_webapp_address(self):
+    import params
+    active_rm_webapp_address = None
+    rm_webapp_addresses = params.rm_webapp_addresses_list
+    if rm_webapp_addresses is not None and len(rm_webapp_addresses) > 0:
+      for rm_webapp_address in rm_webapp_addresses:
+        rm_state_url = params.scheme + "://" + rm_webapp_address + "/ws/v1/cluster/info"
+        get_cluster_info_cmd = "curl --negotiate -u : -ks --location-trusted --connect-timeout " + CURL_CONNECTION_TIMEOUT + " " + rm_state_url
+        try:
+          return_code, stdout, _ = get_user_call_output(get_cluster_info_cmd,
+                                                        user=params.smokeuser,
+                                                        path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
+                                                        )
+          json_response = json.loads(stdout)
+          if json_response is not None and 'clusterInfo' in json_response \
+            and json_response['clusterInfo']['haState'] == "ACTIVE":
+              active_rm_webapp_address = rm_webapp_address
+              break
+        except Exception as e:
+          Logger.warning(format("Cluster info is not available from calling {get_cluster_info_cmd}"))
+
+    if active_rm_webapp_address is None:
+      raise Fail('Resource Manager state is not available. Failed to determine the active Resource Manager web application address from {0}'.format(','.join(rm_webapp_addresses)));
+    return active_rm_webapp_address
 
 if __name__ == "__main__":
   ServiceCheck().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/88e0c29e/ambari-server/src/test/python/stacks/2.0.6/YARN/test_yarn_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_yarn_service_check.py b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_yarn_service_check.py
index bb671aa..fe7456d 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_yarn_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_yarn_service_check.py
@@ -22,11 +22,11 @@ import re
 from mock.mock import MagicMock, call, patch
 from stacks.utils.RMFTestCase import *
 
-curl_call = MagicMock(return_value=(0, "{ \"app\": {\"state\": \"FINISHED\",\"finalStatus\": \"SUCCEEDED\"}}",''))
+curl_returns = [(0, "{\"clusterInfo\":{\"id\": \"1471586271500\",\"haState\": \"ACTIVE\"}}",''),
+                         (0, "{\"app\":{\"state\": \"FINISHED\",\"finalStatus\":\"SUCCEEDED\"}}",'')]
 
 @patch("platform.linux_distribution", new = MagicMock(return_value="Linux"))
 @patch("sys.executable", new = '/usr/bin/python2.6')
-@patch("resource_management.libraries.functions.get_user_call_output.get_user_call_output", new = curl_call)
 class TestServiceCheck(RMFTestCase):
   COMMON_SERVICES_PACKAGE_DIR = "YARN/2.1.0.2.0/package"
   STACK_VERSION = "2.0.6"
@@ -38,32 +38,32 @@ class TestServiceCheck(RMFTestCase):
     re_search_mock.return_value = m
     m.group.return_value = "http://c6402.ambari.apache.org:8088/proxy/application_1429699682952_0010/"
 
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
-                          classname="ServiceCheck",
-                          command="service_check",
-                          config_file="default.json",
-                          stack_version = self.STACK_VERSION,
-                          target = RMFTestCase.TARGET_COMMON_SERVICES,
-                          checked_call_mocks = [(0, "some test text, appTrackingUrl=http:"
-                                "//c6402.ambari.apache.org:8088/proxy/application_1429885383763_0001/, some test text")]
-    )
-    self.assertResourceCalled('HdfsResource', '/user/ambari-qa',
-                              immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
-                              security_enabled = False,
-                              hadoop_bin_dir = '/usr/bin',
-                              keytab = UnknownConfigurationMock(),
-                              kinit_path_local = '/usr/bin/kinit',
-                              user = 'hdfs',
-                              dfs_type = '',
-                              mode = 0770,
-                              owner = 'ambari-qa',
-                              action = ['create_on_execute'], hdfs_resource_ignore_file='/var/lib/ambari-agent/data/.hdfs_resource_ignore', hdfs_site=self.getConfig()['configurations']['hdfs-site'], principal_name=UnknownConfigurationMock(), default_fs='hdfs://c6401.ambari.apache.org:8020',
-                              hadoop_conf_dir = '/etc/hadoop/conf',
-                              type = 'directory',
-                              )
-    self.assertCurlCallForwardsCredentialsOnRedirect()
-    self.assertNoMoreResources()
-
+    with patch("resource_management.libraries.functions.get_user_call_output.get_user_call_output", side_effect = curl_returns) as mock_curl:
+        self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
+                           classname="ServiceCheck",
+                           command="service_check",
+                           config_file="default.json",
+                           stack_version = self.STACK_VERSION,
+                           target = RMFTestCase.TARGET_COMMON_SERVICES,
+                           checked_call_mocks = [(0, "some test text, appTrackingUrl=http:"
+                                                  "//c6402.ambari.apache.org:8088/proxy/application_1429885383763_0001/, some test text")]
+                           )
+        self.assertResourceCalled('HdfsResource', '/user/ambari-qa',
+                                  immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
+                                  security_enabled = False,
+                                  hadoop_bin_dir = '/usr/bin',
+                                  keytab = UnknownConfigurationMock(),
+                                  kinit_path_local = '/usr/bin/kinit',
+                                  user = 'hdfs',
+                                  dfs_type = '',
+                                  mode = 0770,
+                                  owner = 'ambari-qa',
+                                  action = ['create_on_execute'], hdfs_resource_ignore_file='/var/lib/ambari-agent/data/.hdfs_resource_ignore', hdfs_site=self.getConfig()['configurations']['hdfs-site'], principal_name=UnknownConfigurationMock(), default_fs='hdfs://c6401.ambari.apache.org:8020',
+                                  hadoop_conf_dir = '/etc/hadoop/conf',
+                                  type = 'directory',
+                                  )
+        self.assertCurlCallForwardsCredentialsOnRedirect(mock_curl_call = mock_curl)
+        self.assertNoMoreResources()
 
   @patch("re.search")
   def test_service_check_secured(self, re_search_mock):
@@ -71,31 +71,32 @@ class TestServiceCheck(RMFTestCase):
     re_search_mock.return_value = m
     m.group.return_value = "http://c6402.ambari.apache.org:8088/proxy/application_1429699682952_0010/"
 
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
-                          classname="ServiceCheck",
-                          command="service_check",
-                          config_file="secured.json",
-                          stack_version = self.STACK_VERSION,
-                          target = RMFTestCase.TARGET_COMMON_SERVICES,
-                          checked_call_mocks = [(0, "some test text, appTrackingUrl=http:"
-                               "//c6402.ambari.apache.org:8088/proxy/application_1429885383763_0001/, some test text")]
-    )
-    self.assertResourceCalled('HdfsResource', '/user/ambari-qa',
-                              immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
-                              security_enabled = True,
-                              hadoop_bin_dir = '/usr/bin',
-                              keytab = '/etc/security/keytabs/hdfs.headless.keytab',
-                              kinit_path_local = '/usr/bin/kinit',
-                              user = 'hdfs',
-                              dfs_type = '',
-                              mode = 0770,
-                              owner = 'ambari-qa',
-                              action = ['create_on_execute'], hdfs_resource_ignore_file='/var/lib/ambari-agent/data/.hdfs_resource_ignore', hdfs_site=self.getConfig()['configurations']['hdfs-site'], principal_name='hdfs', default_fs='hdfs://c6401.ambari.apache.org:8020',
-                              hadoop_conf_dir = '/etc/hadoop/conf',
-                              type = 'directory',
-                              )
-    self.assertCurlCallForwardsCredentialsOnRedirect()
-    self.assertNoMoreResources()
+    with patch("resource_management.libraries.functions.get_user_call_output.get_user_call_output", side_effect = curl_returns) as mock_curl:
+        self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/service_check.py",
+                           classname="ServiceCheck",
+                           command="service_check",
+                           config_file="secured.json",
+                           stack_version = self.STACK_VERSION,
+                           target = RMFTestCase.TARGET_COMMON_SERVICES,
+                           checked_call_mocks = [(0, "some test text, appTrackingUrl=http:"
+                                                  "//c6402.ambari.apache.org:8088/proxy/application_1429885383763_0001/, some test text")]
+                           )
+        self.assertResourceCalled('HdfsResource', '/user/ambari-qa',
+                                  immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
+                                  security_enabled = True,
+                                  hadoop_bin_dir = '/usr/bin',
+                                  keytab = '/etc/security/keytabs/hdfs.headless.keytab',
+                                  kinit_path_local = '/usr/bin/kinit',
+                                  user = 'hdfs',
+                                  dfs_type = '',
+                                  mode = 0770,
+                                  owner = 'ambari-qa',
+                                  action = ['create_on_execute'], hdfs_resource_ignore_file='/var/lib/ambari-agent/data/.hdfs_resource_ignore', hdfs_site=self.getConfig()['configurations']['hdfs-site'], principal_name='hdfs', default_fs='hdfs://c6401.ambari.apache.org:8020',
+                                  hadoop_conf_dir = '/etc/hadoop/conf',
+                                  type = 'directory',
+                                  )
+        self.assertCurlCallForwardsCredentialsOnRedirect(mock_curl_call = mock_curl)
+        self.assertNoMoreResources()
 
-  def assertCurlCallForwardsCredentialsOnRedirect(self):
-    self.assertIn('--location-trusted', curl_call.call_args[0][0])
\ No newline at end of file
+  def assertCurlCallForwardsCredentialsOnRedirect(self, mock_curl_call):
+    self.assertIn('--location-trusted', mock_curl_call.call_args[0][0])


[18/24] ambari git commit: AMBARI-19053. RU: wrong version exposed when Downgrade is going (ncole)

Posted by jo...@apache.org.
AMBARI-19053. RU: wrong version exposed when Downgrade is going (ncole)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7eb2eaa7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7eb2eaa7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7eb2eaa7

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 7eb2eaa73315189533e039b45cf90655adf25390
Parents: 232a9d8
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Dec 1 16:26:21 2016 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Dec 2 11:19:20 2016 -0500

----------------------------------------------------------------------
 .../internal/UpgradeResourceProvider.java       | 24 ++++++++++++++++----
 .../internal/UpgradeResourceProviderTest.java   |  4 ++--
 2 files changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7eb2eaa7/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 9034989..5931743 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -758,13 +758,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     upgradeContext.setSupportedServices(supportedServices);
     upgradeContext.setScope(scope);
 
+    String downgradeFromVersion = null;
+
     if (direction.isDowngrade()) {
       if (requestMap.containsKey(UPGRADE_FROM_VERSION)) {
-        upgradeContext.setDowngradeFromVersion((String) requestMap.get(UPGRADE_FROM_VERSION));
+        downgradeFromVersion = (String) requestMap.get(UPGRADE_FROM_VERSION);
       } else {
         UpgradeEntity lastUpgradeItemForCluster = s_upgradeDAO.findLastUpgradeForCluster(cluster.getClusterId());
-        upgradeContext.setDowngradeFromVersion(lastUpgradeItemForCluster.getToVersion());
+        downgradeFromVersion = lastUpgradeItemForCluster.getToVersion();
       }
+
+      upgradeContext.setDowngradeFromVersion(downgradeFromVersion);
     }
 
     // optionally skip failures - this can be supplied on either the request or
@@ -922,7 +926,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     }
 
     UpgradeEntity entity = new UpgradeEntity();
-    entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
+
+    if (null != downgradeFromVersion) {
+      entity.setFromVersion(downgradeFromVersion);
+    } else {
+      entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
+    }
+
     entity.setToVersion(version);
     entity.setUpgradeGroups(groupEntities);
     entity.setClusterId(cluster.getClusterId());
@@ -931,7 +941,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     entity.setUpgradeType(pack.getType());
     entity.setAutoSkipComponentFailures(skipComponentFailures);
     entity.setAutoSkipServiceCheckFailures(skipServiceCheckFailures);
-    entity.setDowngradeAllowed(pack.isDowngradeAllowed());
+
+    if (upgradeContext.getDirection().isDowngrade()) {
+      // !!! You can't downgrade a Downgrade, no matter what the upgrade pack says.
+      entity.setDowngradeAllowed(false);
+    } else {
+      entity.setDowngradeAllowed(pack.isDowngradeAllowed());
+    }
 
     req.getRequestStatusResponse();
     return createUpgradeInsideTransaction(cluster, req, entity);

http://git-wip-us.apache.org/repos/asf/ambari/blob/7eb2eaa7/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
index 14e3d08..8efcc61 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
@@ -708,7 +708,7 @@ public class UpgradeResourceProviderTest {
 
     UpgradeEntity entity = upgradeDao.findUpgrade(Long.parseLong(id));
     assertNotNull(entity);
-    assertEquals("2.1.1", entity.getFromVersion());
+    assertEquals("2.1.1.0", entity.getFromVersion());
     assertEquals("2.2.0.0", entity.getToVersion());
     assertEquals(Direction.DOWNGRADE, entity.getDirection());
 
@@ -1249,7 +1249,7 @@ public class UpgradeResourceProviderTest {
       Map<String, String> map = gson.<Map<String, String>> fromJson(se.getCommandParamsStage(),Map.class);
       assertTrue(map.containsKey("upgrade_direction"));
       assertEquals("upgrade", map.get("upgrade_direction"));
-      
+
       if(map.containsKey("upgrade_type")){
         assertEquals("rolling_upgrade", map.get("upgrade_type"));
       }


[16/24] ambari git commit: Revert "AMBARI-18888: Ambari-agent: Create configuration files with JCEKS information"

Posted by jo...@apache.org.
Revert "AMBARI-18888: Ambari-agent: Create configuration files with JCEKS information"

This reverts commit 615438b272e6bd8efd37481ef684ae7d68921e64.


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/60a6bd45
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/60a6bd45
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/60a6bd45

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 60a6bd4575fb87fc26c4a277cbabf850ef2089e1
Parents: 32840c1
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Dec 2 10:50:50 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Dec 2 10:50:50 2016 -0500

----------------------------------------------------------------------
 ambari-agent/conf/unix/ambari-agent.ini         |   3 -
 .../ambari_agent/CustomServiceOrchestrator.py   | 120 -------------------
 ambari-agent/src/packages/tarball/all.xml       |  30 -----
 .../ambari/server/agent/ExecutionCommand.java   |  28 -----
 .../ambari/server/agent/HeartBeatHandler.java   |  10 +-
 .../server/agent/TestHeartbeatHandler.java      |  28 ++---
 6 files changed, 9 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-agent/conf/unix/ambari-agent.ini
----------------------------------------------------------------------
diff --git a/ambari-agent/conf/unix/ambari-agent.ini b/ambari-agent/conf/unix/ambari-agent.ini
index d6fcf5f..61948d4 100644
--- a/ambari-agent/conf/unix/ambari-agent.ini
+++ b/ambari-agent/conf/unix/ambari-agent.ini
@@ -46,9 +46,6 @@ keysdir=/var/lib/ambari-agent/keys
 server_crt=ca.crt
 passphrase_env_var_name=AMBARI_PASSPHRASE
 ssl_verify_cert=0
-credential_lib_dir=/var/lib/ambari-agent/cred/lib
-credential_conf_dir=/var/lib/ambari-agent/cred/conf
-credential_shell_cmd=org.apache.hadoop.security.alias.CredentialShell
 
 [services]
 pidLookupPath=/var/run/

http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index 1eab0a5..7d61611 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -29,8 +29,6 @@ from FileCache import FileCache
 from AgentException import AgentException
 from PythonExecutor import PythonExecutor
 from PythonReflectiveExecutor import PythonReflectiveExecutor
-from resource_management.core.utils import PasswordString
-import subprocess
 import Constants
 import hostname
 
@@ -67,11 +65,6 @@ class CustomServiceOrchestrator():
   REFLECTIVELY_RUN_COMMANDS = FREQUENT_COMMANDS # -- commands which run a lot and often (this increases their speed)
   DONT_BACKUP_LOGS_FOR_COMMANDS = FREQUENT_COMMANDS
 
-  # Path where hadoop credential JARS will be available
-  DEFAULT_CREDENTIAL_SHELL_LIB_PATH = '/var/lib/ambari-agent/cred/lib'
-  DEFAULT_CREDENTIAL_CONF_DIR = '/var/lib/ambari-agent/cred/conf'
-  DEFAULT_CREDENTIAL_SHELL_CMD = 'org.apache.hadoop.security.alias.CredentialShell'
-
   def __init__(self, config, controller):
     self.config = config
     self.tmp_dir = config.get('agent', 'prefix')
@@ -85,14 +78,6 @@ class CustomServiceOrchestrator():
     # cache reset will be called on every agent registration
     controller.registration_listeners.append(self.file_cache.reset)
 
-    # Construct the hadoop credential lib JARs path
-    self.credential_shell_lib_path = os.path.join(config.get('security', 'credential_lib_dir',
-                                                             self.DEFAULT_CREDENTIAL_SHELL_LIB_PATH), '*')
-
-    self.credential_conf_dir = config.get('security', 'credential_conf_dir', self.DEFAULT_CREDENTIAL_CONF_DIR)
-
-    self.credential_shell_cmd = config.get('security', 'credential_shell_cmd', self.DEFAULT_CREDENTIAL_SHELL_CMD)
-
     # Clean up old status command files if any
     try:
       os.unlink(self.status_commands_stdout)
@@ -129,102 +114,6 @@ class CustomServiceOrchestrator():
     else:
       return PythonExecutor(self.tmp_dir, self.config)
 
-  def getProviderDirectory(self, service_name):
-    """
-    Gets the path to the service conf folder where the JCEKS file will be created.
-
-    :param service_name: Name of the service, for example, HIVE
-    :return: lower case path to the service conf folder
-    """
-
-    # The stack definition scripts of the service can move the
-    # JCEKS file around to where it wants, which is usually
-    # /etc/<service_name>/conf
-
-    conf_dir = os.path.join(self.credential_conf_dir, service_name.lower())
-    if not os.path.exists(conf_dir):
-      os.makedirs(conf_dir, 0644)
-
-    return conf_dir
-
-  def getAffectedConfigTypes(self, commandJson):
-    """
-    Gets the affected config types for the service in this command
-
-    :param commandJson:
-    :return:
-    """
-    return commandJson.get('configuration_attributes')
-
-  def getCredentialProviderPropertyName(self):
-    """
-    Gets the property name used by the hadoop credential provider
-    :return:
-    """
-    return 'hadoop.security.credential.provider.path'
-
-  def generateJceks(self, commandJson):
-    """
-    Generates the JCEKS file with passwords for the service specified in commandJson
-
-    :param commandJson: command JSON
-    :return: An exit value from the external process that generated the JCEKS file. None if
-    there are no passwords in the JSON.
-    """
-    cmd_result = None
-    roleCommand = None
-    if 'roleCommand' in commandJson:
-      roleCommand = commandJson['roleCommand']
-
-    logger.info('generateJceks: roleCommand={0}'.format(roleCommand))
-
-    # Password properties for a config type, if present,
-    # are under configuration_attributes:config_type:hidden:{prop1:attributes1, prop2, attributes2}
-    passwordProperties = {}
-    config_types = self.getAffectedConfigTypes(commandJson)
-    for config_type in config_types:
-      elem = config_types.get(config_type)
-      hidden = elem.get('hidden')
-      if hidden is not None:
-        passwordProperties[config_type] = hidden
-
-    # Set up the variables for the external command to generate a JCEKS file
-    java_home = commandJson['hostLevelParams']['java_home']
-    java_bin = '{java_home}/bin/java'.format(java_home=java_home)
-
-    cs_lib_path = self.credential_shell_lib_path
-    serviceName = commandJson['serviceName']
-
-    # Gather the password values and remove them from the configuration
-    configs = commandJson.get('configurations')
-    for key, value in passwordProperties.items():
-      config = configs.get(key)
-      if config is not None:
-        file_path = os.path.join(self.getProviderDirectory(serviceName), "{0}.jceks".format(key))
-        if os.path.exists(file_path):
-          os.remove(file_path)
-        provider_path = 'jceks://file{file_path}'.format(file_path=file_path)
-        logger.info('provider_path={0}'.format(provider_path))
-        for alias in value:
-          pwd = config.get(alias)
-          if pwd is not None:
-            # Remove the clear text password
-            config.pop(alias, None)
-            # Add JCEKS provider path instead
-            config[self.getCredentialProviderPropertyName()] = provider_path
-            logger.debug("config={0}".format(config))
-            protected_pwd = PasswordString(pwd)
-            # Generate the JCEKS file
-            cmd = (java_bin, '-cp', cs_lib_path, self.credential_shell_cmd, 'create',
-                   alias, '-value', protected_pwd, '-provider', provider_path)
-            logger.info(cmd)
-            cmd_result = subprocess.call(cmd)
-            logger.info('cmd_result = {0}'.format(cmd_result))
-            os.chmod(file_path, 0644) # group and others should have read access so that the service user can read
-
-    return cmd_result
-
-
   def runCommand(self, command, tmpoutfile, tmperrfile, forced_command_name=None,
                  override_output_files=True, retry=False):
     """
@@ -290,15 +179,6 @@ class CustomServiceOrchestrator():
         handle.on_background_command_started = self.map_task_to_process
         del command['__handle']
 
-      # If command contains credentialStoreEnabled, then
-      # generate the JCEKS file for the configurations.
-      credentialStoreEnabled = False
-      if 'credentialStoreEnabled' in command:
-        credentialStoreEnabled = (command['credentialStoreEnabled'] == "true")
-
-      if credentialStoreEnabled == True:
-        self.generateJceks(command)
-
       json_path = self.dump_command_to_json(command, retry)
       pre_hook_tuple = self.resolve_hook_script_path(hook_dir,
           self.PRE_HOOK_PREFIX, command_name, script_type)

http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-agent/src/packages/tarball/all.xml
----------------------------------------------------------------------
diff --git a/ambari-agent/src/packages/tarball/all.xml b/ambari-agent/src/packages/tarball/all.xml
index f8a54e3..c481208 100644
--- a/ambari-agent/src/packages/tarball/all.xml
+++ b/ambari-agent/src/packages/tarball/all.xml
@@ -190,34 +190,4 @@
       <outputDirectory>/var/lib/${project.artifactId}/data</outputDirectory>
     </file>
   </files>
-  <moduleSets>
-    <moduleSet>
-      <binaries>
-        <includeDependencies>false</includeDependencies>
-        <outputDirectory>/var/lib/${project.artifactId}/cred/lib</outputDirectory>
-        <unpack>false</unpack>
-        <directoryMode>755</directoryMode>
-        <fileMode>644</fileMode>
-        <dependencySets>
-          <dependencySet>
-            <outputDirectory>/var/lib/${project.artifactId}/cred/lib</outputDirectory>
-            <unpack>false</unpack>
-            <includes>
-              <include>commons-cli:commons-cli</include>
-              <include>commons-collections:commons-collections</include>
-              <include>commons-configuration:commons-configuration</include>
-              <include>commons-io:commons-io:jar:${commons.io.version}</include>
-              <include>commons-lang:commons-lang</include>
-              <include>commons-logging:commons-logging</include>
-              <include>com.google.guava:guava</include>
-              <include>org.slf4j:slf4j-api</include>
-              <include>org.apache.hadoop:hadoop-common</include>
-              <include>org.apache.hadoop:hadoop-auth</include>
-              <include>org.apache.htrace:htrace-core</include>
-            </includes>
-          </dependencySet>
-        </dependencySets>
-      </binaries>
-    </moduleSet>
-  </moduleSets>
 </assembly>

http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 7353366..29737ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -112,13 +112,6 @@ public class ExecutionCommand extends AgentCommand {
   @SerializedName("availableServices")
   private Map<String, String> availableServices = new HashMap<>();
 
-  /**
-   * "true" or "false" indicating whether this
-   * service is enabled for credential store use.
-   */
-  @SerializedName("credentialStoreEnabled")
-  private String credentialStoreEnabled;
-
   public String getCommandId() {
     return commandId;
   }
@@ -302,27 +295,6 @@ public class ExecutionCommand extends AgentCommand {
 	this.serviceType = serviceType;
   }
 
-  /**
-   * Get a value indicating whether this service is enabled
-   * for credential store use.
-   *
-   * @return "true" or "false", any other value is
-   * considered as "false"
-   */
-  public String getCredentialStoreEnabled() {
-    return credentialStoreEnabled;
-  }
-
-  /**
-   * Set a value indicating whether this service is enabled
-   * for credential store use.
-   *
-   * @param credentialStoreEnabled
-   */
-  public void setCredentialStoreEnabled(String credentialStoreEnabled) {
-    this.credentialStoreEnabled = credentialStoreEnabled;
-  }
-
   public String getComponentName() {
     return componentName;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index 48d11c4..75bef30 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -329,15 +329,7 @@ public class HeartBeatHandler {
           case BACKGROUND_EXECUTION_COMMAND:
           case EXECUTION_COMMAND: {
             ExecutionCommand ec = (ExecutionCommand)ac;
-            /*
-             * Set the value of credentialStore enabled before sending the command to agent.
-             */
-            Cluster cluster = clusterFsm.getCluster(ec.getClusterName());
-            Service service = cluster.getService(ec.getServiceName());
-            if (service != null) {
-              ec.setCredentialStoreEnabled(String.valueOf(service.isCredentialStoreEnabled()));
-            }
-            LOG.info("HeartBeatHandler.sendCommands: sending ExecutionCommand for host {}, role {}, roleCommand {}, and command ID {}, task ID {}",
+            LOG.info("HeartBeatHandler.sendCommands: sending ExecutionCommand for host {}, role {}, roleCommand {}, and command ID {}, taskId {}",
                      ec.getHostname(), ec.getRole(), ec.getRoleCommand(), ec.getCommandId(), ec.getTaskId());
             Map<String, String> hlp = ec.getHostLevelParams();
             if (hlp != null) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/60a6bd45/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index ac58f64..a50a116 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -48,7 +48,6 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -172,31 +171,22 @@ public class TestHeartbeatHandler {
     ActionManager am = actionManagerTestHelper.getMockActionManager();
     expect(am.getTasks(anyObject(List.class))).andReturn(new ArrayList<HostRoleCommand>());
     replay(am);
-
-    Cluster cluster = heartbeatTestHelper.getDummyCluster();
-    Service hdfs = cluster.addService(HDFS);
-    hdfs.addServiceComponent(DATANODE);
-    hdfs.addServiceComponent(NAMENODE);
-    hdfs.addServiceComponent(SECONDARY_NAMENODE);
-    Collection<Host> hosts = cluster.getHosts();
-    assertEquals(hosts.size(), 1);
-
     Clusters fsm = clusters;
-    Host hostObject = hosts.iterator().next();
+    fsm.addHost(DummyHostname1);
+    Host hostObject = clusters.getHost(DummyHostname1);
     hostObject.setIPv4("ipv4");
     hostObject.setIPv6("ipv6");
     hostObject.setOsType(DummyOsType);
 
-    String hostname = hostObject.getHostName();
     ActionQueue aq = new ActionQueue();
 
     HeartBeatHandler handler = new HeartBeatHandler(fsm, aq, am, injector);
     Register reg = new Register();
     HostInfo hi = new HostInfo();
-    hi.setHostName(hostname);
+    hi.setHostName(DummyHostname1);
     hi.setOS(DummyOs);
     hi.setOSRelease(DummyOSRelease);
-    reg.setHostname(hostname);
+    reg.setHostname(DummyHostname1);
     reg.setHardwareProfile(hi);
     reg.setAgentVersion(metaInfo.getServerVersion());
     handler.handleRegistration(reg);
@@ -205,21 +195,19 @@ public class TestHeartbeatHandler {
 
     ExecutionCommand execCmd = new ExecutionCommand();
     execCmd.setRequestAndStage(2, 34);
-    execCmd.setHostname(hostname);
-    execCmd.setClusterName(cluster.getClusterName());
-    execCmd.setServiceName(HDFS);
-    aq.enqueue(hostname, execCmd);
+    execCmd.setHostname(DummyHostname1);
+    aq.enqueue(DummyHostname1, new ExecutionCommand());
     HeartBeat hb = new HeartBeat();
     hb.setResponseId(0);
     HostStatus hs = new HostStatus(Status.HEALTHY, DummyHostStatus);
     List<Alert> al = new ArrayList<Alert>();
     al.add(new Alert());
     hb.setNodeStatus(hs);
-    hb.setHostname(hostname);
+    hb.setHostname(DummyHostname1);
 
     handler.handleHeartBeat(hb);
     assertEquals(HostState.HEALTHY, hostObject.getState());
-    assertEquals(0, aq.dequeueAll(hostname).size());
+    assertEquals(0, aq.dequeueAll(DummyHostname1).size());
   }
 
 


[15/24] ambari git commit: AMBARI-19055 - Removing Tasks From host_role_command Causes Upgrades To Show As PENDING (jonathanhurley)

Posted by jo...@apache.org.
AMBARI-19055 - Removing Tasks From host_role_command Causes Upgrades To Show As PENDING (jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/32840c1e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/32840c1e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/32840c1e

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 32840c1ed434ae4cc99e3ab6f7d3f2604fb69d06
Parents: f4ea309
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Dec 1 15:49:06 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Dec 2 10:19:41 2016 -0500

----------------------------------------------------------------------
 .../controller/internal/CalculatedStatus.java   | 52 +++++++++++++++-----
 .../internal/RequestResourceProvider.java       | 34 ++++++++-----
 .../internal/StageResourceProvider.java         |  2 +-
 .../internal/CalculatedStatusTest.java          | 31 ++++++++++++
 .../internal/RequestResourceProviderTest.java   | 12 +++--
 5 files changed, 103 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/32840c1e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
index 3a86aef..3c415df 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
@@ -53,6 +53,17 @@ public class CalculatedStatus {
    */
   private final double percent;
 
+  /**
+   * A status which represents a COMPLETED state at 0%
+   */
+  public static final CalculatedStatus COMPLETED = new CalculatedStatus(HostRoleStatus.COMPLETED,
+      HostRoleStatus.COMPLETED, 100.0);
+
+  /**
+   * A status which represents a PENDING state at 0%
+   */
+  public static final CalculatedStatus PENDING = new CalculatedStatus(HostRoleStatus.PENDING,
+      HostRoleStatus.PENDING, 0.0);
 
   // ----- Constructors ------------------------------------------------------
 
@@ -79,12 +90,6 @@ public class CalculatedStatus {
     this.percent = percent;
   }
 
-  /**
-   * Static factory method to get Status that represents a Completed state
-   */
-  public static CalculatedStatus getCompletedStatus() {
-    return new CalculatedStatus(HostRoleStatus.COMPLETED, HostRoleStatus.COMPLETED, 100.0);
-  }
 
   // ----- CalculatedStatus --------------------------------------------------
 
@@ -291,14 +296,25 @@ public class CalculatedStatus {
   }
 
   /**
-   * Calculates the overall status of an upgrade.
-   * @param stageDto  the map of stage-to-summary value objects
-   * @param stageIds  the stage ids to consider from the value objects
+   * Calculates the overall status of an upgrade. If there are no tasks, then a
+   * status of {@link HostRoleStatus#COMPLETED} is returned.
+   *
+   * @param stageDto
+   *          the map of stage-to-summary value objects
+   * @param stageIds
+   *          the stage ids to consider from the value objects
    * @return the calculated status
    */
   public static CalculatedStatus statusFromStageSummary(Map<Long, HostRoleCommandStatusSummaryDTO> stageDto,
       Set<Long> stageIds) {
 
+    // if either are empty, then we have no tasks and therefore no status - we
+    // should return COMPLETED. This can happen if someone removes all tasks but
+    // leaves the stages and request
+    if (stageDto.isEmpty() || stageIds.isEmpty()) {
+      return COMPLETED;
+    }
+
     Collection<HostRoleStatus> stageStatuses = new HashSet<>();
     Collection<HostRoleStatus> stageDisplayStatuses = new HashSet<>();
     Collection<HostRoleStatus> taskStatuses = new ArrayList<>();
@@ -378,19 +394,28 @@ public class CalculatedStatus {
    */
   public static HostRoleStatus calculateSummaryStatusOfStage(Map<HostRoleStatus, Integer> counters,
       int total, boolean skippable) {
+
+    // when there are 0 tasks, return COMPLETED
+    if (total == 0) {
+      return HostRoleStatus.COMPLETED;
+    }
+
     if (counters.get(HostRoleStatus.PENDING) == total) {
       return HostRoleStatus.PENDING;
     }
+
     // By definition, any tasks in a future stage must be held in a PENDING status.
     if (counters.get(HostRoleStatus.HOLDING) > 0 || counters.get(HostRoleStatus.HOLDING_FAILED) > 0 || counters.get(HostRoleStatus.HOLDING_TIMEDOUT) > 0) {
       return counters.get(HostRoleStatus.HOLDING) > 0 ? HostRoleStatus.HOLDING :
       counters.get(HostRoleStatus.HOLDING_FAILED) > 0 ? HostRoleStatus.HOLDING_FAILED :
       HostRoleStatus.HOLDING_TIMEDOUT;
     }
+
     // Because tasks are not skippable, guaranteed to be FAILED
     if (counters.get(HostRoleStatus.FAILED) > 0 && !skippable) {
       return HostRoleStatus.FAILED;
     }
+
     // Because tasks are not skippable, guaranteed to be TIMEDOUT
     if (counters.get(HostRoleStatus.TIMEDOUT) > 0  && !skippable) {
       return HostRoleStatus.TIMEDOUT;
@@ -401,9 +426,11 @@ public class CalculatedStatus {
     if (counters.get(HostRoleStatus.ABORTED) > 0 && numActiveTasks == 0) {
       return HostRoleStatus.ABORTED;
     }
+
     if (counters.get(HostRoleStatus.COMPLETED) == total) {
       return HostRoleStatus.COMPLETED;
     }
+
     return HostRoleStatus.IN_PROGRESS;
   }
 
@@ -415,7 +442,8 @@ public class CalculatedStatus {
    *
    * @return summary request status based on statuses of tasks in different states.
    */
-  private static HostRoleStatus calculateSummaryStatusOfUpgrade(Map<HostRoleStatus, Integer> counters, int total) {
+  protected static HostRoleStatus calculateSummaryStatusOfUpgrade(
+      Map<HostRoleStatus, Integer> counters, int total) {
     return calculateSummaryStatusOfStage(counters, total, false);
   }
 
@@ -428,8 +456,8 @@ public class CalculatedStatus {
    *
    * @return summary request status based on statuses of tasks in different states.
    */
-  private static HostRoleStatus calculateSummaryDisplayStatus(Map<HostRoleStatus, Integer> counters,
-                                                              int total, boolean skippable) {
+  protected static HostRoleStatus calculateSummaryDisplayStatus(
+      Map<HostRoleStatus, Integer> counters, int total, boolean skippable) {
     return counters.get(HostRoleStatus.SKIPPED_FAILED) > 0 ? HostRoleStatus.SKIPPED_FAILED :
            counters.get(HostRoleStatus.FAILED) > 0 ? HostRoleStatus.FAILED:
            calculateSummaryStatusOfStage(counters, total, skippable);

http://git-wip-us.apache.org/repos/asf/ambari/blob/32840c1e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
index 8c1bc57..0690ee7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
@@ -69,10 +69,10 @@ import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.topology.LogicalRequest;
 import org.apache.ambari.server.topology.TopologyManager;
+import org.apache.commons.lang.StringUtils;
 
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
-import org.apache.commons.lang.StringUtils;
 
 /**
  * Resource provider for request resources.
@@ -566,13 +566,18 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
 
     @Override
     public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
+      if (this == o) {
+        return true;
+      }
+      if (o == null || getClass() != o.getClass()) {
+        return false;
+      }
 
       ServiceComponentTuple that = (ServiceComponentTuple) o;
 
-      if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null)
+      if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) {
         return false;
+      }
       return !(componentName != null ? !componentName.equals(that.componentName) : that.componentName != null);
 
     }
@@ -739,15 +744,20 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
     // get summaries from TopologyManager for logical requests
     summary.putAll(topologyManager.getStageSummaries(entity.getRequestId()));
 
+    // summary might be empty due to delete host have cleared all
+    // HostRoleCommands or due to hosts haven't registered yet with the cluster
+    // when the cluster is provisioned with a Blueprint
+    final CalculatedStatus status;
     LogicalRequest logicalRequest = topologyManager.getRequest(entity.getRequestId());
-
-    CalculatedStatus status = CalculatedStatus.statusFromStageSummary(summary, summary.keySet());
-    if (summary.isEmpty() && logicalRequest == null) {
-
-      // summary might be empty due to delete host have cleared all HostRoleCommands
-      // or due to hosts haven't registered yet with the cluster when the cluster is provisioned
-      // with a Blueprint
-      status = CalculatedStatus.getCompletedStatus();
+    if (summary.isEmpty() && null != logicalRequest) {
+      // in this case, it appears that there are no tasks but this is a logical
+      // topology request, so it's a matter of hosts simply not registering yet
+      // for tasks to be created
+      status = CalculatedStatus.PENDING;
+    } else {
+      // there are either tasks or this is not a logical request, so do normal
+      // status calculations
+      status = CalculatedStatus.statusFromStageSummary(summary, summary.keySet());
     }
 
     setResourceProperty(resource, REQUEST_STATUS_PROPERTY_ID, status.getStatus().toString(), requestedPropertyIds);

http://git-wip-us.apache.org/repos/asf/ambari/blob/32840c1e/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
index 59dd9d9..a778882 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StageResourceProvider.java
@@ -339,7 +339,7 @@ public class StageResourceProvider extends AbstractControllerResourceProvider im
     CalculatedStatus status;
     if (summary.isEmpty()) {
       // Delete host might have cleared all HostRoleCommands
-      status = CalculatedStatus.getCompletedStatus();
+      status = CalculatedStatus.COMPLETED;
     } else {
       status = CalculatedStatus.statusFromStageSummary(summary, Collections.singleton(entity.getStageId()));
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/32840c1e/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
index 6f592cd..a96f395 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CalculatedStatusTest.java
@@ -657,6 +657,37 @@ public class CalculatedStatusTest {
     assertEquals(HostRoleStatus.IN_PROGRESS, calc.getStatus());
   }
 
+  /**
+   * Tests that when there are no tasks and all counts are 0, that the returned
+   * status is {@link HostRoleStatus#COMPLETED}.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testGetCompletedStatusForNoTasks() throws Exception {
+    // no status / no tasks
+    CalculatedStatus status = CalculatedStatus.statusFromTaskEntities(
+        new ArrayList<HostRoleCommandEntity>(), false);
+
+    assertEquals(HostRoleStatus.COMPLETED, status.getStatus());
+
+    // empty summaries
+    status = CalculatedStatus.statusFromStageSummary(
+        new HashMap<Long, HostRoleCommandStatusSummaryDTO>(), new HashSet<Long>());
+
+    assertEquals(HostRoleStatus.COMPLETED, status.getStatus());
+
+    // generate a map of 0's - COMPLETED=0, IN_PROGRESS=0, etc
+    Map<HostRoleStatus, Integer> counts = CalculatedStatus.calculateStatusCounts(new ArrayList<HostRoleStatus>());
+    Map<HostRoleStatus, Integer> displayCounts = CalculatedStatus.calculateStatusCounts(new ArrayList<HostRoleStatus>());
+
+    HostRoleStatus hostRoleStatus = CalculatedStatus.calculateSummaryStatusOfUpgrade(counts, 0);
+    HostRoleStatus hostRoleDisplayStatus = CalculatedStatus.calculateSummaryDisplayStatus(displayCounts, 0, false);
+
+    assertEquals(HostRoleStatus.COMPLETED, hostRoleStatus);
+    assertEquals(HostRoleStatus.COMPLETED, hostRoleDisplayStatus);
+  }
+
   private Collection<HostRoleCommandEntity> getTaskEntities(HostRoleStatus... statuses) {
     Collection<HostRoleCommandEntity> entities = new LinkedList<HostRoleCommandEntity>();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/32840c1e/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
index 5dfc74d..f7dff11 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
@@ -20,11 +20,10 @@ package org.apache.ambari.server.controller.internal;
 
 
 import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID;
-import org.apache.ambari.server.topology.Blueprint;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.newCapture;
 import static org.powermock.api.easymock.PowerMock.createMock;
 import static org.powermock.api.easymock.PowerMock.createNiceMock;
@@ -77,6 +76,7 @@ import org.apache.ambari.server.security.authorization.AuthorizationHelperInitia
 import org.apache.ambari.server.security.authorization.RoleAuthorization;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.topology.Blueprint;
 import org.apache.ambari.server.topology.ClusterTopology;
 import org.apache.ambari.server.topology.HostGroupInfo;
 import org.apache.ambari.server.topology.LogicalRequest;
@@ -1200,7 +1200,7 @@ public class RequestResourceProviderTest {
       }
     }
     Assert.assertNotNull(propertyIdToAssert);
-    Assert.assertEquals("true", (String) propertyValueToAssert);
+    Assert.assertEquals("true", propertyValueToAssert);
   }
 
   @Test
@@ -1624,6 +1624,12 @@ public class RequestResourceProviderTest {
     verify(managementController, actionManager, clusters, requestMock, requestDAO, hrcDAO);
   }
 
+  /**
+   * Tests that topology requests return different status (PENDING) if there are
+   * no tasks. Normal requests should return COMPLETED.
+   *
+   * @throws Exception
+   */
   @Test
   @PrepareForTest(AmbariServer.class)
   public void testGetLogicalRequestStatusWithNoTasks() throws Exception {


[24/24] ambari git commit: Merge branch 'trunk' into branch-feature-AMBARI-18456

Posted by jo...@apache.org.
Merge branch 'trunk' into branch-feature-AMBARI-18456


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a58c39c9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a58c39c9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a58c39c9

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: a58c39c9c177da52c32dd6f004cefa9658e9019d
Parents: 087de8b 0c837a6
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Dec 2 16:19:40 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Dec 2 16:19:40 2016 -0500

----------------------------------------------------------------------
 .../admin-web/app/scripts/services/Cluster.js   |  51 --
 .../app/scripts/services/RoleDetailsModal.js    |  31 +-
 .../app/views/modals/RoleDetailsModal.html      |   6 +-
 .../src/main/python/ambari_agent/ActionQueue.py |  11 +
 .../ambari_agent/CustomServiceOrchestrator.py   |   7 +-
 .../src/main/python/ambari_agent/FileCache.py   |  12 +-
 .../test/python/ambari_agent/TestActionQueue.py |  48 ++
 .../TestCustomServiceOrchestrator.py            |  30 +-
 .../test/python/ambari_agent/TestFileCache.py   |  10 +-
 .../ambari_commons/ambari_metrics_helper.py     |  45 +-
 .../timeline/AbstractTimelineMetricsSink.java   |   6 +-
 .../AbstractTimelineMetricSinkTest.java         |  10 +-
 .../conf/unix/ambari-metrics-grafana            |   6 +-
 .../timeline/HadoopTimelineMetricsSink.java     |   4 +-
 .../timeline/HadoopTimelineMetricsSinkTest.java |   6 +-
 .../src/main/python/core/config_reader.py       |   9 +-
 .../src/test/python/core/TestEmitter.py         |   2 +-
 .../ambari/server/agent/ExecutionCommand.java   |   1 +
 .../AmbariManagementControllerImpl.java         |   9 +
 .../controller/internal/CalculatedStatus.java   |  52 +-
 .../internal/RequestResourceProvider.java       |  34 +-
 .../internal/StageResourceProvider.java         |   2 +-
 .../internal/UpgradeResourceProvider.java       |  24 +-
 .../orm/AmbariJpaLocalTxnInterceptor.java       |   9 +-
 .../ambari/server/state/ComponentInfo.java      |  14 +
 .../stack/upgrade/ConfigurationCondition.java   |  72 +-
 .../server/upgrade/UpgradeCatalog211.java       |  24 +-
 .../server/upgrade/UpgradeCatalog250.java       |   6 +
 .../ambari/server/utils/RequestUtils.java       |  10 +
 .../python/ambari_server/serverConfiguration.py |  14 +-
 .../src/main/python/ambari_server/utils.py      |  23 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  11 +-
 .../1.6.1.2.2.0/package/scripts/params.py       |   2 +-
 .../AMBARI_METRICS/0.1.0/metainfo.xml           |   1 +
 .../0.1.0/package/scripts/params.py             |   2 +-
 .../0.1.0/package/scripts/service_check.py      |   2 +-
 .../FLUME/1.4.0.2.0/package/scripts/params.py   |   2 +-
 .../0.96.0.2.0/package/scripts/params_linux.py  |   2 +-
 .../package/alerts/alert_metrics_deviation.py   |   2 +-
 .../KAFKA/0.8.1/package/scripts/params.py       |   2 +-
 .../STORM/0.9.1/package/scripts/params_linux.py |   2 +-
 .../2.1.0.2.0/package/scripts/service_check.py  |  66 +-
 .../ZOOKEEPER/3.4.6/metainfo.xml                |   2 +-
 .../2.0.6/hooks/before-START/scripts/params.py  |   2 +-
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml |  27 +-
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml |  27 +-
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml |  27 +-
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml |  27 +-
 .../services/HDFS/configuration/hadoop-env.xml  | 176 ++++
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml |  27 +-
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml |  27 +-
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml |  27 +-
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml |  27 +-
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml |  27 +-
 .../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml |  27 +-
 .../2.1/hooks/before-START/scripts/params.py    |   4 +-
 .../src/main/resources/upgrade-pack.xsd         |   8 +-
 .../AmbariManagementControllerTest.java         |   9 +
 .../internal/CalculatedStatusTest.java          |  31 +
 .../internal/RequestResourceProviderTest.java   |  12 +-
 .../internal/UpgradeResourceProviderTest.java   |   2 +-
 .../orm/AmbariJpaLocalTxnInterceptorTest.java   | 155 ++++
 .../server/orm/InMemoryDefaultTestModule.java   |   5 +
 .../server/upgrade/UpgradeCatalog250Test.java   |  17 +-
 .../ambari/server/utils/RequestUtilsTest.java   |  18 +
 ambari-server/src/test/python/TestMpacks.py     | 102 ++-
 .../2.0.6/YARN/test_yarn_service_check.py       | 111 +--
 .../src/test/resources/dashboards/README.txt    |  18 +
 .../stacks/HDP/0.1/services/HDFS/metainfo.xml   |   1 +
 .../controllers/main/service/info/summary.js    |  37 +-
 .../main/service/reassign/step4_controller.js   |  19 +-
 .../mixins/main/dashboard/widgets/editable.js   |  47 +-
 .../main/dashboard/edit_widget_popup.hbs        |   4 +-
 .../edit_widget_popup_single_threshold.hbs      |   2 +-
 .../main/dashboard/plus_button_filter.hbs       |   2 +-
 .../app/templates/main/dashboard/widgets.hbs    |   8 +-
 .../main/dashboard/widgets/pie_chart.hbs        |   5 +-
 .../main/service/info/service_alert_popup.hbs   |  15 +-
 .../app/views/common/not-scrollable-textarea.js |   2 +-
 ambari-web/app/views/main/dashboard/widget.js   | 159 ++--
 ambari-web/app/views/main/dashboard/widgets.js  | 824 +++++++++----------
 .../main/dashboard/widgets/datanode_live.js     |   7 -
 .../main/dashboard/widgets/flume_agent_live.js  |   7 -
 .../main/dashboard/widgets/hawqsegment_live.js  |   7 -
 .../dashboard/widgets/hbase_average_load.js     |  11 +-
 .../views/main/dashboard/widgets/hbase_links.js |   4 -
 .../main/dashboard/widgets/hbase_master_heap.js |   4 -
 .../dashboard/widgets/hbase_master_uptime.js    |   5 -
 .../widgets/hbase_regions_in_transition.js      |  10 +-
 .../main/dashboard/widgets/hdfs_capacity.js     |   4 -
 .../views/main/dashboard/widgets/hdfs_links.js  |   4 -
 .../views/main/dashboard/widgets/metrics_cpu.js |   3 -
 .../main/dashboard/widgets/metrics_load.js      |   3 -
 .../main/dashboard/widgets/metrics_memory.js    |   3 -
 .../main/dashboard/widgets/metrics_network.js   |   3 -
 .../main/dashboard/widgets/namenode_cpu.js      |   4 -
 .../main/dashboard/widgets/namenode_heap.js     |   4 -
 .../main/dashboard/widgets/namenode_rpc.js      |  10 +-
 .../main/dashboard/widgets/namenode_uptime.js   |   5 -
 .../dashboard/widgets/node_managers_live.js     |   7 -
 .../main/dashboard/widgets/pie_chart_widget.js  |  16 +-
 .../views/main/dashboard/widgets/pxf_live.js    |   6 -
 .../dashboard/widgets/resource_manager_heap.js  |   4 -
 .../widgets/resource_manager_uptime.js          |   5 -
 .../main/dashboard/widgets/supervisor_live.js   |   7 -
 .../views/main/dashboard/widgets/text_widget.js |   4 +-
 .../widgets/text_widget_single_threshold.js     |   6 +-
 .../dashboard/widgets/uptime_text_widget.js     |   2 -
 .../views/main/dashboard/widgets/yarn_links.js  |   4 -
 .../views/main/dashboard/widgets/yarn_memory.js |   4 -
 .../service/reassign/step4_controller_test.js   |   2 +-
 .../test/views/main/dashboard/widget_test.js    | 200 ++---
 .../widgets/hbase_average_load_test.js          |   4 +-
 .../widgets/hbase_regions_in_transition_test.js |   6 +-
 .../main/dashboard/widgets/namenode_rpc_test.js |  13 +-
 .../text_widget_single_threshold_test.js        |  10 +-
 .../main/dashboard/widgets/text_widget_test.js  |  10 +-
 .../widgets/uptime_text_widget_test.js          |   2 +-
 .../test/views/main/dashboard/widgets_test.js   | 669 ++++++---------
 contrib/views/pom.xml                           |   1 -
 contrib/views/zeppelin/pom.xml                  | 190 -----
 .../view/zeppelin/ZeppelinServiceCheck.java     |  55 --
 .../ambari/view/zeppelin/ZeppelinServlet.java   | 113 ---
 .../zeppelin/src/main/resources/WEB-INF/web.xml |  40 -
 .../src/main/resources/view.log4j.properties    |  27 -
 .../views/zeppelin/src/main/resources/view.xml  |  48 --
 126 files changed, 2017 insertions(+), 2285 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a58c39c9/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/a58c39c9/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ambari/blob/a58c39c9/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------


[14/24] ambari git commit: AMBARI-18944 - Improve remoteIp in audit log (Wang Yaoxin via jonathanhurley)

Posted by jo...@apache.org.
AMBARI-18944 - Improve remoteIp in audit log (Wang Yaoxin via jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f4ea3091
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f4ea3091
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f4ea3091

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: f4ea309196a2c02b88f5e5ce062200d50d888005
Parents: ae3ff2a
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Dec 2 10:18:35 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Dec 2 10:19:41 2016 -0500

----------------------------------------------------------------------
 .../apache/ambari/server/utils/RequestUtils.java  | 10 ++++++++++
 .../ambari/server/utils/RequestUtilsTest.java     | 18 ++++++++++++++++++
 2 files changed, 28 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f4ea3091/ambari-server/src/main/java/org/apache/ambari/server/utils/RequestUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/RequestUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/RequestUtils.java
index 0ac782f..dbb0f11 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/RequestUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/RequestUtils.java
@@ -50,6 +50,9 @@ public class RequestUtils {
     if (isRemoteAddressUnknown(ip)) {
       ip = request.getRemoteAddr();
     }
+    if (containsMultipleRemoteAddresses(ip)) {
+       ip = ip.substring(0, ip.indexOf(","));
+    }
     return ip;
   }
 
@@ -76,6 +79,13 @@ public class RequestUtils {
   }
 
   /**
+   * Checks if ip contains multiple IP addresses
+   */
+  private static boolean containsMultipleRemoteAddresses(String ip) {
+    return ip != null && ip.indexOf(",") > 0;
+  }
+
+  /**
    * Checks if RequestContextHolder contains a valid HTTP request
    * @return
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/f4ea3091/ambari-server/src/test/java/org/apache/ambari/server/utils/RequestUtilsTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/RequestUtilsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/RequestUtilsTest.java
index 595127e..f36858e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/RequestUtilsTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/RequestUtilsTest.java
@@ -30,6 +30,7 @@ import org.junit.Test;
 public class RequestUtilsTest {
 
   public static final String REMOTE_ADDRESS = "12.13.14.15";
+  public static final String REMOTE_ADDRESS_MULTIPLE = "12.13.14.15,12.13.14.16";
 
   @Test
   public void testGetRemoteAddress() {
@@ -49,6 +50,23 @@ public class RequestUtilsTest {
   }
 
   @Test
+  public void testGetMultipleRemoteAddress() {
+    // GIVEN
+    HttpServletRequest mockedRequest = createMock(HttpServletRequest.class);
+    expect(mockedRequest.getHeader("X-Forwarded-For")).andReturn(null);
+    expect(mockedRequest.getHeader("Proxy-Client-IP")).andReturn("unknown");
+    expect(mockedRequest.getHeader("WL-Proxy-Client-IP")).andReturn("");
+    expect(mockedRequest.getHeader("HTTP_CLIENT_IP")).andReturn("unknown");
+    expect(mockedRequest.getHeader("HTTP_X_FORWARDED_FOR")).andReturn(REMOTE_ADDRESS_MULTIPLE);
+    replay(mockedRequest);
+    // WHEN
+    String remoteAddress = RequestUtils.getRemoteAddress(mockedRequest);
+    // THEN
+    assertEquals(REMOTE_ADDRESS, remoteAddress);
+    verify(mockedRequest);
+  }
+
+  @Test
   public void testGetRemoteAddressFoundFirstHeader() {
     // GIVEN
     HttpServletRequest mockedRequest = createMock(HttpServletRequest.class);


[17/24] ambari git commit: AMBARI-19018 - Services should be able to specify their own resources subdirs for syncing to agents

Posted by jo...@apache.org.
AMBARI-19018 - Services should be able to specify their own resources subdirs for syncing to agents


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/232a9d87
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/232a9d87
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/232a9d87

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 232a9d87e72dfb87e0d25f6a4cba6738e27beb53
Parents: 60a6bd4
Author: Tim Thorpe <tt...@apache.org>
Authored: Fri Dec 2 08:15:09 2016 -0800
Committer: Tim Thorpe <tt...@apache.org>
Committed: Fri Dec 2 08:15:09 2016 -0800

----------------------------------------------------------------------
 .../ambari_agent/CustomServiceOrchestrator.py   |   7 +-
 .../src/main/python/ambari_agent/FileCache.py   |  12 ++-
 .../TestCustomServiceOrchestrator.py            |  30 +-----
 .../test/python/ambari_agent/TestFileCache.py   |  10 +-
 .../ambari/server/agent/ExecutionCommand.java   |   1 +
 .../AmbariManagementControllerImpl.java         |   9 ++
 .../ambari/server/state/ComponentInfo.java      |  14 +++
 .../python/ambari_server/serverConfiguration.py |  14 +--
 .../AMBARI_METRICS/0.1.0/metainfo.xml           |   1 +
 .../AmbariManagementControllerTest.java         |   9 ++
 .../server/orm/InMemoryDefaultTestModule.java   |   5 +
 ambari-server/src/test/python/TestMpacks.py     | 102 +++++++++++++------
 .../src/test/resources/dashboards/README.txt    |  18 ++++
 .../stacks/HDP/0.1/services/HDFS/metainfo.xml   |   1 +
 14 files changed, 150 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index 7d61611..11c8cbe 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -154,12 +154,7 @@ class CustomServiceOrchestrator():
         self.file_cache.get_host_scripts_base_dir(server_url_prefix)          
         hook_dir = self.file_cache.get_hook_base_dir(command, server_url_prefix)
         base_dir = self.file_cache.get_service_base_dir(command, server_url_prefix)
-        from ActionQueue import ActionQueue  # To avoid cyclic dependency
-        if self.COMMAND_TYPE in command and command[self.COMMAND_TYPE] == ActionQueue.EXECUTION_COMMAND:
-          logger.info("Found it - " + str(command[self.COMMAND_TYPE]) + " yeah")
-          # limiting to only EXECUTION_COMMANDs for now
-          # TODO need a design for limiting to specific role/component such as METRICS_GRAFANA
-          self.file_cache.get_dashboard_base_dir(server_url_prefix)
+        self.file_cache.get_custom_resources_subdir(command, server_url_prefix)
 
         script_path = self.resolve_script_path(base_dir, script)
         script_tuple = (script_path, base_dir)

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-agent/src/main/python/ambari_agent/FileCache.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/FileCache.py b/ambari-agent/src/main/python/ambari_agent/FileCache.py
index 83ac373..a9ea8f6 100644
--- a/ambari-agent/src/main/python/ambari_agent/FileCache.py
+++ b/ambari-agent/src/main/python/ambari_agent/FileCache.py
@@ -45,7 +45,6 @@ class FileCache():
   STACKS_CACHE_DIRECTORY="stacks"
   COMMON_SERVICES_DIRECTORY="common-services"
   CUSTOM_ACTIONS_CACHE_DIRECTORY="custom_actions"
-  DASHBOARD_DIRECTORY="dashboards"
   HOST_SCRIPTS_CACHE_DIRECTORY="host_scripts"
   HASH_SUM_FILE=".hash"
   ARCHIVE_NAME="archive.zip"
@@ -100,12 +99,17 @@ class FileCache():
                                   server_url_prefix)
 
 
-  def get_dashboard_base_dir(self, server_url_prefix):
+  def get_custom_resources_subdir(self, command, server_url_prefix):
     """
-    Returns a base directory for dashboards
+    Returns a custom directory which must be a subdirectory of the resources dir
     """
+    try:
+      custom_dir = command['commandParams']['custom_folder']
+    except KeyError:
+      return None
+
     return self.provide_directory(self.cache_dir,
-                                  self.DASHBOARD_DIRECTORY,
+                                  custom_dir,
                                   server_url_prefix)
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py b/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
index 0304adc..5323d9a 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
@@ -220,7 +220,7 @@ class TestCustomServiceOrchestrator(TestCase):
     except AgentException:
       pass # Expected
 
-  @patch.object(FileCache, "get_dashboard_base_dir")
+  @patch.object(FileCache, "get_custom_resources_subdir")
   @patch.object(CustomServiceOrchestrator, "resolve_script_path")
   @patch.object(CustomServiceOrchestrator, "resolve_hook_script_path")
   @patch.object(FileCache, "get_host_scripts_base_dir")
@@ -235,7 +235,7 @@ class TestCustomServiceOrchestrator(TestCase):
                       get_host_scripts_base_dir_mock, 
                       resolve_hook_script_path_mock, 
                       resolve_script_path_mock,
-                      get_dashboard_base_dir_mock):
+                      get_custom_resources_subdir_mock):
     
     FileCache_mock.return_value = None
     command = {
@@ -267,7 +267,6 @@ class TestCustomServiceOrchestrator(TestCase):
     unix_process_id = 111
     orchestrator.commands_in_progress = {command['taskId']: unix_process_id}
     get_hook_base_dir_mock.return_value = "/hooks/"
-    get_dashboard_base_dir_mock.return_value = "/dashboards/"
     # normal run case
     run_file_mock.return_value = {
         'stdout' : 'sss',
@@ -278,7 +277,6 @@ class TestCustomServiceOrchestrator(TestCase):
     self.assertEqual(ret['exitcode'], 0)
     self.assertTrue(run_file_mock.called)
     self.assertEqual(run_file_mock.call_count, 3)
-    self.assertTrue(get_dashboard_base_dir_mock.called)
 
     run_file_mock.reset_mock()
 
@@ -301,25 +299,6 @@ class TestCustomServiceOrchestrator(TestCase):
 
     run_file_mock.reset_mock()
 
-    # For role=METRICS_GRAFANA, dashboards should be sync'd
-    command['role'] = 'METRICS_GRAFANA'
-    get_dashboard_base_dir_mock.reset_mock()
-    get_dashboard_base_dir_mock.return_value = "/dashboards/"
-
-    run_file_mock.return_value = {
-        'stdout' : 'sss',
-        'stderr' : 'eee',
-        'exitcode': 0,
-      }
-    ret = orchestrator.runCommand(command, "out.txt", "err.txt")
-    self.assertEqual(ret['exitcode'], 0)
-    self.assertTrue(run_file_mock.called)
-    self.assertEqual(run_file_mock.call_count, 3)
-    self.assertTrue(get_dashboard_base_dir_mock.called)
-
-    command['role'] = 'REGION_SERVER'
-    run_file_mock.reset_mock()
-
     # unknown script type case
     command['commandParams']['script_type'] = "SOME_TYPE"
     ret = orchestrator.runCommand(command, "out.txt", "err.txt")
@@ -332,7 +311,6 @@ class TestCustomServiceOrchestrator(TestCase):
 
     pass
 
-  @patch.object(FileCache, "get_dashboard_base_dir")
   @patch("ambari_commons.shell.kill_process_with_children")
   @patch.object(CustomServiceOrchestrator, "resolve_script_path")
   @patch.object(CustomServiceOrchestrator, "resolve_hook_script_path")
@@ -347,8 +325,7 @@ class TestCustomServiceOrchestrator(TestCase):
                       get_hook_base_dir_mock, get_service_base_dir_mock,
                       get_host_scripts_base_dir_mock,
                       resolve_hook_script_path_mock, resolve_script_path_mock,
-                      kill_process_with_children_mock,
-                      get_dashboard_base_dir_mock):
+                      kill_process_with_children_mock):
     FileCache_mock.return_value = None
     command = {
       'role' : 'REGION_SERVER',
@@ -378,7 +355,6 @@ class TestCustomServiceOrchestrator(TestCase):
     unix_process_id = 111
     orchestrator.commands_in_progress = {command['taskId']: unix_process_id}
     get_hook_base_dir_mock.return_value = "/hooks/"
-    get_dashboard_base_dir_mock.return_value = "/dashboards/"
     run_file_mock_return_value = {
       'stdout' : 'killed',
       'stderr' : 'killed',

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestFileCache.py b/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
index fbefc2b..00f6b69 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestFileCache.py
@@ -119,10 +119,16 @@ class TestFileCache(TestCase):
 
 
   @patch.object(FileCache, "provide_directory")
-  def test_get_dashboard_base_dir(self, provide_directory_mock):
+  def test_get_custom_resources_subdir(self, provide_directory_mock):
     provide_directory_mock.return_value = "dummy value"
     fileCache = FileCache(self.config)
-    res = fileCache.get_dashboard_base_dir("server_url_pref")
+    command = {
+      'commandParams': {
+        'custom_folder' : 'dashboards'
+      }
+    }
+
+    res = fileCache.get_custom_resources_subdir(command, "server_url_pref")
     self.assertEquals(
       pprint.pformat(provide_directory_mock.call_args_list[0][0]),
       "('/var/lib/ambari-agent/cache', 'dashboards', 'server_url_pref')")

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 29737ee..ef1ee4f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -343,6 +343,7 @@ public class ExecutionCommand extends AgentCommand {
     String SCRIPT_TYPE = "script_type";
     String SERVICE_PACKAGE_FOLDER = "service_package_folder";
     String HOOKS_FOLDER = "hooks_folder";
+    String CUSTOM_FOLDER = "custom_folder";
     String STACK_NAME = "stack_name";
     String SERVICE_TYPE = "service_type";
     String STACK_VERSION = "stack_version";

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index ac9e405..0448b9f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -25,6 +25,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CUSTOM_FOLDER;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.GROUP_LIST;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
@@ -2217,6 +2218,14 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       serviceInfo.getServicePackageFolder());
     commandParams.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder());
 
+    String customCacheDirectory = componentInfo.getCustomFolder();
+    if (customCacheDirectory != null) {
+      File customCache = new File(configs.getResourceDirPath(), customCacheDirectory);
+      if (customCache.exists() && customCache.isDirectory()) {
+        commandParams.put(CUSTOM_FOLDER, customCacheDirectory);
+      }
+    }
+
     String clusterName = cluster.getClusterName();
     if (customCommandExecutionHelper.isTopologyRefreshRequired(roleCommand.name(), clusterName, serviceName)) {
       commandParams.put(ExecutionCommand.KeyNames.REFRESH_TOPOLOGY, "True");

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
index 1e494b4..bd9b798 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
@@ -133,6 +133,9 @@ public class ComponentInfo {
 
   private String timelineAppid;
 
+  @XmlElement(name="customFolder")
+  private String customFolder;
+
   public ComponentInfo() {
   }
 
@@ -158,6 +161,7 @@ public class ComponentInfo {
     clientConfigFiles = prototype.clientConfigFiles;
     timelineAppid = prototype.timelineAppid;
     reassignAllowed = prototype.reassignAllowed;
+    customFolder = prototype.customFolder;
   }
 
   public String getName() {
@@ -396,6 +400,14 @@ public class ComponentInfo {
     this.reassignAllowed = reassignAllowed;
   }
 
+  public String getCustomFolder() {
+    return customFolder;
+  }
+
+  public void setCustomFolder(String customFolder) {
+    this.customFolder = customFolder;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -426,6 +438,7 @@ public class ComponentInfo {
     if (name != null ? !name.equals(that.name) : that.name != null) return false;
     if (clientConfigFiles != null ? !clientConfigFiles.equals(that.clientConfigFiles) :
         that.clientConfigFiles != null) return false;
+    if (customFolder != null ? !customFolder.equals(that.customFolder) : that.customFolder != null) return false;
 
     return true;
   }
@@ -450,6 +463,7 @@ public class ComponentInfo {
     result = 31 * result + (clientConfigFiles != null ? clientConfigFiles.hashCode() : 0);
     // NULL = 0, TRUE = 2, FALSE = 1
     result = 31 * result + (versionAdvertisedField != null ? (versionAdvertisedField.booleanValue() ? 2 : 1) : 0);
+    result = 31 * result + (customFolder != null ? customFolder.hashCode() : 0);
     return result;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/main/python/ambari_server/serverConfiguration.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/serverConfiguration.py b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
index 9596e0d..6a6c89e 100644
--- a/ambari-server/src/main/python/ambari_server/serverConfiguration.py
+++ b/ambari-server/src/main/python/ambari_server/serverConfiguration.py
@@ -186,7 +186,6 @@ SETUP_OR_UPGRADE_MSG = "- If this is a new setup, then run the \"ambari-server s
 DEFAULT_DB_NAME = "ambari"
 
 SECURITY_KEYS_DIR = "security.server.keys_dir"
-DASHBOARD_PATH_PROPERTY = 'dashboards.path'
 EXTENSION_PATH_PROPERTY = 'extensions.path'
 COMMON_SERVICES_PATH_PROPERTY = 'common.services.path'
 MPACKS_STAGING_PATH_PROPERTY = 'mpacks.staging.path'
@@ -398,8 +397,8 @@ class ServerConfigDefaults(object):
     self.EXTENSION_LOCATION_DEFAULT = ""
     self.COMMON_SERVICES_LOCATION_DEFAULT = ""
     self.MPACKS_STAGING_LOCATION_DEFAULT = ""
-    self.DASHBOARD_LOCATION_DEFAULT = ""
     self.SERVER_TMP_DIR_DEFAULT = ""
+    self.DASHBOARD_DIRNAME = "dashboards"
 
     self.DEFAULT_VIEWS_DIR = ""
 
@@ -470,7 +469,6 @@ class ServerConfigDefaultsWindows(ServerConfigDefaults):
     self.EXTENSION_LOCATION_DEFAULT = "resources\\extensions"
     self.COMMON_SERVICES_LOCATION_DEFAULT = "resources\\common-services"
     self.MPACKS_STAGING_LOCATION_DEFAULT = "resources\\mpacks"
-    self.DASHBOARD_LOCATION_DEFAULT = "resources\\dashboards"
     self.SERVER_TMP_DIR_DEFAULT = "data\\tmp"
 
     self.DEFAULT_VIEWS_DIR = "resources\\views"
@@ -557,7 +555,6 @@ class ServerConfigDefaultsLinux(ServerConfigDefaults):
     self.EXTENSION_LOCATION_DEFAULT = AmbariPath.get("/var/lib/ambari-server/resources/extensions")
     self.COMMON_SERVICES_LOCATION_DEFAULT = AmbariPath.get("/var/lib/ambari-server/resources/common-services")
     self.MPACKS_STAGING_LOCATION_DEFAULT = AmbariPath.get("/var/lib/ambari-server/resources/mpacks")
-    self.DASHBOARD_LOCATION_DEFAULT = AmbariPath.get("/var/lib/ambari-server/resources/dashboards")
     self.SERVER_TMP_DIR_DEFAULT = AmbariPath.get("/var/lib/ambari-server/data/tmp")
 
     self.DEFAULT_VIEWS_DIR = AmbariPath.get("/var/lib/ambari-server/resources/views")
@@ -1448,13 +1445,8 @@ def get_mpacks_staging_location(properties):
 # Dashboard location
 #
 def get_dashboard_location(properties):
-  try:
-    dashboard_location = properties[DASHBOARD_PATH_PROPERTY]
-  except KeyError:
-    dashboard_location = configDefaults.DASHBOARD_LOCATION_DEFAULT
-
-  if not dashboard_location:
-    dashboard_location = configDefaults.DASHBOARD_LOCATION_DEFAULT
+  resources_dir = get_resources_location(properties)
+  dashboard_location = os.path.join(resources_dir, configDefaults.DASHBOARD_DIRNAME)
   return dashboard_location
 
 #

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml
index 43a4320..740a91a 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml
@@ -101,6 +101,7 @@
           <category>MASTER</category>
           <cardinality>0-1</cardinality>
           <versionAdvertised>false</versionAdvertised>
+          <customFolder>dashboards</customFolder>
           <commandScript>
             <script>scripts/metrics_grafana.py</script>
             <scriptType>PYTHON</scriptType>

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 0fdaa46..db64f17 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -1283,6 +1283,15 @@ public class AmbariManagementControllerTest {
     assertEquals("false", ec.getCommandParams().get("command_retry_enabled"));
     Map<String, Set<String>> chInfo = ec.getClusterHostInfo();
     assertTrue(chInfo.containsKey("namenode_host"));
+    assertFalse(ec.getCommandParams().containsKey("custom_folder"));
+
+    ec = controller.getExecutionCommand(cluster,
+                                        s1.getServiceComponent("DATANODE").getServiceComponentHost(host1),
+                                        RoleCommand.START);
+    assertEquals(cluster1, ec.getClusterName());
+    assertNotNull(ec.getCommandParams());
+    assertTrue(ec.getCommandParams().containsKey("custom_folder"));
+    assertEquals("dashboards", ec.getCommandParams().get("custom_folder"));
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
index 6773176..a4a9e26 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/InMemoryDefaultTestModule.java
@@ -90,6 +90,7 @@ public class InMemoryDefaultTestModule extends AbstractModule {
     String stacks = "src/test/resources/stacks";
     String version = "src/test/resources/version";
     String sharedResourcesDir = "src/test/resources/";
+    String resourcesDir = "src/test/resources/";
     if (System.getProperty("os.name").contains("Windows")) {
       stacks = ClassLoader.getSystemClassLoader().getResource("stacks").getPath();
       version = new File(new File(ClassLoader.getSystemClassLoader().getResource("").getPath()).getParent(), "version").getPath();
@@ -116,6 +117,10 @@ public class InMemoryDefaultTestModule extends AbstractModule {
       properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), sharedResourcesDir);
     }
 
+    if (!properties.containsKey(Configuration.RESOURCES_DIR.getKey())) {
+      properties.setProperty(Configuration.RESOURCES_DIR.getKey(), resourcesDir);
+    }
+
     try {
       install(Modules.override(new BeanDefinitionsCachingTestControllerModule(properties)).with(new AbstractModule() {
         @Override

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/test/python/TestMpacks.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestMpacks.py b/ambari-server/src/test/python/TestMpacks.py
index ba37856..32db005 100644
--- a/ambari-server/src/test/python/TestMpacks.py
+++ b/ambari-server/src/test/python/TestMpacks.py
@@ -64,7 +64,7 @@ def get_configs():
     serverConfiguration.STACK_LOCATION_KEY : "/var/lib/ambari-server/resources/stacks",
     serverConfiguration.COMMON_SERVICES_PATH_PROPERTY : "/var/lib/ambari-server/resources/common-services",
     serverConfiguration.EXTENSION_PATH_PROPERTY : "/var/lib/ambari-server/resources/extensions",
-    serverConfiguration.DASHBOARD_PATH_PROPERTY : "/var/lib/ambari-server/resources/dashboards",
+    serverConfiguration.RESOURCES_DIR_PROPERTY : "/var/lib/ambari-server/resources",
     serverConfiguration.MPACKS_STAGING_PATH_PROPERTY : mpacks_directory,
     serverConfiguration.SERVER_TMP_DIR_PROPERTY : "/tmp",
     serverConfiguration.JDBC_DATABASE_PROPERTY: "postgres"
@@ -100,9 +100,11 @@ class TestMpacks(TestCase):
       fail = True
     self.assertTrue(fail)
 
+  @patch("os.path.exists")
   @patch("ambari_server.setupMpacks.get_YN_input")
   @patch("ambari_server.setupMpacks.run_mpack_install_checker")
-  def test_validate_purge(self, run_mpack_install_checker_mock, get_YN_input_mock):
+  @patch("ambari_server.setupMpacks.get_ambari_properties")
+  def test_validate_purge(self, get_ambari_properties_mock, run_mpack_install_checker_mock, get_YN_input_mock, os_path_exists_mock):
     options = self._create_empty_options_mock()
     options.purge = True
     purge_list = options.purge_list.split(',')
@@ -112,6 +114,7 @@ class TestMpacks(TestCase):
     replay_mode = False
     run_mpack_install_checker_mock.return_value = (0, "No errors found", "")
     get_YN_input_mock.return_value = True
+    os_path_exists_mock.return_value = True
 
     fail = False
     try:
@@ -160,22 +163,28 @@ class TestMpacks(TestCase):
     extensions_directory = configs[serverConfiguration.EXTENSION_PATH_PROPERTY]
     common_services_directory = configs[serverConfiguration.COMMON_SERVICES_PATH_PROPERTY]
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
-    os_path_exists_mock.return_value = False
+    os_path_exists_mock.side_effect = [True]
 
     purge_stacks_and_mpacks(None)
-    os_path_exists_calls = []
+    os_path_exists_calls = [
+      call('/var/lib/ambari-server/resources'),
+    ]
     os_path_exists_mock.assert_has_calls(os_path_exists_calls)
 
+    os_path_exists_mock.side_effect = [True, False, False]
     purge_stacks_and_mpacks(options.purge_list.split(","))
     os_path_exists_calls = [
+      call('/var/lib/ambari-server/resources'),
       call(stacks_directory),
       call(mpacks_directory)
     ]
     os_path_exists_mock.assert_has_calls(os_path_exists_calls)
 
     options.purge_list = ",".join([STACK_DEFINITIONS_RESOURCE_NAME, SERVICE_DEFINITIONS_RESOURCE_NAME, MPACKS_RESOURCE_NAME])
+    os_path_exists_mock.side_effect = [True, False, False, False]
     purge_stacks_and_mpacks(options.purge_list.split(","))
     os_path_exists_calls = [
+      call('/var/lib/ambari-server/resources'),
       call(stacks_directory),
       call(common_services_directory),
       call(mpacks_directory)
@@ -183,8 +192,10 @@ class TestMpacks(TestCase):
     os_path_exists_mock.assert_has_calls(os_path_exists_calls)
 
     options.purge_list = ",".join([STACK_DEFINITIONS_RESOURCE_NAME, EXTENSION_DEFINITIONS_RESOURCE_NAME, MPACKS_RESOURCE_NAME])
+    os_path_exists_mock.side_effect = [True, False, False, False]
     purge_stacks_and_mpacks(options.purge_list.split(","))
     os_path_exists_calls = [
+      call('/var/lib/ambari-server/resources'),
       call(stacks_directory),
       call(extensions_directory),
       call(mpacks_directory)
@@ -193,10 +204,13 @@ class TestMpacks(TestCase):
 
     options.purge_list = ",".join([STACK_DEFINITIONS_RESOURCE_NAME, SERVICE_DEFINITIONS_RESOURCE_NAME, MPACKS_RESOURCE_NAME])
     options.replay_mode = True
+    os_path_exists_mock.side_effect = [True, False, False, False]
     purge_stacks_and_mpacks(options.purge_list.split(","))
     os_path_exists_calls = [
+      call('/var/lib/ambari-server/resources'),
       call(stacks_directory),
-      call(common_services_directory)
+      call(common_services_directory),
+      call(mpacks_directory)
     ]
     os_path_exists_mock.assert_has_calls(os_path_exists_calls)
 
@@ -266,10 +280,11 @@ class TestMpacks(TestCase):
     get_ambari_version_mock.return_value = "2.4.0.0"
     run_os_command_mock.return_value = (0, "", "")
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
-    """
+
     os_path_exists_calls = [call('/tmp/mystack.tar.gz'),
                             call('mpacks/mystack-ambari-mpack-1.0.0.0/mpack.json'),
                             call('mpacks/mystack-ambari-mpack-1.0.0.0/hooks/before_install.py'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks'),
                             call('/var/lib/ambari-server/resources/extensions'),
                             call('/var/lib/ambari-server/resources/common-services'),
@@ -277,12 +292,14 @@ class TestMpacks(TestCase):
                             call(mpacks_directory + '/cache'),
                             call('/var/lib/ambari-server/resources/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/common-services/SERVICEA'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/1.0/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEA/2.0/dashboards'),
                             call('/var/lib/ambari-server/resources/common-services/SERVICEB'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/1.0.0/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/common-services/SERVICEB/2.0.0/dashboards'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
@@ -295,22 +312,26 @@ class TestMpacks(TestCase):
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEA/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/stacks/MYSTACK/2.0/services/SERVICEB/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.0/hooks/after_install.py')]
-    """
-    os_path_exists_mock.side_effect = [True, True, True, False, True, False, False, False, False,
-                                       False, False, False, False, False, False,
-                                       False, False, False, False, False, False, False, False,
-                                       False, False, False, False, True]
+
+    os_path_exists_mock.side_effect = [True, True, True, True, False, True, False, False, False, False,
+                                       False, True, False, False, False, False, False, False, True, False,
+                                       False, False, False, False, False, False, False, False, False, False,
+                                       True]
     get_ambari_properties_mock.return_value = configs
     shutil_move_mock.return_value = True
 
-    install_mpack(options)
+    try:
+      install_mpack(options)
+    except Exception as e:
+      print e
 
     stacks_directory = configs[serverConfiguration.STACK_LOCATION_KEY]
     common_services_directory = configs[serverConfiguration.COMMON_SERVICES_PATH_PROPERTY]
     extensions_directory = configs[serverConfiguration.EXTENSION_PATH_PROPERTY]
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
-    dashboards_directory = serverConfiguration.get_dashboard_location(configs)
     mpacks_staging_directory = os.path.join(mpacks_directory, "mystack-ambari-mpack-1.0.0.0")
+    resources_directory = configs[serverConfiguration.RESOURCES_DIR_PROPERTY]
+    dashboards_directory = os.path.join(resources_directory, "dashboards")
 
     run_os_command_calls = [
       call([
@@ -377,6 +398,7 @@ class TestMpacks(TestCase):
            "SERVICEB", None)
     ]
 
+    os_path_exists_mock.assert_has_calls(os_path_exists_calls)
     self.assertTrue(purge_stacks_and_mpacks_mock.called)
     run_os_command_mock.assert_has_calls(run_os_command_calls)
     os_mkdir_mock.assert_has_calls(os_mkdir_calls)
@@ -403,8 +425,8 @@ class TestMpacks(TestCase):
     expand_mpack_mock.return_value = "mpacks/myextension-ambari-mpack-1.0.0.0"
     get_ambari_version_mock.return_value = "2.4.0.0"
     
-    os_path_exists_mock.side_effect = [True, True, True, False, True, False, False, False,
-                                       False, True, False, False, False]
+    os_path_exists_mock.side_effect = [True, True, True, True, False, True, False, False, False,
+                                       False, True, True, False, False, False]
     get_ambari_properties_mock.return_value = configs
     shutil_move_mock.return_value = True
 
@@ -413,10 +435,12 @@ class TestMpacks(TestCase):
     extensions_directory = configs[serverConfiguration.EXTENSION_PATH_PROPERTY]
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
     mpacks_staging_directory = os.path.join(mpacks_directory, "myextension-ambari-mpack-1.0.0.0")
-    dashboards_directory = serverConfiguration.get_dashboard_location(configs)
+    resources_directory = configs[serverConfiguration.RESOURCES_DIR_PROPERTY]
+    dashboards_directory = os.path.join(resources_directory, "dashboards")
 
     os_path_exists_calls = [call('/tmp/myextension.tar.gz'),
                             call('mpacks/myextension-ambari-mpack-1.0.0.0/mpack.json'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks'),
                             call('/var/lib/ambari-server/resources/extensions'),
                             call('/var/lib/ambari-server/resources/common-services'),
@@ -424,6 +448,7 @@ class TestMpacks(TestCase):
                             call(mpacks_directory + '/cache'),
                             call('/var/lib/ambari-server/resources/dashboards'),
                             call(mpacks_directory + '/myextension-ambari-mpack-1.0.0.0'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/extensions'),
                             call('/var/lib/ambari-server/resources/extensions/MYEXTENSION'),
                             call(mpacks_directory + '/myextension-ambari-mpack-1.0.0.0/extensions/MYEXTENSION/1.0/services'),
@@ -476,9 +501,9 @@ class TestMpacks(TestCase):
     expand_mpack_mock.return_value = "mpacks/myservice-ambari-mpack-1.0.0.0"
     get_ambari_version_mock.return_value = "2.4.0.0"
 
-    os_path_exists_mock.side_effect = [True, True, True, True, True, True,
-                                       True, True, False, False, False, False,
-                                       True, True, True, False, True, True,
+    os_path_exists_mock.side_effect = [True, True, True, True, True, True, True,
+                                       True, True, False, False, True, False, False,
+                                       True, True, True, True, False, True, True,
                                        True, False]
 
     get_ambari_properties_mock.return_value = configs
@@ -491,11 +516,13 @@ class TestMpacks(TestCase):
     common_services_directory = configs[serverConfiguration.COMMON_SERVICES_PATH_PROPERTY]
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
     mpacks_staging_directory = os.path.join(mpacks_directory, "myservice-ambari-mpack-1.0.0.0")
-    dashboards_directory = serverConfiguration.get_dashboard_location(configs)
+    resources_directory = configs[serverConfiguration.RESOURCES_DIR_PROPERTY]
+    dashboards_directory = os.path.join(resources_directory, "dashboards")
 
     os_path_exists_calls = [call('/tmp/myservice.tar.gz'),
                             call('mpacks/myservice-ambari-mpack-1.0.0.0/mpack.json'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks'),
                             call('/var/lib/ambari-server/resources/extensions'),
                             call('/var/lib/ambari-server/resources/common-services'),
@@ -503,8 +530,10 @@ class TestMpacks(TestCase):
                             call(mpacks_directory + '/cache'),
                             call('/var/lib/ambari-server/resources/dashboards'),
                             call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/common-services/MYSERVICE'),
                             call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0/common-services/MYSERVICE/1.0.0/dashboards'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
@@ -562,14 +591,14 @@ class TestMpacks(TestCase):
     get_ambari_version_mock.return_value = "2.4.0.0"
     run_os_command_mock.return_value = (0, "", "")
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
-    os_path_exists_mock.side_effect = [True, True, True, True, True, True, True, True,
-                                       True, True, True, True, True, True, True, False,
-                                       False, True, False, False, True, False, False, 
-                                       False, False, False, True, True, True, False,
-                                       True, True, False, True, True, False, False,
-                                       False, False, False, True, True, True, True,
-                                       True, True, True, False, True, False, True, True, 
-                                       True, True, True, True]
+    os_path_exists_mock.side_effect = [True, True, True, True, True, True, True, True, True, True,
+                                       True, True, True, True, True, True, True, False, False, True,
+                                       True, False, False, True, False, False, False, False, False, True,
+                                       True, True, True, False, True, True, False, True, True, False,
+                                       False, False, False, False, True, True, True, True, True, True,
+                                       True, False, True, False, True, True, True, True, True, True,
+                                       True]
+
     get_ambari_properties_mock.return_value = configs
     shutil_move_mock.return_value = True
 
@@ -579,10 +608,12 @@ class TestMpacks(TestCase):
     common_services_directory = configs[serverConfiguration.COMMON_SERVICES_PATH_PROPERTY]
     mpacks_directory = configs[serverConfiguration.MPACKS_STAGING_PATH_PROPERTY]
     mpacks_staging_directory = os.path.join(mpacks_directory, "mystack-ambari-mpack-1.0.0.1")
-    dashboards_directory = serverConfiguration.get_dashboard_location(configs)
+    resources_directory = configs[serverConfiguration.RESOURCES_DIR_PROPERTY]
+    dashboards_directory = os.path.join(resources_directory, "dashboards")
 
     os_path_exists_calls = [call('/tmp/mystack-1.0.0.1.tar.gz'),
                             call('mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json'),
+                            call('/var/lib/ambari-server/resources'),
                             call(mpacks_directory),
                             call(mpacks_directory + '/myextension-ambari-mpack-1.0.0.0/mpack.json'),
                             call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0/mpack.json'),
@@ -591,6 +622,7 @@ class TestMpacks(TestCase):
                             call('/tmp/mystack-1.0.0.1.tar.gz'),
                             call('mpacks/mystack-ambari-mpack-1.0.0.1/mpack.json'),
                             call('mpacks/mystack-ambari-mpack-1.0.0.1/hooks/before_upgrade.py'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks'),
                             call('/var/lib/ambari-server/resources/extensions'),
                             call('/var/lib/ambari-server/resources/common-services'),
@@ -598,6 +630,7 @@ class TestMpacks(TestCase):
                             call(mpacks_directory + '/cache'),
                             call('/var/lib/ambari-server/resources/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/common-services/SERVICEA'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/1.0/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEA/2.0/dashboards'),
@@ -607,6 +640,7 @@ class TestMpacks(TestCase):
                             call('/var/lib/ambari-server/resources/common-services/SERVICEC'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/1.0.0/dashboards'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/common-services/SERVICEC/2.0.0/dashboards'),
+                            call('/var/lib/ambari-server/resources'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0'),
                             call('/var/lib/ambari-server/resources/stacks/MYSTACK/1.0/services'),
@@ -631,6 +665,7 @@ class TestMpacks(TestCase):
                             call('/var/lib/ambari-server/resources/dashboards/grafana-dashboards/SERVICEC'),
                             call(mpacks_directory + '/mystack-ambari-mpack-1.0.0.1/stacks/MYSTACK/3.0/services/SERVICEC/dashboards/service-metrics/SERVICEC.txt'),
                             call('/var/lib/ambari-server/resources/dashboards/service-metrics/SERVICEC.txt'),
+                            call('/var/lib/ambari-server/resources'),
                             call(mpacks_directory),
                             call(mpacks_directory + '/myextension-ambari-mpack-1.0.0.0/mpack.json'),
                             call(mpacks_directory + '/myservice-ambari-mpack-1.0.0.0/mpack.json'),
@@ -775,7 +810,7 @@ class TestMpacks(TestCase):
       serverConfiguration.COMMON_SERVICES_PATH_PROPERTY : os.path.join(uninstall_directory, "common-services"),
       serverConfiguration.EXTENSION_PATH_PROPERTY : os.path.join(uninstall_directory, "extensions"),
       serverConfiguration.MPACKS_STAGING_PATH_PROPERTY : mpacks_directory,
-      serverConfiguration.DASHBOARD_PATH_PROPERTY : os.path.join(uninstall_directory, "dashboards"),
+      serverConfiguration.RESOURCES_DIR_PROPERTY : uninstall_directory,
       serverConfiguration.SERVER_TMP_DIR_PROPERTY : "/tmp"
     }
 
@@ -784,7 +819,8 @@ class TestMpacks(TestCase):
     stacks_directory = fake_configs[serverConfiguration.STACK_LOCATION_KEY]
     extension_directory = fake_configs[serverConfiguration.EXTENSION_PATH_PROPERTY]
     common_services_directory = fake_configs[serverConfiguration.COMMON_SERVICES_PATH_PROPERTY]
-    dashboard_directory = fake_configs[serverConfiguration.DASHBOARD_PATH_PROPERTY]
+    resources_directory = fake_configs[serverConfiguration.RESOURCES_DIR_PROPERTY]
+    dashboards_directory = os.path.join(resources_directory, "dashboards")
 
     _uninstall_mpack("mystack-ambari-mpack", "1.0.0.1")
 
@@ -794,8 +830,8 @@ class TestMpacks(TestCase):
                               call(os.path.join(stacks_directory, "2.0/files/metainfo2.xml")),
                               call(os.path.join(extension_directory, "SERVICEB")),
                               call(os.path.join(common_services_directory, "SERVICEB")),
-                              call(os.path.join(dashboard_directory, "SERVICEB")),
-                              call(os.path.join(dashboard_directory, "files/STORM.txt"))] 
+                              call(os.path.join(dashboards_directory, "SERVICEB")),
+                              call(os.path.join(dashboards_directory, "files/STORM.txt"))]
 
   def _create_empty_options_mock(self):
     options = MagicMock()

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/test/resources/dashboards/README.txt
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/dashboards/README.txt b/ambari-server/src/test/resources/dashboards/README.txt
new file mode 100644
index 0000000..919d510
--- /dev/null
+++ b/ambari-server/src/test/resources/dashboards/README.txt
@@ -0,0 +1,18 @@
+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.
+
+
+Test directory for sync'ing a components custom folder - AMBARI-19018

http://git-wip-us.apache.org/repos/asf/ambari/blob/232a9d87/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
index f4195a8..7629552 100644
--- a/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
@@ -57,6 +57,7 @@
           <name>DATANODE</name>
           <category>SLAVE</category>
           <cardinality>1+</cardinality>
+          <customFolder>dashboards</customFolder>
           <commandScript>
             <script>scripts/datanode.py</script>
             <scriptType>PYTHON</scriptType>


[19/24] ambari git commit: AMBARI-19064 Refactor widgets on Dashboard page. (atkach)

Posted by jo...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widget_test.js b/ambari-web/test/views/main/dashboard/widget_test.js
index 0544ff6..63da712 100644
--- a/ambari-web/test/views/main/dashboard/widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widget_test.js
@@ -21,178 +21,84 @@ require('views/main/dashboard/widget');
 
 describe('App.DashboardWidgetView', function () {
 
-  var dashboardWidgetView = App.DashboardWidgetView.create({
+  var dashboardWidgetView;
+
+  dashboardWidgetView = App.DashboardWidgetView.create({
     parentView: Em.Object.create({
       widgetsMapper: Em.K,
-      getUserPref: function () {return {complete: Em.K}},
+      getUserPref: function () {
+        return {complete: Em.K}
+      },
       postUserPref: Em.K,
       translateToReal: Em.K,
       visibleWidgets: [],
       hiddenWidgets: []
+    }),
+    widget: Em.Object.create({
+      id: 5,
+      sourceName: 'HDFS',
+      title: 'Widget'
     })
   });
 
   describe('#viewID', function () {
     it('viewID is computed with id', function () {
-      dashboardWidgetView.set('id', 5);
       expect(dashboardWidgetView.get('viewID')).to.equal('widget-5');
     });
   });
 
   describe('#model', function () {
-    it('model_type is null', function () {
-      dashboardWidgetView.set('model_type', null);
+
+    beforeEach(function() {
+      sinon.stub(dashboardWidgetView, 'findModelBySource').returns(Em.Object.create({serviceName: 'HDFS'}));
+    });
+
+    afterEach(function() {
+      dashboardWidgetView.findModelBySource.restore();
+    });
+
+    it('sourceName is null', function () {
+      dashboardWidgetView.set('widget.sourceName', null);
       dashboardWidgetView.propertyDidChange('model');
-      expect(dashboardWidgetView.get('model')).to.eql({});
+      expect(dashboardWidgetView.get('model')).to.be.an.object;
     });
-    it('model_type is valid', function () {
-      dashboardWidgetView.set('model_type', 's');
+    it('sourceName is valid', function () {
+      dashboardWidgetView.set('widget.sourceName', 'HDFS');
       dashboardWidgetView.propertyDidChange('model');
-      dashboardWidgetView.set('parentView.s_model', {'s': {}});
-      expect(dashboardWidgetView.get('model')).to.eql({'s': {}});
+      expect(dashboardWidgetView.get('model')).to.eql(Em.Object.create({serviceName: 'HDFS'}));
     });
   });
 
   describe("#didInsertElement()", function () {
-    before(function () {
+
+    beforeEach(function () {
       sinon.stub(App, 'tooltip', Em.K);
     });
-    after(function () {
+    afterEach(function () {
       App.tooltip.restore();
     });
+
     it("call App.tooltip", function () {
       dashboardWidgetView.didInsertElement();
       expect(App.tooltip.calledOnce).to.be.true;
     });
   });
 
-  describe("#deleteWidget()", function () {
-    beforeEach(function () {
-      sinon.stub(dashboardWidgetView.get('parentView'), 'widgetsMapper').returns({});
-      sinon.stub(dashboardWidgetView.get('parentView'), 'getUserPref').returns({
-        complete: Em.K
-      });
-    });
-
-    afterEach(function () {
-      dashboardWidgetView.get('parentView').widgetsMapper.restore();
-      dashboardWidgetView.get('parentView').getUserPref.restore();
-    });
-
-    it("testMode is off", function () {
-      dashboardWidgetView.set('parentView.persistKey', 'key');
-      dashboardWidgetView.deleteWidget();
-      expect(dashboardWidgetView.get('parentView').getUserPref.calledWith('key')).to.be.true;
-    });
-  });
+  describe("#editWidget()", function () {
 
-  describe("#deleteWidgetComplete()", function () {
     beforeEach(function () {
-      sinon.spy(dashboardWidgetView.get('parentView'), 'postUserPref');
-      sinon.spy(dashboardWidgetView.get('parentView'), 'translateToReal');
-      dashboardWidgetView.set('parentView.currentPrefObject', {
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [],
-        threshold: 'threshold'
-      });
-      dashboardWidgetView.set('parentView.persistKey', 'key');
-      dashboardWidgetView.deleteWidgetComplete();
-    });
-    afterEach(function () {
-      dashboardWidgetView.get('parentView').postUserPref.restore();
-      dashboardWidgetView.get('parentView').translateToReal.restore();
-    });
-    it("postUserPref is called with correct data", function () {
-      var arg = JSON.parse(JSON.stringify(dashboardWidgetView.get('parentView').postUserPref.args[0][1]));
-      expect(arg).to.be.eql({
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [[5, null]],
-        threshold: 'threshold'
-      });
-    });
-    it("translateToReal is called with valid data", function () {
-      var arg = JSON.parse(JSON.stringify(dashboardWidgetView.get('parentView').translateToReal.args[0][0]));
-      expect(arg).to.be.eql({
-        dashboardVersion: 'new',
-        visible: ['1', '2'],
-        hidden: [[5, null]],
-        threshold: 'threshold'
-      });
-    });
-  });
-
-  describe("#editWidget()", function () {
-    before(function () {
       sinon.stub(dashboardWidgetView, 'showEditDialog', Em.K);
     });
-    after(function () {
+    afterEach(function () {
       dashboardWidgetView.showEditDialog.restore();
     });
+
     it("call showEditDialog", function () {
       dashboardWidgetView.editWidget();
       expect(dashboardWidgetView.showEditDialog.calledOnce).to.be.true;
     });
   });
 
-  describe("#showEditDialog()", function () {
-    var obj = Em.Object.create({
-      observeThresh1Value: Em.K,
-      observeThresh2Value: Em.K,
-      thresh1: '1',
-      thresh2: '2'
-    });
-    beforeEach(function () {
-      sinon.spy(obj, 'observeThresh1Value');
-      sinon.spy(obj, 'observeThresh2Value');
-      sinon.stub(dashboardWidgetView.get('parentView'), 'getUserPref').returns({
-        complete: Em.K
-      });
-      var popup = dashboardWidgetView.showEditDialog(obj);
-      popup.onPrimary();
-    });
-    afterEach(function () {
-      obj.observeThresh1Value.restore();
-      obj.observeThresh2Value.restore();
-      dashboardWidgetView.get('parentView').getUserPref.restore();
-    });
-
-    it("observeThresh1Value is called once", function () {
-      expect(obj.observeThresh1Value.calledOnce).to.be.true;
-    });
-
-    it("observeThresh2Value is called once", function () {
-      expect(obj.observeThresh2Value.calledOnce).to.be.true;
-    });
-
-    it("thresh1 = 1", function () {
-      expect(dashboardWidgetView.get('thresh1')).to.equal(1);
-    });
-
-    it("thresh2 = 2", function () {
-      expect(dashboardWidgetView.get('thresh2')).to.equal(2);
-    });
-
-    it("getUserPref is called once", function () {
-      expect(dashboardWidgetView.get('parentView').getUserPref.calledOnce).to.be.true;
-    });
-  });
-
-  describe('#model', function () {
-    it('model_type is null', function () {
-      dashboardWidgetView.set('model_type', null);
-      dashboardWidgetView.propertyDidChange('model');
-      expect(dashboardWidgetView.get('model')).to.eql({});
-    });
-    it('model_type is valid', function () {
-      dashboardWidgetView.set('model_type', 's');
-      dashboardWidgetView.propertyDidChange('model');
-      dashboardWidgetView.set('parentView.s_model', {'s': {}});
-      expect(dashboardWidgetView.get('model')).to.eql({'s': {}});
-    });
-  });
-
   describe('#hoverContentTopClass', function () {
     var tests = [
       {
@@ -258,7 +164,7 @@ describe('App.DashboardWidgetView', function () {
       var testCases = [
         {
           data: {
-            thresh1: '',
+            thresholdMin: '',
             maxValue: 0
           },
           result: {
@@ -268,7 +174,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: 'NaN',
+            thresholdMin: 'NaN',
             maxValue: 0
           },
           result: {
@@ -278,7 +184,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '-1',
+            thresholdMin: '-1',
             maxValue: 0
           },
           result: {
@@ -288,7 +194,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '2',
+            thresholdMin: '2',
             maxValue: 1
           },
           result: {
@@ -298,8 +204,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '1',
+            thresholdMin: '1',
+            thresholdMax: '1',
             maxValue: 2
           },
           result: {
@@ -309,8 +215,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '0',
+            thresholdMin: '1',
+            thresholdMax: '0',
             maxValue: 2
           },
           result: {
@@ -320,8 +226,8 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh1: '1',
-            thresh2: '2',
+            thresholdMin: '1',
+            thresholdMax: '2',
             maxValue: 2
           },
           result: {
@@ -331,12 +237,12 @@ describe('App.DashboardWidgetView', function () {
         }
       ];
       testCases.forEach(function (test) {
-        describe("thresh1 - " + test.data.thresh1 + ', maxValue - ' + test.data.maxValue, function () {
+        describe("thresholdMin - " + test.data.thresholdMin + ', maxValue - ' + test.data.maxValue, function () {
 
           beforeEach(function () {
             widget.set('isThresh2Error', false);
-            widget.set('thresh2', test.data.thresh2 || "");
-            widget.set('thresh1', test.data.thresh1);
+            widget.set('thresholdMax', test.data.thresholdMax || "");
+            widget.set('thresholdMin', test.data.thresholdMin);
             widget.set('maxValue', test.data.maxValue);
             widget.observeThresh1Value();
           });
@@ -367,7 +273,7 @@ describe('App.DashboardWidgetView', function () {
       var testCases = [
         {
           data: {
-            thresh2: '',
+            thresholdMax: '',
             maxValue: 0
           },
           result: {
@@ -377,7 +283,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: 'NaN',
+            thresholdMax: 'NaN',
             maxValue: 0
           },
           result: {
@@ -387,7 +293,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '-1',
+            thresholdMax: '-1',
             maxValue: 0
           },
           result: {
@@ -397,7 +303,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '2',
+            thresholdMax: '2',
             maxValue: 1
           },
           result: {
@@ -407,7 +313,7 @@ describe('App.DashboardWidgetView', function () {
         },
         {
           data: {
-            thresh2: '2',
+            thresholdMax: '2',
             maxValue: 2
           },
           result: {
@@ -417,10 +323,10 @@ describe('App.DashboardWidgetView', function () {
         }
       ];
       testCases.forEach(function (test) {
-        describe("thresh2 - " + test.data.thresh2 + ', maxValue - ' + test.data.maxValue, function () {
+        describe("thresholdMax - " + test.data.thresholdMax + ', maxValue - ' + test.data.maxValue, function () {
 
           beforeEach(function () {
-            widget.set('thresh2', test.data.thresh2 || "");
+            widget.set('thresholdMax', test.data.thresholdMax || "");
             widget.set('maxValue', test.data.maxValue);
             widget.observeThresh2Value();
           });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
index e3a08c9..8cb3246 100644
--- a/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/hbase_average_load_test.js
@@ -82,8 +82,8 @@ describe('App.HBaseAverageLoadView', function() {
 
   App.TestAliases.testAsComputedAlias(getView(), 'data', 'model.averageLoad', 'number');
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
index 8ad1531..4366ab6 100644
--- a/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/hbase_regions_in_transition_test.js
@@ -23,7 +23,7 @@ require('views/main/dashboard/widgets/text_widget');
 require('views/main/dashboard/widget');
 
 function getView() {
-  return App.HBaseRegionsInTransitionView.create({model_type:null});
+  return App.HBaseRegionsInTransitionView.create({});
 }
 
 describe('App.HBaseRegionsInTransitionView', function() {
@@ -81,9 +81,9 @@ describe('App.HBaseRegionsInTransitionView', function() {
 
   App.TestAliases.testAsComputedAlias(getView(), 'data', 'model.regionsInTransition', 'number');
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
   App.TestAliases.testAsComputedAnd(getView(), 'isOrange', ['!isGreen', '!isRed']);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
index 474d099..15b7503 100644
--- a/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/namenode_rpc_test.js
@@ -35,7 +35,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 1
       },
       e: {
-        isOrange: true,
         isNA: false,
         content: '1.00 ms',
         data: '1.00'
@@ -46,7 +45,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 10
       },
       e: {
-        isOrange: false,
         isNA: false,
         content: '10.00 ms',
         data: '10.00'
@@ -57,7 +55,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: 0
       },
       e: {
-        isOrange: false,
         isNA: false,
         content: '0 ms',
         data: 0
@@ -68,7 +65,6 @@ describe('App.NameNodeRpcView', function() {
         nameNodeRpc: null
       },
       e: {
-        isOrange: false,
         isNA: true,
         content: Em.I18n.t('services.service.summary.notAvailable'),
         data: null
@@ -78,24 +74,21 @@ describe('App.NameNodeRpcView', function() {
 
   tests.forEach(function(test) {
     describe('nameNodeRpc - ' + test.model.nameNodeRpc, function() {
-      var jobTrackerRpcView = App.NameNodeRpcView.create({model_type:null, model: test.model});
+      var jobTrackerRpcView = App.NameNodeRpcView.create({model: test.model});
       it('content', function() {
         expect(jobTrackerRpcView.get('content')).to.equal(test.e.content);
       });
       it('data', function() {
         expect(jobTrackerRpcView.get('data')).to.equal(test.e.data);
       });
-      it('isOrange', function() {
-        expect(jobTrackerRpcView.get('isOrange')).to.equal(test.e.isOrange);
-      });
       it('isNA', function() {
         expect(jobTrackerRpcView.get('isNA')).to.equal(test.e.isNA);
       });
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
index e564922..3136c35 100644
--- a/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/text_widget_single_threshold_test.js
@@ -22,7 +22,7 @@ require('views/main/dashboard/widget');
 require('views/main/dashboard/widgets/text_widget_single_threshold');
 
 function getView() {
-  return App.TextDashboardSingleThresholdWidgetView.create({thresh1:0});
+  return App.TextDashboardSingleThresholdWidgetView.create({thresholdMin:0});
 }
 
 describe('App.TextDashboardSingleThresholdWidgetView', function() {
@@ -43,8 +43,8 @@ describe('App.TextDashboardSingleThresholdWidgetView', function() {
   ];
 
   tests.forEach(function(test) {
-    describe('data - ' + test.data + ' | thresh1 - 0', function() {
-      var textDashboardWidgetSingleThresholdView = App.TextDashboardSingleThresholdWidgetView.create({thresh1:0});
+    describe('data - ' + test.data + ' | thresholdMin - 0', function() {
+      var textDashboardWidgetSingleThresholdView = App.TextDashboardSingleThresholdWidgetView.create({thresholdMin:0});
       textDashboardWidgetSingleThresholdView.set('data', test.data);
       it('isNA', function() {
         expect(textDashboardWidgetSingleThresholdView.get('isNA')).to.equal(test.e.isNA);
@@ -52,6 +52,6 @@ describe('App.TextDashboardSingleThresholdWidgetView', function() {
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresh1');
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresh1');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isRed', 'data', 'thresholdMin');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isGreen', 'data', 'thresholdMin');
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
index 730e209..096d782 100644
--- a/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/text_widget_test.js
@@ -22,7 +22,7 @@ require('views/main/dashboard/widget');
 require('views/main/dashboard/widgets/text_widget');
 
 function getView() {
-  return App.TextDashboardWidgetView.create({thresh1:40, thresh2:70});
+  return App.TextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
 }
 
 describe('App.TextDashboardWidgetView', function() {
@@ -43,8 +43,8 @@ describe('App.TextDashboardWidgetView', function() {
   ];
 
   tests.forEach(function(test) {
-    describe('data - ' + test.data + ' | thresh1 - 40 | thresh2 - 70', function() {
-      var textDashboardWidgetView = App.TextDashboardWidgetView.create({thresh1:40, thresh2:70});
+    describe('data - ' + test.data + ' | thresholdMin - 40 | thresholdMax - 70', function() {
+      var textDashboardWidgetView = App.TextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
       textDashboardWidgetView.set('data', test.data);
       it('isNA', function() {
         expect(textDashboardWidgetView.get('isNA')).to.equal(test.e.isNA);
@@ -52,9 +52,9 @@ describe('App.TextDashboardWidgetView', function() {
     });
   });
 
-  App.TestAliases.testAsComputedGtProperties(getView(), 'isGreen', 'data', 'thresh2');
+  App.TestAliases.testAsComputedGtProperties(getView(), 'isGreen', 'data', 'thresholdMax');
 
-  App.TestAliases.testAsComputedLteProperties(getView(), 'isRed', 'data', 'thresh1');
+  App.TestAliases.testAsComputedLteProperties(getView(), 'isRed', 'data', 'thresholdMin');
 
   App.TestAliases.testAsComputedAnd(getView(), 'isOrange', ['!isGreen', '!isRed']);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
index fbe2694..fa20593 100644
--- a/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets/uptime_text_widget_test.js
@@ -25,7 +25,7 @@ var uptimeTextDashboardWidgetView;
 describe('App.UptimeTextDashboardWidgetView', function() {
 
   beforeEach(function () {
-    uptimeTextDashboardWidgetView = App.UptimeTextDashboardWidgetView.create({thresh1:40, thresh2:70});
+    uptimeTextDashboardWidgetView = App.UptimeTextDashboardWidgetView.create({thresholdMin:40, thresholdMax:70});
   });
 
   describe('#timeConverter', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/test/views/main/dashboard/widgets_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard/widgets_test.js b/ambari-web/test/views/main/dashboard/widgets_test.js
index 0781c79..707087a 100644
--- a/ambari-web/test/views/main/dashboard/widgets_test.js
+++ b/ambari-web/test/views/main/dashboard/widgets_test.js
@@ -25,526 +25,325 @@ require('views/main/dashboard/widgets');
 
 describe('App.MainDashboardWidgetsView', function () {
 
-  var view = App.MainDashboardWidgetsView.create();
-
-  describe('#setInitPrefObject', function () {
-    var hostMetricsWidgetsCount = 4;
-    var hdfsWidgetsCount = 7;
-    var hbaseWidgetsCount = 4;
-    var yarnWidgetsCount = 4;
-    var totalWidgetsCount = 20;
-    var tests = Em.A([
-      {
-        models: {
-          host_metrics_model: null,
-          hdfs_model: null,
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hostMetricsWidgetsCount - hdfsWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'All models are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: null,
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hdfsWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hdfs_model, hbase_model, yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hbase_model, yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: null,
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - hbaseWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 0
-        },
-        m: 'hbase_model and yarn_model are null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: {},
-          yarn_model: null
-        },
-        e: {
-          visibleL: totalWidgetsCount - yarnWidgetsCount - 1,
-          hiddenL: 1
-        },
-        m: 'yarn_model is null'
-      },
-      {
-        models: {
-          host_metrics_model: {},
-          hdfs_model: {},
-          hbase_model: {},
-          yarn_model: {}
-        },
-        e: {
-          visibleL: totalWidgetsCount - 1,
-          hiddenL: 1
-        },
-        m: 'All models are not null'
-      }
-    ]);
+  var view;
+
+  beforeEach(function() {
+    view = App.MainDashboardWidgetsView.create({
+      getUserPref: Em.K,
+      postUserPref: Em.K,
+      setDBProperty: Em.K,
+      persistKey: 'key'
+    });
+  });
+
+  describe('#didInsertElement()', function() {
 
     beforeEach(function() {
-      sinon.stub(view, 'resolveConfigDependencies');
+      sinon.stub(view, 'loadWidgetsSettings').returns({
+        complete: Em.clb
+      });
+      sinon.stub(view, 'checkServicesChange');
+      sinon.stub(view, 'renderWidgets');
+      sinon.stub(Em.run, 'next');
+      view.didInsertElement();
     });
 
     afterEach(function() {
-      view.resolveConfigDependencies.restore();
+      view.loadWidgetsSettings.restore();
+      view.checkServicesChange.restore();
+      view.renderWidgets.restore();
+      Em.run.next.restore();
     });
 
-    tests.forEach(function (test) {
-      describe(test.m, function () {
-
-        beforeEach(function () {
-          view.set('host_metrics_model', test.models.host_metrics_model);
-          view.set('hdfs_model', test.models.hdfs_model);
-          view.set('hbase_model', test.models.hbase_model);
-          view.set('yarn_model', test.models.yarn_model);
-          view.setInitPrefObject();
-        });
-
-        it('visible.length is ' + test.e.visibleL, function () {
-          expect(view.get('initPrefObject.visible.length')).to.equal(test.e.visibleL);
-        });
-
-        it('hidden.length is ' + test.e.hiddenL, function () {
-          expect(view.get('initPrefObject.hidden.length')).to.equal(test.e.hiddenL);
-        });
-
-      });
+    it('checkServicesChange should be called', function() {
+      expect(view.checkServicesChange).to.be.calledOnce;
     });
-  });
 
-  describe('#persistKey', function () {
-    beforeEach(function () {
-      sinon.stub(App, 'get').withArgs('router.loginName').returns('tdk');
+    it('renderWidgets should be called', function() {
+      expect(view.renderWidgets).to.be.calledOnce;
     });
-    afterEach(function () {
-      App.get.restore();
+
+    it('isDataLoaded should be true', function() {
+      expect(view.get('isDataLoaded')).to.be.true;
     });
-    it('Check it', function () {
-      expect(view.get('persistKey')).to.equal('user-pref-tdk-dashboard');
+
+    it('Em.run.next should be called', function() {
+      expect(Em.run.next.calledWith(view, 'makeSortable')).to.be.true;
     });
   });
 
-  describe("#didInsertElement()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'setWidgetsDataModel', Em.K);
-      sinon.stub(view, 'setInitPrefObject', Em.K);
-      sinon.stub(view, 'setOnLoadVisibleWidgets', Em.K);
-      sinon.stub(Em.run, 'next', Em.K);
-      view.didInsertElement();
-    });
-    afterEach(function () {
-      view.setWidgetsDataModel.restore();
-      view.setInitPrefObject.restore();
-      view.setOnLoadVisibleWidgets.restore();
-      Em.run.next.restore();
-    });
-    it("setWidgetsDataModel is called once", function () {
-      expect(view.setWidgetsDataModel.calledOnce).to.be.true;
-    });
-    it("setInitPrefObject is called once", function () {
-      expect(view.setInitPrefObject.calledOnce).to.be.true;
-    });
-    it("setOnLoadVisibleWidgets is called once", function () {
-      expect(view.setOnLoadVisibleWidgets.calledOnce).to.be.true;
+  describe('#loadWidgetsSettings()', function() {
+
+    beforeEach(function() {
+      sinon.spy(view, 'getUserPref');
     });
-    it("makeSortable is called in the next loop", function () {
-      expect(Em.run.next.calledWith(view, 'makeSortable')).to.be.true;
+
+    afterEach(function() {
+      view.getUserPref.restore();
     });
-    it("isDataLoaded is true", function () {
-      expect(view.get('isDataLoaded')).to.be.true
+
+    it('getUserPref should be called', function() {
+      view.loadWidgetsSettings();
+      expect(view.getUserPref.calledWith('key')).to.be.true;
     });
   });
 
-  describe("#setWidgetsDataModel()", function () {
-    beforeEach(function () {
-      this.model = sinon.stub(App.Service, 'find');
-      this.get = sinon.stub(App, 'get');
-    });
-    afterEach(function () {
-      this.model.restore();
-      this.get.restore();
+  describe('#saveWidgetsSettings()', function() {
+
+    beforeEach(function() {
+      sinon.stub(view, 'setDBProperty');
+      sinon.stub(view, 'postUserPref');
+      view.saveWidgetsSettings({settings:{}});
     });
-    it("No host_metrics_model", function () {
-      this.get.returns([]);
-      this.model.returns([Em.Object.create({
-        serviceName: 'S1',
-        id: 'S1'
-      })]);
-      view.set('host_metrics_model', null);
-      view.setWidgetsDataModel();
-      expect(view.get('host_metrics_model')).to.be.null;
-      expect(view.get('s1_model')).to.eql(Em.Object.create({
-        serviceName: 'S1',
-        id: 'S1'
-      }));
+
+    afterEach(function() {
+      view.setDBProperty.restore();
+      view.postUserPref.restore();
     });
-    it("host_metrics_model is present", function () {
-      this.get.returns([1]);
-      this.model.returns([Em.Object.create({
-        serviceName: 'HDFS',
-        id: 'HDFS'
-      })]);
-      view.set('host_metrics_model', null);
-      view.setWidgetsDataModel();
-      expect(view.get('host_metrics_model')).to.eql([1]);
-      expect(view.get('hdfs_model.id')).to.equal('HDFS');
+
+    it('setDBProperty should be called', function() {
+      expect(view.setDBProperty.calledWith('key', {settings:{}})).to.be.true;
     });
-  });
 
-  describe("#plusButtonFilterView", function () {
-    var plusButtonFilterView = view.get('plusButtonFilterView').create({
-      parentView: view
+    it('postUserPref should be called', function() {
+      expect(view.postUserPref.calledWith('key', {settings:{}})).to.be.true;
     });
-    plusButtonFilterView.reopen({
-      visibleWidgets: [],
-      hiddenWidgets: []
+
+    it('userPreferences should be set', function() {
+      expect(view.get('userPreferences')).to.be.eql({settings:{}});
     });
+  });
 
-    describe("#applyFilter()", function () {
-      var widget = {checked: true};
-      beforeEach(function () {
-        sinon.stub(view, 'getUserPref').returns({
-          complete: Em.K
-        });
-        sinon.stub(view, 'widgetsMapper').returns(widget);
-      });
+  describe('#getUserPrefSuccessCallback()', function() {
 
-      afterEach(function () {
-        view.getUserPref.restore();
-        view.widgetsMapper.restore();
-      });
+    beforeEach(function() {
+      sinon.stub(view, 'getUserPrefErrorCallback');
+    });
 
-      it("testMode is off", function () {
-        plusButtonFilterView.applyFilter();
-        expect(view.getUserPref.calledOnce).to.be.true;
-      });
+    afterEach(function() {
+      view.getUserPrefErrorCallback.restore();
     });
 
-    describe("#applyFilterComplete()", function () {
-      beforeEach(function () {
-        sinon.stub(view, 'postUserPref');
-        sinon.stub(view, 'translateToReal');
-        sinon.stub(App.router, 'get', function (k) {
-          if ('loginName' === k) return 'tdk';
-          return Em.get(App.router, k);
-        });
-        plusButtonFilterView.set('hiddenWidgets', [
-          Em.Object.create({
-            checked: true,
-            id: 1,
-            displayName: 'i1'
-          }),
-          Em.Object.create({
-            checked: false,
-            id: 2,
-            displayName: 'i2'
-          })
-        ]);
-        view.set('currentPrefObject', Em.Object.create({
-          dashboardVersion: 'new',
-          visible: [],
-          hidden: [],
-          threshold: 'threshold'
-        }));
-        view.set('persistKey', 'key');
-        plusButtonFilterView.applyFilterComplete();
-      });
-      afterEach(function () {
-        view.postUserPref.restore();
-        view.translateToReal.restore();
-        App.router.get.restore();
-      });
-      it("postUserPref is called once", function () {
-        expect(view.postUserPref.calledOnce).to.be.true;
-      });
-      it("translateToReal is called with correct data", function () {
-        expect(view.translateToReal.getCall(0).args[0]).to.eql(Em.Object.create({
-          dashboardVersion: 'new',
-          visible: [1],
-          hidden: [
-            [2, 'i2']
-          ],
-          threshold: 'threshold'
-        }));
-      });
-      it("1 hidden widget", function () {
-        expect(plusButtonFilterView.get('hiddenWidgets.length')).to.equal(1);
-      });
+    it('getUserPrefErrorCallback should be called', function() {
+      view.getUserPrefSuccessCallback(null);
+      expect(view.getUserPrefErrorCallback).to.be.calledOnce;
     });
-  });
 
-  describe("#translateToReal()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'widgetsMapper').returns(Em.Object.create());
-      view.set('visibleWidgets', []);
-      view.set('hiddenWidgets', []);
-    });
-    afterEach(function () {
-      view.widgetsMapper.restore();
-    });
-    it("version is not new", function () {
-      var data = {
-        dashboardVersion: null,
-        visible: [],
-        hidden: [],
-        threshold: []
-      };
-      view.translateToReal(data);
-      expect(view.get('visibleWidgets')).to.be.empty;
-      expect(view.get('hiddenWidgets')).to.be.empty;
-    });
-    it("version is new", function () {
-      var data = {
-        dashboardVersion: 'new',
-        visible: [1],
-        hidden: [
-          ['id', 'title']
-        ],
-        threshold: [
-          [],
-          [
-            ['tresh1'],
-            ['tresh2']
-          ]
-        ]
-      };
-      view.translateToReal(data);
-      expect(view.get('visibleWidgets')).to.not.be.empty;
-      expect(view.get('hiddenWidgets')).to.not.be.empty;
+    it('userPreferences should be set', function() {
+      view.getUserPrefSuccessCallback({settings:{}});
+      expect(view.get('userPreferences')).to.be.eql({settings:{}});
     });
   });
 
-  describe("#setOnLoadVisibleWidgets()", function () {
-    beforeEach(function () {
-      sinon.stub(view, 'translateToReal', Em.K);
-      sinon.stub(view, 'getUserPref').returns({complete: Em.K});
-    });
+  describe('#getUserPrefErrorCallback()', function() {
 
-    afterEach(function () {
-      view.translateToReal.restore();
-      view.getUserPref.restore();
+    beforeEach(function() {
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({settings:{}});
+      sinon.stub(view, 'saveWidgetsSettings');
     });
 
-    it("testMode is false", function () {
-      view.setOnLoadVisibleWidgets();
-      expect(view.getUserPref.calledOnce).to.be.true;
+    afterEach(function() {
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
     });
-  });
 
-  describe("#removeWidget()", function () {
-    var widget;
-    var value;
-    beforeEach(function () {
-      widget = {};
-      value = {
-        visible: [widget],
-        hidden: [
-          [widget]
-        ]
-      };
-      value = view.removeWidget(value, widget);
-    });
-    it("value.visible is empty", function () {
-      expect(value.visible).to.be.empty;
-    });
-    it("value.hidden is empty", function () {
-      expect(value.hidden).to.be.empty;
+    it('saveWidgetsSettings should be called', function() {
+      view.getUserPrefErrorCallback();
+      expect(view.saveWidgetsSettings.calledWith({settings:{}})).to.be.true;
     });
   });
 
-  describe("#containsWidget()", function () {
-    it("widget visible", function () {
-      var widget = {};
-      var value = {
-        visible: [widget],
-        hidden: [
-          [widget]
-        ]
-      };
-      expect(view.containsWidget(value, widget)).to.be.true;
-    });
-    it("widget absent", function () {
-      var widget = {};
-      var value = {
-        visible: [],
-        hidden: []
-      };
-      expect(view.containsWidget(value, widget)).to.be.false;
-    });
-    it("widget hidden", function () {
-      var widget = {};
-      var value = {
-        visible: [],
-        hidden: [
-          [widget]
-        ]
-      };
-      expect(view.containsWidget(value, widget)).to.be.true;
+  describe('#resolveConfigDependencies()', function() {
+
+    beforeEach(function() {
+      this.mock = sinon.stub(App.router, 'get');
     });
-  });
 
-  describe("#persistKey", function () {
-    before(function () {
-      sinon.stub(App, 'get').withArgs('router.loginName').returns('user');
+    afterEach(function() {
+      App.router.get.restore();
     });
-    after(function () {
-      App.get.restore();
+
+    it('isHiddenByDefault should be undefined', function() {
+      var widgets = [{id: 20}];
+      this.mock.returns({properties: {'hide_yarn_memory_widget': 'false'}});
+      view.resolveConfigDependencies(widgets);
+      expect(widgets[0].isHiddenByDefault).to.be.undefined;
     });
-    it("depends on router.loginName", function () {
-      view.propertyDidChange('persistKey');
-      expect(view.get('persistKey')).to.equal('user-pref-user-dashboard');
+
+    it('isHiddenByDefault should be true', function() {
+      var widgets = [{id: 20}];
+      this.mock.returns({properties: {'hide_yarn_memory_widget': 'true'}});
+      view.resolveConfigDependencies(widgets);
+      expect(widgets[0].isHiddenByDefault).to.be.true;
     });
   });
 
-  describe("#getUserPrefSuccessCallback()", function () {
+  describe('#generateDefaultUserPreferences', function() {
 
-    it("response is null", function () {
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback(null, {}, {});
-      expect(view.get('currentPrefObject')).to.be.null;
+    beforeEach(function() {
+      sinon.stub(view, 'resolveConfigDependencies');
+      sinon.stub(App.Service, 'find').returns(Em.Object.create());
+      view.set('widgetsDefinition', [
+        Em.Object.create({sourceName: 'S1', id: 1}),
+        Em.Object.create({sourceName: 'HOST_METRICS', id: 2, isHiddenByDefault: true, threshold: []}),
+        Em.Object.create({sourceName: 'HOST_METRICS', id: 3, threshold: [1, 2]})
+      ]);
     });
 
-    it("response is correct", function () {
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback({}, {}, {});
-      expect(view.get('currentPrefObject')).to.eql({});
+    afterEach(function() {
+      view.resolveConfigDependencies.restore();
+      App.Service.find.restore();
     });
 
-    it('should update missing thresholds', function () {
+    it('should generate default preferences', function() {
+      expect(JSON.stringify(view.generateDefaultUserPreferences())).to.be.eql(JSON.stringify({
+        "visible": [3],
+        "hidden": [2],
+        "threshold": {
+          "2": [],
+          "3": [1,2]
+        }
+      }));
+      expect(view.resolveConfigDependencies).to.be.calledOnce;
+    });
+  });
+
+  describe('#renderWidgets()', function() {
 
-      view.set('currentPrefObject', null);
-      view.getUserPrefSuccessCallback({
+    it('should set visibleWidgets and hiddenWidgets', function() {
+      view.set('userPreferences', {
+        visible: [1],
+        hidden: [2],
         threshold: {
-          17: []
+          1: [],
+          2: [1,2]
         }
-      }, {}, {});
-      expect(view.get('currentPrefObject.threshold')['17']).to.eql([70, 90]);
+      });
+      view.renderWidgets();
+      expect(view.get('visibleWidgets')).to.be.eql([Em.Object.create({
+        id: 1,
+        threshold: [],
+        viewClass: App['NameNodeHeapPieChartView'],
+        sourceName: 'HDFS',
+        title: Em.I18n.t('dashboard.widgets.NameNodeHeap')
+      })]);
+      expect(view.get('hiddenWidgets')).to.be.eql([
+        Em.Object.create({
+          id: 2,
+          title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
+          checked: false
+        })
+      ]);
+    });
+  });
+
+  describe('#checkServicesChange()', function() {
+
+    beforeEach(function() {
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({
+        visible: [1, 2],
+        hidden: [3, 4]
+      });
+      sinon.stub(view, 'saveWidgetsSettings');
+    });
 
+    afterEach(function() {
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
     });
 
+    it('userPreferences should be updated', function() {
+      view.set('userPreferences', {
+        visible: [3],
+        hidden: [1],
+        threshold: {}
+      });
+      view.checkServicesChange();
+      expect(view.saveWidgetsSettings.getCall(0).args[0]).to.be.eql({
+        visible: [3, 2],
+        hidden: [1, 4],
+        threshold: {}
+      });
+    });
   });
 
-  describe("#resetAllWidgets()", function () {
+  describe('#resetAllWidgets()', function() {
 
-    beforeEach(function () {
+    beforeEach(function() {
       sinon.stub(App, 'showConfirmationPopup', Em.clb);
-      sinon.stub(view, 'postUserPref', Em.K);
-      sinon.stub(view, 'setDBProperty', Em.K);
-      sinon.stub(view, 'translateToReal', Em.K);
-      view.setProperties({
-        currentTimeRangeIndex: 1,
-        customStartTime: 1000,
-        customEndTime: 2000
-      });
+      sinon.stub(view, 'generateDefaultUserPreferences').returns({settings: {}});
+      sinon.stub(view, 'saveWidgetsSettings');
+      sinon.stub(view, 'renderWidgets');
       view.resetAllWidgets();
     });
 
-    afterEach(function () {
+    afterEach(function() {
       App.showConfirmationPopup.restore();
-      view.postUserPref.restore();
-      view.setDBProperty.restore();
-      view.translateToReal.restore();
+      view.generateDefaultUserPreferences.restore();
+      view.saveWidgetsSettings.restore();
+      view.renderWidgets.restore();
     });
 
-    it('persist reset', function () {
-      expect(view.postUserPref.calledOnce).to.be.true;
-    });
-    it('local storage reset', function () {
-      expect(view.setDBProperty.calledOnce).to.be.true;
+    it('saveWidgetsSettings should be called', function() {
+      expect(view.saveWidgetsSettings.calledWith({settings: {}})).to.be.true;
     });
-    it('time range reset', function () {
-      expect(view.get('currentTimeRangeIndex')).to.equal(0);
+
+    it('renderWidgets should be called', function() {
+      expect(view.renderWidgets).to.be.calledOnce;
     });
-    it('custom start time reset', function () {
+
+    it('properties should be reset', function() {
+      expect(view.get('currentTimeRangeIndex')).to.be.equal(0);
       expect(view.get('customStartTime')).to.be.null;
-    });
-    it('custom end time reset', function () {
       expect(view.get('customEndTime')).to.be.null;
     });
-    it('default settings application', function () {
-      expect(view.translateToReal.calledOnce).to.be.true;
-    });
-
   });
 
-  describe('#checkServicesChange', function () {
+  describe('#plusButtonFilterView', function() {
+    var plusButtonFilterView;
 
-    var emptyCurrentPref = {
-        visible: [],
-        hidden: [],
-        threshold: {}
-      },
-      widgetsMap = {
-        hdfs_model: ['1', '2', '3', '4', '5', '10', '11'],
-        host_metrics_model: ['6', '7', '8', '9'],
-        hbase_model: ['12', '13', '14', '15', '16'],
-        yarn_model: ['17', '18', '19', '20', '23'],
-        storm_model: ['21'],
-        flume_model: ['22']
-      },
-      emptyModelTitle = '{0} absent',
-      notEmptyModelTitle = '{0} present';
-
-    Em.keys(widgetsMap).forEach(function (item, index, array) {
-      it(notEmptyModelTitle.format(item), function () {
-        array.forEach(function (modelName) {
-          view.set(modelName, modelName === item ? {} : null);
-        });
-        expect(view.checkServicesChange(emptyCurrentPref).visible).to.eql(widgetsMap[item]);
+    beforeEach(function() {
+      plusButtonFilterView = view.get('plusButtonFilterView').create({
+        parentView: Em.Object.create({
+          saveWidgetsSettings: Em.K,
+          renderWidgets: Em.K
+        })
       });
     });
 
-    Em.keys(widgetsMap).forEach(function (item, index, array) {
-      it(emptyModelTitle.format(item), function () {
-        var expected = [];
-        array.forEach(function (modelName) {
-          if (modelName === item) {
-            view.set(modelName, null);
-          } else {
-            view.set(modelName, {});
-            expected = expected.concat(widgetsMap[modelName]);
-          }
+    describe('#applyFilter()', function() {
+
+      beforeEach(function() {
+        sinon.spy(plusButtonFilterView.get('parentView'), 'renderWidgets');
+        sinon.spy(plusButtonFilterView.get('parentView'), 'saveWidgetsSettings');
+        plusButtonFilterView.set('parentView.userPreferences', {
+          visible: [2],
+          hidden: [1, 3],
+          threshold: {}
         });
-        expect(view.checkServicesChange({
-          visible: widgetsMap[item],
-          hidden: [],
+        plusButtonFilterView.set('hiddenWidgets', [
+          Em.Object.create({checked: true, id: 1})
+        ]);
+        plusButtonFilterView.applyFilter();
+      });
+
+      afterEach(function() {
+        plusButtonFilterView.get('parentView').renderWidgets.restore();
+        plusButtonFilterView.get('parentView').saveWidgetsSettings.restore();
+      });
+
+      it('saveWidgetsSettings should be called', function() {
+        expect(plusButtonFilterView.get('parentView').saveWidgetsSettings.getCall(0).args[0]).to.be.eql({
+          visible: [2, 1],
+          hidden: [3],
           threshold: {}
-        }).visible).to.eql(expected);
+        });
       });
-    });
 
+      it('renderWidgets should be called', function() {
+        expect(plusButtonFilterView.get('parentView').renderWidgets).to.be.calledOnce;
+      });
+    });
   });
+
 });


[06/24] ambari git commit: AMBARI-18888: Ambari-agent: Create configuration files with JCEKS information

Posted by jo...@apache.org.
AMBARI-18888: Ambari-agent: Create configuration files with JCEKS information


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/615438b2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/615438b2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/615438b2

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 615438b272e6bd8efd37481ef684ae7d68921e64
Parents: 7577ebb
Author: Nahappan Somasundaram <ns...@hortonworks.com>
Authored: Tue Nov 29 13:36:16 2016 -0800
Committer: Nahappan Somasundaram <ns...@hortonworks.com>
Committed: Thu Dec 1 13:58:54 2016 -0800

----------------------------------------------------------------------
 ambari-agent/conf/unix/ambari-agent.ini         |   3 +
 .../ambari_agent/CustomServiceOrchestrator.py   | 120 +++++++++++++++++++
 ambari-agent/src/packages/tarball/all.xml       |  30 +++++
 .../ambari/server/agent/ExecutionCommand.java   |  28 +++++
 .../ambari/server/agent/HeartBeatHandler.java   |  10 +-
 .../server/agent/TestHeartbeatHandler.java      |  28 +++--
 6 files changed, 210 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-agent/conf/unix/ambari-agent.ini
----------------------------------------------------------------------
diff --git a/ambari-agent/conf/unix/ambari-agent.ini b/ambari-agent/conf/unix/ambari-agent.ini
index 61948d4..d6fcf5f 100644
--- a/ambari-agent/conf/unix/ambari-agent.ini
+++ b/ambari-agent/conf/unix/ambari-agent.ini
@@ -46,6 +46,9 @@ keysdir=/var/lib/ambari-agent/keys
 server_crt=ca.crt
 passphrase_env_var_name=AMBARI_PASSPHRASE
 ssl_verify_cert=0
+credential_lib_dir=/var/lib/ambari-agent/cred/lib
+credential_conf_dir=/var/lib/ambari-agent/cred/conf
+credential_shell_cmd=org.apache.hadoop.security.alias.CredentialShell
 
 [services]
 pidLookupPath=/var/run/

http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
index 7d61611..1eab0a5 100644
--- a/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
+++ b/ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
@@ -29,6 +29,8 @@ from FileCache import FileCache
 from AgentException import AgentException
 from PythonExecutor import PythonExecutor
 from PythonReflectiveExecutor import PythonReflectiveExecutor
+from resource_management.core.utils import PasswordString
+import subprocess
 import Constants
 import hostname
 
@@ -65,6 +67,11 @@ class CustomServiceOrchestrator():
   REFLECTIVELY_RUN_COMMANDS = FREQUENT_COMMANDS # -- commands which run a lot and often (this increases their speed)
   DONT_BACKUP_LOGS_FOR_COMMANDS = FREQUENT_COMMANDS
 
+  # Path where hadoop credential JARS will be available
+  DEFAULT_CREDENTIAL_SHELL_LIB_PATH = '/var/lib/ambari-agent/cred/lib'
+  DEFAULT_CREDENTIAL_CONF_DIR = '/var/lib/ambari-agent/cred/conf'
+  DEFAULT_CREDENTIAL_SHELL_CMD = 'org.apache.hadoop.security.alias.CredentialShell'
+
   def __init__(self, config, controller):
     self.config = config
     self.tmp_dir = config.get('agent', 'prefix')
@@ -78,6 +85,14 @@ class CustomServiceOrchestrator():
     # cache reset will be called on every agent registration
     controller.registration_listeners.append(self.file_cache.reset)
 
+    # Construct the hadoop credential lib JARs path
+    self.credential_shell_lib_path = os.path.join(config.get('security', 'credential_lib_dir',
+                                                             self.DEFAULT_CREDENTIAL_SHELL_LIB_PATH), '*')
+
+    self.credential_conf_dir = config.get('security', 'credential_conf_dir', self.DEFAULT_CREDENTIAL_CONF_DIR)
+
+    self.credential_shell_cmd = config.get('security', 'credential_shell_cmd', self.DEFAULT_CREDENTIAL_SHELL_CMD)
+
     # Clean up old status command files if any
     try:
       os.unlink(self.status_commands_stdout)
@@ -114,6 +129,102 @@ class CustomServiceOrchestrator():
     else:
       return PythonExecutor(self.tmp_dir, self.config)
 
+  def getProviderDirectory(self, service_name):
+    """
+    Gets the path to the service conf folder where the JCEKS file will be created.
+
+    :param service_name: Name of the service, for example, HIVE
+    :return: lower case path to the service conf folder
+    """
+
+    # The stack definition scripts of the service can move the
+    # JCEKS file around to where it wants, which is usually
+    # /etc/<service_name>/conf
+
+    conf_dir = os.path.join(self.credential_conf_dir, service_name.lower())
+    if not os.path.exists(conf_dir):
+      os.makedirs(conf_dir, 0644)
+
+    return conf_dir
+
+  def getAffectedConfigTypes(self, commandJson):
+    """
+    Gets the affected config types for the service in this command
+
+    :param commandJson:
+    :return:
+    """
+    return commandJson.get('configuration_attributes')
+
+  def getCredentialProviderPropertyName(self):
+    """
+    Gets the property name used by the hadoop credential provider
+    :return:
+    """
+    return 'hadoop.security.credential.provider.path'
+
+  def generateJceks(self, commandJson):
+    """
+    Generates the JCEKS file with passwords for the service specified in commandJson
+
+    :param commandJson: command JSON
+    :return: An exit value from the external process that generated the JCEKS file. None if
+    there are no passwords in the JSON.
+    """
+    cmd_result = None
+    roleCommand = None
+    if 'roleCommand' in commandJson:
+      roleCommand = commandJson['roleCommand']
+
+    logger.info('generateJceks: roleCommand={0}'.format(roleCommand))
+
+    # Password properties for a config type, if present,
+    # are under configuration_attributes:config_type:hidden:{prop1:attributes1, prop2, attributes2}
+    passwordProperties = {}
+    config_types = self.getAffectedConfigTypes(commandJson)
+    for config_type in config_types:
+      elem = config_types.get(config_type)
+      hidden = elem.get('hidden')
+      if hidden is not None:
+        passwordProperties[config_type] = hidden
+
+    # Set up the variables for the external command to generate a JCEKS file
+    java_home = commandJson['hostLevelParams']['java_home']
+    java_bin = '{java_home}/bin/java'.format(java_home=java_home)
+
+    cs_lib_path = self.credential_shell_lib_path
+    serviceName = commandJson['serviceName']
+
+    # Gather the password values and remove them from the configuration
+    configs = commandJson.get('configurations')
+    for key, value in passwordProperties.items():
+      config = configs.get(key)
+      if config is not None:
+        file_path = os.path.join(self.getProviderDirectory(serviceName), "{0}.jceks".format(key))
+        if os.path.exists(file_path):
+          os.remove(file_path)
+        provider_path = 'jceks://file{file_path}'.format(file_path=file_path)
+        logger.info('provider_path={0}'.format(provider_path))
+        for alias in value:
+          pwd = config.get(alias)
+          if pwd is not None:
+            # Remove the clear text password
+            config.pop(alias, None)
+            # Add JCEKS provider path instead
+            config[self.getCredentialProviderPropertyName()] = provider_path
+            logger.debug("config={0}".format(config))
+            protected_pwd = PasswordString(pwd)
+            # Generate the JCEKS file
+            cmd = (java_bin, '-cp', cs_lib_path, self.credential_shell_cmd, 'create',
+                   alias, '-value', protected_pwd, '-provider', provider_path)
+            logger.info(cmd)
+            cmd_result = subprocess.call(cmd)
+            logger.info('cmd_result = {0}'.format(cmd_result))
+            os.chmod(file_path, 0644) # group and others should have read access so that the service user can read
+
+    return cmd_result
+
+
   def runCommand(self, command, tmpoutfile, tmperrfile, forced_command_name=None,
                  override_output_files=True, retry=False):
     """
@@ -179,6 +290,15 @@ class CustomServiceOrchestrator():
         handle.on_background_command_started = self.map_task_to_process
         del command['__handle']
 
+      # If command contains credentialStoreEnabled, then
+      # generate the JCEKS file for the configurations.
+      credentialStoreEnabled = False
+      if 'credentialStoreEnabled' in command:
+        credentialStoreEnabled = (command['credentialStoreEnabled'] == "true")
+
+      if credentialStoreEnabled == True:
+        self.generateJceks(command)
+
       json_path = self.dump_command_to_json(command, retry)
       pre_hook_tuple = self.resolve_hook_script_path(hook_dir,
           self.PRE_HOOK_PREFIX, command_name, script_type)

http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-agent/src/packages/tarball/all.xml
----------------------------------------------------------------------
diff --git a/ambari-agent/src/packages/tarball/all.xml b/ambari-agent/src/packages/tarball/all.xml
index c481208..f8a54e3 100644
--- a/ambari-agent/src/packages/tarball/all.xml
+++ b/ambari-agent/src/packages/tarball/all.xml
@@ -190,4 +190,34 @@
       <outputDirectory>/var/lib/${project.artifactId}/data</outputDirectory>
     </file>
   </files>
+  <moduleSets>
+    <moduleSet>
+      <binaries>
+        <includeDependencies>false</includeDependencies>
+        <outputDirectory>/var/lib/${project.artifactId}/cred/lib</outputDirectory>
+        <unpack>false</unpack>
+        <directoryMode>755</directoryMode>
+        <fileMode>644</fileMode>
+        <dependencySets>
+          <dependencySet>
+            <outputDirectory>/var/lib/${project.artifactId}/cred/lib</outputDirectory>
+            <unpack>false</unpack>
+            <includes>
+              <include>commons-cli:commons-cli</include>
+              <include>commons-collections:commons-collections</include>
+              <include>commons-configuration:commons-configuration</include>
+              <include>commons-io:commons-io:jar:${commons.io.version}</include>
+              <include>commons-lang:commons-lang</include>
+              <include>commons-logging:commons-logging</include>
+              <include>com.google.guava:guava</include>
+              <include>org.slf4j:slf4j-api</include>
+              <include>org.apache.hadoop:hadoop-common</include>
+              <include>org.apache.hadoop:hadoop-auth</include>
+              <include>org.apache.htrace:htrace-core</include>
+            </includes>
+          </dependencySet>
+        </dependencySets>
+      </binaries>
+    </moduleSet>
+  </moduleSets>
 </assembly>

http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 29737ee..7353366 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -112,6 +112,13 @@ public class ExecutionCommand extends AgentCommand {
   @SerializedName("availableServices")
   private Map<String, String> availableServices = new HashMap<>();
 
+  /**
+   * "true" or "false" indicating whether this
+   * service is enabled for credential store use.
+   */
+  @SerializedName("credentialStoreEnabled")
+  private String credentialStoreEnabled;
+
   public String getCommandId() {
     return commandId;
   }
@@ -295,6 +302,27 @@ public class ExecutionCommand extends AgentCommand {
 	this.serviceType = serviceType;
   }
 
+  /**
+   * Get a value indicating whether this service is enabled
+   * for credential store use.
+   *
+   * @return "true" or "false", any other value is
+   * considered as "false"
+   */
+  public String getCredentialStoreEnabled() {
+    return credentialStoreEnabled;
+  }
+
+  /**
+   * Set a value indicating whether this service is enabled
+   * for credential store use.
+   *
+   * @param credentialStoreEnabled
+   */
+  public void setCredentialStoreEnabled(String credentialStoreEnabled) {
+    this.credentialStoreEnabled = credentialStoreEnabled;
+  }
+
   public String getComponentName() {
     return componentName;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index 75bef30..48d11c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -329,7 +329,15 @@ public class HeartBeatHandler {
           case BACKGROUND_EXECUTION_COMMAND:
           case EXECUTION_COMMAND: {
             ExecutionCommand ec = (ExecutionCommand)ac;
-            LOG.info("HeartBeatHandler.sendCommands: sending ExecutionCommand for host {}, role {}, roleCommand {}, and command ID {}, taskId {}",
+            /*
+             * Set the value of credentialStore enabled before sending the command to agent.
+             */
+            Cluster cluster = clusterFsm.getCluster(ec.getClusterName());
+            Service service = cluster.getService(ec.getServiceName());
+            if (service != null) {
+              ec.setCredentialStoreEnabled(String.valueOf(service.isCredentialStoreEnabled()));
+            }
+            LOG.info("HeartBeatHandler.sendCommands: sending ExecutionCommand for host {}, role {}, roleCommand {}, and command ID {}, task ID {}",
                      ec.getHostname(), ec.getRole(), ec.getRoleCommand(), ec.getCommandId(), ec.getTaskId());
             Map<String, String> hlp = ec.getHostLevelParams();
             if (hlp != null) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/615438b2/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index a50a116..ac58f64 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -48,6 +48,7 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -171,22 +172,31 @@ public class TestHeartbeatHandler {
     ActionManager am = actionManagerTestHelper.getMockActionManager();
     expect(am.getTasks(anyObject(List.class))).andReturn(new ArrayList<HostRoleCommand>());
     replay(am);
+
+    Cluster cluster = heartbeatTestHelper.getDummyCluster();
+    Service hdfs = cluster.addService(HDFS);
+    hdfs.addServiceComponent(DATANODE);
+    hdfs.addServiceComponent(NAMENODE);
+    hdfs.addServiceComponent(SECONDARY_NAMENODE);
+    Collection<Host> hosts = cluster.getHosts();
+    assertEquals(hosts.size(), 1);
+
     Clusters fsm = clusters;
-    fsm.addHost(DummyHostname1);
-    Host hostObject = clusters.getHost(DummyHostname1);
+    Host hostObject = hosts.iterator().next();
     hostObject.setIPv4("ipv4");
     hostObject.setIPv6("ipv6");
     hostObject.setOsType(DummyOsType);
 
+    String hostname = hostObject.getHostName();
     ActionQueue aq = new ActionQueue();
 
     HeartBeatHandler handler = new HeartBeatHandler(fsm, aq, am, injector);
     Register reg = new Register();
     HostInfo hi = new HostInfo();
-    hi.setHostName(DummyHostname1);
+    hi.setHostName(hostname);
     hi.setOS(DummyOs);
     hi.setOSRelease(DummyOSRelease);
-    reg.setHostname(DummyHostname1);
+    reg.setHostname(hostname);
     reg.setHardwareProfile(hi);
     reg.setAgentVersion(metaInfo.getServerVersion());
     handler.handleRegistration(reg);
@@ -195,19 +205,21 @@ public class TestHeartbeatHandler {
 
     ExecutionCommand execCmd = new ExecutionCommand();
     execCmd.setRequestAndStage(2, 34);
-    execCmd.setHostname(DummyHostname1);
-    aq.enqueue(DummyHostname1, new ExecutionCommand());
+    execCmd.setHostname(hostname);
+    execCmd.setClusterName(cluster.getClusterName());
+    execCmd.setServiceName(HDFS);
+    aq.enqueue(hostname, execCmd);
     HeartBeat hb = new HeartBeat();
     hb.setResponseId(0);
     HostStatus hs = new HostStatus(Status.HEALTHY, DummyHostStatus);
     List<Alert> al = new ArrayList<Alert>();
     al.add(new Alert());
     hb.setNodeStatus(hs);
-    hb.setHostname(DummyHostname1);
+    hb.setHostname(hostname);
 
     handler.handleHeartBeat(hb);
     assertEquals(HostState.HEALTHY, hostObject.getState());
-    assertEquals(0, aq.dequeueAll(DummyHostname1).size());
+    assertEquals(0, aq.dequeueAll(hostname).size());
   }
 
 


[21/24] ambari git commit: AMBARI-19049. Alerts Popup displays full error stacktrace instead of minimal content (alexantonenko)

Posted by jo...@apache.org.
AMBARI-19049. Alerts Popup displays full error stacktrace instead of minimal content (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/def3b0ae
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/def3b0ae
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/def3b0ae

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: def3b0ae85b968c7dd41307f4c671bf07d4fc826
Parents: 9348725
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Dec 2 15:18:46 2016 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Fri Dec 2 20:13:17 2016 +0200

----------------------------------------------------------------------
 .../controllers/main/service/info/summary.js    | 37 +++++++++++---------
 .../main/service/info/service_alert_popup.hbs   | 15 +++++---
 2 files changed, 31 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/def3b0ae/ambari-web/app/controllers/main/service/info/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/summary.js b/ambari-web/app/controllers/main/service/info/summary.js
index 88a6581..fc423fe 100644
--- a/ambari-web/app/controllers/main/service/info/summary.js
+++ b/ambari-web/app/controllers/main/service/info/summary.js
@@ -386,25 +386,30 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
           var property = context.get('componentName') ? 'componentName' : 'serviceName';
           var serviceDefinitions = this.get('controller.content').filterProperty(property, context.get(property));
           // definitions should be sorted in order: critical, warning, ok, unknown, other
-          var criticalDefinitions = [], warningDefinitions = [], okDefinitions = [], unknownDefinitions = [];
+          var definitionTypes = {
+            "isCritical": [],
+            "isWarning": [],
+            "isOK": [],
+            "isUnknown": []
+          };
+
           serviceDefinitions.forEach(function (definition) {
-            if (definition.get('isCritical')) {
-              criticalDefinitions.push(definition);
-              serviceDefinitions = serviceDefinitions.without(definition);
-            } else if (definition.get('isWarning')) {
-              warningDefinitions.push(definition);
-              serviceDefinitions = serviceDefinitions.without(definition);
-            } else if (definition.get('isOK')) {
-              okDefinitions.push(definition);
-              serviceDefinitions = serviceDefinitions.without(definition);
-            } else if (definition.get('isUnknown')) {
-              unknownDefinitions.push(definition);
-              serviceDefinitions = serviceDefinitions.without(definition);
-            }
+            Object.keys(definitionTypes).forEach(function (type) {
+              if (definition.get(type)) {
+                definition.set('isCollapsed', true);
+                definitionTypes[type].push(definition);
+                serviceDefinitions = serviceDefinitions.without(definition);
+              }
+            });
           });
-          serviceDefinitions = criticalDefinitions.concat(warningDefinitions, okDefinitions, unknownDefinitions, serviceDefinitions);
+          serviceDefinitions = definitionTypes.isCritical.concat(definitionTypes.isWarning, definitionTypes.isOK, definitionTypes.isUnknown, serviceDefinitions);
+
           return serviceDefinitions;
         }.property('controller.content'),
+        onToggleBlock: function (alert) {
+          this.$('#' + alert.context.clientId).toggle('blind', 500);
+          alert.context.set("isCollapsed", !alert.context.get("isCollapsed"));
+        },
         gotoAlertDetails: function (event) {
           if (event && event.context) {
             this.get('parentView').hide();
@@ -856,4 +861,4 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
     App.router.route('main' + event.context.href);
   }
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/def3b0ae/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/service/info/service_alert_popup.hbs b/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
index 3c132a3..8b72a50 100644
--- a/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
+++ b/ambari-web/app/templates/main/service/info/service_alert_popup.hbs
@@ -22,11 +22,16 @@
       <li class="alert-list-wrap">
         <div class="row">
           <div class="col-md-8 name-text">
-            <div>
-              <a href="#" {{action "gotoAlertDetails" alert target="view"}}>{{alert.label}}</a>
-            </div>
-            <div class="definition-latest-text">
-              {{alert.latestText}}
+            <div class="accordion-group block">
+              <div class="accordion-heading" {{action "onToggleBlock" alert target="view"}}>
+                <i {{bindAttr class=":pull-left :accordion-toggle alert.isCollapsed:icon-caret-right:icon-caret-down"}}></i>
+                <a class="accordion-toggle" href="#" {{action "gotoAlertDetails" alert target="view"}}>{{alert.label}}</a>
+              </div>
+              <div id="{{unbound alert.clientId}}" class="accordion-body collapse in" style="display: none">
+                <div class="accordion-inner definition-latest-text">
+                  {{alert.latestText}}
+                </div>
+              </div>
             </div>
           </div>
           <div class="col-md-4 status-col" rel="alert-status-tooltip" >


[02/24] ambari git commit: AMBARI-19006. EU to message users to start YARN queues if work preserving recovery is disabled (alejandro)

Posted by jo...@apache.org.
AMBARI-19006. EU to message users to start YARN queues if work preserving recovery is disabled (alejandro)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/63938e09
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/63938e09
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/63938e09

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 63938e09ca9e79ee541dd51104964322192e293f
Parents: 88e0c29
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Mon Nov 28 18:05:41 2016 -0800
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Thu Dec 1 09:55:33 2016 -0800

----------------------------------------------------------------------
 .../stack/upgrade/ConfigurationCondition.java   | 72 +++++++++++++++++---
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml | 27 +++++---
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml | 27 +++++---
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml | 27 +++++---
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml | 27 +++++---
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml | 27 +++++---
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml | 27 +++++---
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml | 27 +++++---
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml | 27 +++++---
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml | 27 +++++---
 .../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml | 27 +++++---
 .../src/main/resources/upgrade-pack.xsd         |  8 ++-
 12 files changed, 231 insertions(+), 119 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigurationCondition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigurationCondition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigurationCondition.java
index 1bd88e4..d229270 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigurationCondition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigurationCondition.java
@@ -52,7 +52,37 @@ public final class ConfigurationCondition extends Condition {
      * Equals comparison.
      */
     @XmlEnumValue("equals")
-    EQUALS;
+    EQUALS,
+
+    /**
+     * Not equals comparison.
+     */
+    @XmlEnumValue("not-equals")
+    NOT_EQUALS,
+
+    /**
+     * String contains.
+     */
+    @XmlEnumValue("contains")
+    CONTAINS,
+
+    /**
+     * Does not contain.
+     */
+    @XmlEnumValue("not-contains")
+    NOT_CONTAINS,
+
+    /**
+     * Exists with any value.
+     */
+    @XmlEnumValue("exists")
+    EXISTS,
+
+    /**
+     * Does not exist.
+     */
+    @XmlEnumValue("not-exists")
+    NOT_EXISTS;
   }
 
   /**
@@ -68,12 +98,18 @@ public final class ConfigurationCondition extends Condition {
   public String property;
 
   /**
-   * The value to compare against.
+   * The value to compare against; only valid if comparison type is in (=, !=, contains, !contains).
    */
   @XmlAttribute(name = "value")
   public String value;
 
   /**
+   * The value to return if comparison type is in (=, !=, contains, !contains) and the config is missing.
+   */
+  @XmlAttribute(name = "return_value_if_config_missing")
+  public boolean returnValueIfConfigMissing;
+
+  /**
    * The type of comparison to make.
    */
   @XmlAttribute(name = "comparison")
@@ -84,7 +120,7 @@ public final class ConfigurationCondition extends Condition {
    */
   @Override
   public String toString() {
-    return Objects.toStringHelper(this).add("type", type).add("property", property).add(value,
+    return Objects.toStringHelper(this).add("type", type).add("property", property).add("value",
         value).add("comparison", comparisonType).omitNullValues().toString();
   }
 
@@ -94,20 +130,40 @@ public final class ConfigurationCondition extends Condition {
   @Override
   public boolean isSatisfied(UpgradeContext upgradeContext) {
     Cluster cluster = upgradeContext.getCluster();
+
+    boolean propertyExists = false;
     Config config = cluster.getDesiredConfigByType(type);
-    if (null == config) {
-      return false;
+    Map<String, String> properties = null;
+    if (null != config) {
+      properties = config.getProperties();
+      if (properties.containsKey(property)) {
+        propertyExists = true;
+      }
+    }
+
+    if (comparisonType == ComparisonType.EXISTS) {
+      return propertyExists;
+    }
+    if (comparisonType == ComparisonType.NOT_EXISTS) {
+      return !propertyExists;
     }
 
-    Map<String, String> properties = config.getProperties();
-    if (MapUtils.isEmpty(properties)) {
-      return false;
+    // If property doesn't exist, we cannot make any claims using =, !=, contains !contains.
+    // Therefore, check if the Upgrade Pack provided a default return value when the config is missing.
+    if (!propertyExists) {
+      return returnValueIfConfigMissing;
     }
 
     String propertyValue = properties.get(property);
     switch (comparisonType) {
       case EQUALS:
         return StringUtils.equals(propertyValue, value);
+      case NOT_EQUALS:
+        return !StringUtils.equals(propertyValue, value);
+      case CONTAINS:
+        return StringUtils.contains(propertyValue, value);
+      case NOT_CONTAINS:
+        return !StringUtils.contains(propertyValue, value);
       default:
         return false;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml
index d824309..d274135 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.3.xml
@@ -36,8 +36,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -416,6 +417,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -633,16 +648,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml
index 882e78b..8c9414a 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.4.xml
@@ -36,8 +36,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -467,6 +468,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -684,16 +699,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml
index 24b90b2..37a46d0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.5.xml
@@ -47,8 +47,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -611,6 +612,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -828,16 +843,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
index 019c76e..155aaf9 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
@@ -48,8 +48,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -612,6 +613,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -829,16 +844,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml
index b7d7983..b9a7e1e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.4.xml
@@ -35,8 +35,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -409,6 +410,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -626,16 +641,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml
index 3608247..7b9b55e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.5.xml
@@ -43,8 +43,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -562,6 +563,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -779,16 +794,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
index 2a1ecf7..92ce832 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
@@ -48,8 +48,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -567,6 +568,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -784,16 +799,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml
index 414ce15..6bca487 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.5.xml
@@ -36,8 +36,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -441,6 +442,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -692,16 +707,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
index c13ad99..66f872d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
@@ -36,8 +36,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -440,6 +441,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -691,16 +706,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
index d34d476..1c65f9b 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
@@ -36,8 +36,9 @@
       <supports-auto-skip-failure>false</supports-auto-skip-failure>
 
       <execute-stage service="YARN" component="RESOURCEMANAGER" title="Stop YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
         <task xsi:type="manual">
-          <message>Before continuing, please stop all YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
+          <message>Before continuing, please stop all YARN queues.</message>
         </task>
       </execute-stage>
 
@@ -414,6 +415,20 @@
       </service>
     </group>
 
+    <group xsi:type="cluster" name="START_YARN_QUEUES" title="Start YARN Queues">
+      <direction>UPGRADE</direction>
+      <service-check>false</service-check>
+      <skippable>true</skippable>
+      <parallel-scheduler/>
+
+      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
+        <condition xsi:type="config" type="yarn-site" property="yarn.resourcemanager.work-preserving-recovery.enabled" value="true" comparison="not-equals"/>
+        <task xsi:type="manual">
+          <message>Before continuing, please start all YARN queues.</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group xsi:type="restart" name="HBASE" title="HBASE">
       <service-check>false</service-check>
       <skippable>true</skippable>
@@ -665,16 +680,6 @@
       </execute-stage>
     </group>
 
-    <group xsi:type="cluster" name="MANUAL_STEPS" title="Finishing Upgrade">
-      <direction>UPGRADE</direction>
-
-      <execute-stage service="YARN" component="RESOURCEMANAGER" title="Start YARN Queues">
-        <task xsi:type="manual">
-          <message>Please start previously stopped YARN queues. If yarn-site's yarn.resourcemanager.work-preserving-recovery.enabled is set to true, then you can skip this step since the clients will retry on their own.</message>
-        </task>
-      </execute-stage>
-    </group>
-
     <group xsi:type="cluster" name="POST_CLUSTER" title="Finalize {{direction.text.proper}}">
       <skippable>true</skippable>
       <supports-auto-skip-failure>false</supports-auto-skip-failure>

http://git-wip-us.apache.org/repos/asf/ambari/blob/63938e09/ambari-server/src/main/resources/upgrade-pack.xsd
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/upgrade-pack.xsd b/ambari-server/src/main/resources/upgrade-pack.xsd
index 45cf5fa..aeec803 100644
--- a/ambari-server/src/main/resources/upgrade-pack.xsd
+++ b/ambari-server/src/main/resources/upgrade-pack.xsd
@@ -66,6 +66,11 @@
   <xs:simpleType name="config-condition-comparison-type">
     <xs:restriction base="xs:string">
       <xs:enumeration value="equals" />
+      <xs:enumeration value="not-equals" />
+      <xs:enumeration value="contains" />
+      <xs:enumeration value="not-contains" />
+      <xs:enumeration value="exists" />
+      <xs:enumeration value="not-exists" />
     </xs:restriction>
   </xs:simpleType>
   
@@ -76,7 +81,8 @@
       <xs:extension base="abstract-condition-type">  
         <xs:attribute name="type" type="xs:Name" use="required"/>
         <xs:attribute name="property" type="xs:Name" use="required"/>
-        <xs:attribute name="value" type="xs:string" use="required"/>
+        <xs:attribute name="value" type="xs:string" use="optional"/>
+        <xs:attribute name="return_value_if_config_missing" type="xs:boolean" use="optional"/>
         <xs:attribute name="comparison" type="config-condition-comparison-type" use="required"/>
       </xs:extension>
     </xs:complexContent>


[22/24] ambari git commit: AMBARI-19020. Ubuntu14/16 Add Support for Zookeeper on HDP 2.5 (Duc Le via ncole)

Posted by jo...@apache.org.
AMBARI-19020. Ubuntu14/16 Add Support for Zookeeper on HDP 2.5 (Duc Le via ncole)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/05fe4235
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/05fe4235
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/05fe4235

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 05fe42351131f77a6ee5d58da355b1c461562046
Parents: def3b0a
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Dec 2 13:23:36 2016 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Dec 2 13:23:36 2016 -0500

----------------------------------------------------------------------
 .../main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/05fe4235/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml b/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml
index 525078e..cbb5ba2 100644
--- a/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/ZOOKEEPER/3.4.6/metainfo.xml
@@ -35,7 +35,7 @@
           </packages>
         </osSpecific>
         <osSpecific>
-          <osFamily>ubuntu12</osFamily>
+          <osFamily>ubuntu12,ubuntu14,ubuntu16</osFamily>
           <packages>
             <package>
               <name>zookeeper-${stack_version}</name>


[10/24] ambari git commit: AMBARI-19061. Ambari-server restart command not working. if any parameters are changed and reset to default. (aonishuk)

Posted by jo...@apache.org.
AMBARI-19061. Ambari-server restart command not working. if any parameters are changed and reset to default.  (aonishuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2de7ee8d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2de7ee8d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2de7ee8d

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 2de7ee8d01ce850bbbf9844ad8789615b6570168
Parents: c2dc753
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Fri Dec 2 11:45:57 2016 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Fri Dec 2 11:45:57 2016 +0200

----------------------------------------------------------------------
 .../src/main/python/ambari_server/utils.py      | 23 ++++++++++----------
 1 file changed, 12 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2de7ee8d/ambari-server/src/main/python/ambari_server/utils.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server/utils.py b/ambari-server/src/main/python/ambari_server/utils.py
index 26e59ae..fc631f5 100644
--- a/ambari-server/src/main/python/ambari_server/utils.py
+++ b/ambari-server/src/main/python/ambari_server/utils.py
@@ -127,17 +127,18 @@ def save_main_pid_ex(pids, pidfile, exclude_list=[], skip_daemonize=False):
   """
   pid_saved = False
   try:
-    pfile = open(pidfile, "w")
-    for item in pids:
-      if pid_exists(item["pid"]) and (item["exe"] not in exclude_list):
-        pfile.write("%s\n" % item["pid"])
-        pid_saved = True
-        logger.info("Ambari server started with PID " + str(item["pid"]))
-      if pid_exists(item["pid"]) and (item["exe"] in exclude_list) and not skip_daemonize:
-        try:
-          os.kill(int(item["pid"]), signal.SIGKILL)
-        except:
-          pass
+    if pids:
+      pfile = open(pidfile, "w")
+      for item in pids:
+        if pid_exists(item["pid"]) and (item["exe"] not in exclude_list):
+          pfile.write("%s\n" % item["pid"])
+          pid_saved = True
+          logger.info("Ambari server started with PID " + str(item["pid"]))
+        if pid_exists(item["pid"]) and (item["exe"] in exclude_list) and not skip_daemonize:
+          try:
+            os.kill(int(item["pid"]), signal.SIGKILL)
+          except:
+            pass
   except IOError as e:
     logger.error("Failed to write PID to " + pidfile + " due to " + str(e))
     pass


[20/24] ambari git commit: AMBARI-19064 Refactor widgets on Dashboard page. (atkach)

Posted by jo...@apache.org.
AMBARI-19064 Refactor widgets on Dashboard page. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9348725b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9348725b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9348725b

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 9348725b1067fab38907c8eebc172978729394ad
Parents: 7eb2eaa
Author: Andrii Tkach <at...@apache.org>
Authored: Fri Dec 2 19:27:20 2016 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Dec 2 19:27:20 2016 +0200

----------------------------------------------------------------------
 .../mixins/main/dashboard/widgets/editable.js   |  47 +-
 .../main/dashboard/edit_widget_popup.hbs        |   4 +-
 .../edit_widget_popup_single_threshold.hbs      |   2 +-
 .../main/dashboard/plus_button_filter.hbs       |   2 +-
 .../app/templates/main/dashboard/widgets.hbs    |   8 +-
 .../main/dashboard/widgets/pie_chart.hbs        |   5 +-
 .../app/views/common/not-scrollable-textarea.js |   2 +-
 ambari-web/app/views/main/dashboard/widget.js   | 159 ++--
 ambari-web/app/views/main/dashboard/widgets.js  | 824 +++++++++----------
 .../main/dashboard/widgets/datanode_live.js     |   7 -
 .../main/dashboard/widgets/flume_agent_live.js  |   7 -
 .../main/dashboard/widgets/hawqsegment_live.js  |   7 -
 .../dashboard/widgets/hbase_average_load.js     |  11 +-
 .../views/main/dashboard/widgets/hbase_links.js |   4 -
 .../main/dashboard/widgets/hbase_master_heap.js |   4 -
 .../dashboard/widgets/hbase_master_uptime.js    |   5 -
 .../widgets/hbase_regions_in_transition.js      |  10 +-
 .../main/dashboard/widgets/hdfs_capacity.js     |   4 -
 .../views/main/dashboard/widgets/hdfs_links.js  |   4 -
 .../views/main/dashboard/widgets/metrics_cpu.js |   3 -
 .../main/dashboard/widgets/metrics_load.js      |   3 -
 .../main/dashboard/widgets/metrics_memory.js    |   3 -
 .../main/dashboard/widgets/metrics_network.js   |   3 -
 .../main/dashboard/widgets/namenode_cpu.js      |   4 -
 .../main/dashboard/widgets/namenode_heap.js     |   4 -
 .../main/dashboard/widgets/namenode_rpc.js      |  10 +-
 .../main/dashboard/widgets/namenode_uptime.js   |   5 -
 .../dashboard/widgets/node_managers_live.js     |   7 -
 .../main/dashboard/widgets/pie_chart_widget.js  |  16 +-
 .../views/main/dashboard/widgets/pxf_live.js    |   6 -
 .../dashboard/widgets/resource_manager_heap.js  |   4 -
 .../widgets/resource_manager_uptime.js          |   5 -
 .../main/dashboard/widgets/supervisor_live.js   |   7 -
 .../views/main/dashboard/widgets/text_widget.js |   4 +-
 .../widgets/text_widget_single_threshold.js     |   6 +-
 .../dashboard/widgets/uptime_text_widget.js     |   2 -
 .../views/main/dashboard/widgets/yarn_links.js  |   4 -
 .../views/main/dashboard/widgets/yarn_memory.js |   4 -
 .../test/views/main/dashboard/widget_test.js    | 200 ++---
 .../widgets/hbase_average_load_test.js          |   4 +-
 .../widgets/hbase_regions_in_transition_test.js |   6 +-
 .../main/dashboard/widgets/namenode_rpc_test.js |  13 +-
 .../text_widget_single_threshold_test.js        |  10 +-
 .../main/dashboard/widgets/text_widget_test.js  |  10 +-
 .../widgets/uptime_text_widget_test.js          |   2 +-
 .../test/views/main/dashboard/widgets_test.js   | 669 ++++++---------
 46 files changed, 813 insertions(+), 1317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/dashboard/widgets/editable.js b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
index f330ec3..3206229 100644
--- a/ambari-web/app/mixins/main/dashboard/widgets/editable.js
+++ b/ambari-web/app/mixins/main/dashboard/widgets/editable.js
@@ -23,24 +23,24 @@ App.EditableWidgetMixin = Em.Mixin.create({
   hintInfo: '',
 
   editWidget: function () {
-    var parent = this;
+    var self = this;
     var configObj = Ember.Object.create({
-      thresh1: parent.get('thresh1') + '',
-      thresh2: parent.get('thresh2') + '',
-      hintInfo: parent.get('hintInfo'),
+      thresholdMin: self.get('thresholdMin') + '',
+      thresholdMax: self.get('thresholdMax') + '',
+      hintInfo: self.get('hintInfo'),
       isThresh1Error: false,
       isThresh2Error: false,
       errorMessage1: "",
       errorMessage2: "",
       maxValue: 'infinity',
       observeNewThresholdValue: function () {
-        var thresh1 = this.get('thresh1');
-        var thresh2 = this.get('thresh2');
-        if (thresh1.trim() !== "") {
-          if (isNaN(thresh1) || thresh1 < 0) {
+        var thresholdMin = this.get('thresholdMin');
+        var thresholdMax = this.get('thresholdMax');
+        if (thresholdMin.trim() !== "") {
+          if (isNaN(thresholdMin) || thresholdMin < 0) {
             this.set('isThresh1Error', true);
             this.set('errorMessage1', 'Invalid! Enter a number larger than 0');
-          } else if ( this.get('isThresh2Error') === false && parseFloat(thresh2)<= parseFloat(thresh1)){
+          } else if ( this.get('isThresh2Error') === false && parseFloat(thresholdMax)<= parseFloat(thresholdMin)){
             this.set('isThresh1Error', true);
             this.set('errorMessage1', 'Threshold 1 should be smaller than threshold 2 !');
           } else {
@@ -52,8 +52,8 @@ App.EditableWidgetMixin = Em.Mixin.create({
           this.set('errorMessage1', 'This is required');
         }
 
-        if (thresh2.trim() !== "") {
-          if (isNaN(thresh2) || thresh2 < 0) {
+        if (thresholdMax.trim() !== "") {
+          if (isNaN(thresholdMax) || thresholdMax < 0) {
             this.set('isThresh2Error', true);
             this.set('errorMessage2', 'Invalid! Enter a number larger than 0');
           } else {
@@ -65,12 +65,12 @@ App.EditableWidgetMixin = Em.Mixin.create({
           this.set('errorMessage2', 'This is required');
         }
 
-      }.observes('thresh1', 'thresh2')
+      }.observes('thresholdMin', 'thresholdMax')
 
     });
 
-    var browserVerion = this.getInternetExplorerVersion();
-    App.ModalPopup.show( {
+    var browserVersion = this.getInternetExplorerVersion();
+    App.ModalPopup.show({
       header: Em.I18n.t('dashboard.widgets.popupHeader'),
       classNames: [ 'modal-edit-widget'],
       modalDialogClasses: ['modal-lg'],
@@ -82,17 +82,12 @@ App.EditableWidgetMixin = Em.Mixin.create({
       onPrimary: function () {
         configObj.observeNewThresholdValue();
         if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          parent.set('thresh1', parseFloat(configObj.get('thresh1')) );
-          parent.set('thresh2', parseFloat(configObj.get('thresh2')) );
-          if (!App.get('testMode')) {
-            //save to persist
-            var bigParent = parent.get('parentView');
-            bigParent.getUserPref(bigParent.get('persistKey'));
-            var oldValue = bigParent.get('currentPrefObject');
-            oldValue.threshold[parseInt(parent.id, 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-            bigParent.postUserPref(bigParent.get('persistKey'),oldValue);
-          }
 
+          var parent = self.get('parentView');
+          var userPreferences = parent.get('userPreferences');
+          userPreferences.threshold[Number(self.get('id'))] = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
+          parent.saveWidgetsSettings(userPreferences);
+          parent.renderWidgets();
           this.hide();
         }
       },
@@ -102,7 +97,7 @@ App.EditableWidgetMixin = Em.Mixin.create({
         var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
         var handlers = [33, 66]; //fixed value
 
-        if (browserVerion === -1 || browserVerion > 9) {
+        if (browserVersion === -1 || browserVersion > 9) {
           configObj.set('isIE9', false);
           configObj.set('isGreenOrangeRed', true);
           $("#slider-range").slider({
@@ -112,7 +107,7 @@ App.EditableWidgetMixin = Em.Mixin.create({
             max: 100,
             values: handlers,
             create: function (event, ui) {
-              parent.updateColors(handlers, colors);
+              self.updateColors(handlers, colors);
             }
           });
         } else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
index 3a36ed6..3802e29 100644
--- a/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
+++ b/ambari-web/app/templates/main/dashboard/edit_widget_popup.hbs
@@ -41,13 +41,13 @@
           <input type="text" value="0" disabled="disabled" class="form-control" />
         </div>
         <div id="slider-value2" {{bindAttr class="view.configPropertyObj.isThresh1Error:slider-error :value-on-slider :col-md-4 view.configPropertyObj.isThresh1Error:has-error"}}>
-          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresh1"}}
+          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresholdMin"}}
           {{#if view.configPropertyObj.errorMessage1}}
             <span class="help-block validation-block">{{view.configPropertyObj.errorMessage1}}</span>
           {{/if}}
         </div>
         <div id="slider-value3" {{bindAttr class="view.configPropertyObj.isThresh2Error:slider-error :value-on-slider :col-md-4 view.configPropertyObj.isThresh2Error:has-error"}}>
-          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresh2"}}
+          {{view Ember.TextField class="form-control" valueBinding="view.configPropertyObj.thresholdMax"}}
           {{#if view.configPropertyObj.errorMessage1}}
             <span class="help-block validation-block">{{view.configPropertyObj.errorMessage2}}</span>
           {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
index d80e601..982dc9b 100644
--- a/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
+++ b/ambari-web/app/templates/main/dashboard/edit_widget_popup_single_threshold.hbs
@@ -43,7 +43,7 @@
       <input type="text" value="0" disabled="disabled" class="form-control" />
     </div>
       <div id="slider-value2" {{bindAttr class="view.configPropertyObj.isThresh1Error:slider-error :value-on-slider :col-md-4 :col-md-offset-2 :col-sm-offset-2 view.configPropertyObj.isThresh1Error:has-error"}}>
-        {{view Ember.TextField valueBinding="view.configPropertyObj.thresh1" class="form-control"}}
+        {{view Ember.TextField valueBinding="view.configPropertyObj.thresholdMin" class="form-control"}}
         {{#if view.configPropertyObj.errorMessage1}}
           <span class="help-block validation-block">{{view.configPropertyObj.errorMessage1}}</span>
         {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
index df7714c..81420ff 100644
--- a/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
+++ b/ambari-web/app/templates/main/dashboard/plus_button_filter.hbs
@@ -21,7 +21,7 @@
       <ul>
         {{#each widget in view.hiddenWidgets}}
           <li>
-            {{view view.widgetCheckbox class="checkbox" checkedBinding="widget.checked" labelBinding="widget.displayName"}}
+            {{view view.widgetCheckbox class="checkbox" checkedBinding="widget.checked" labelBinding="widget.title"}}
           </li>
         {{/each}}
       </ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/widgets.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/widgets.hbs b/ambari-web/app/templates/main/dashboard/widgets.hbs
index a778033..8e04f1c 100644
--- a/ambari-web/app/templates/main/dashboard/widgets.hbs
+++ b/ambari-web/app/templates/main/dashboard/widgets.hbs
@@ -48,13 +48,13 @@
     <div id="dashboard-widgets"  class="widgets-container">
       <div class="thumbnails" id="sortable">
         {{#if view.visibleWidgets.length}}
-          {{#each widgetClass in view.visibleWidgets}}
-            <div {{bindAttr class="widgetClass.class"}}>
-              {{view widgetClass }}
-            </div>
+          {{#each widget in view.visibleWidgets}}
+             {{view widget.viewClass widgetBinding="widget"}}
           {{/each}}
         {{/if}}
       </div>
     </div>
   </div>
+{{else}}
+  {{view App.SpinnerView}}
 {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
index fdeafd1..1b14503 100644
--- a/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
+++ b/ambari-web/app/templates/main/dashboard/widgets/pie_chart.hbs
@@ -42,7 +42,10 @@
 
         {{#if view.isPieExist}}
           <div {{bindAttr class=":widget-content view.hoverContentTopClass"}}>
-            {{view view.content modelBinding="view.model" thresh1Binding="view.thresh1" thresh2Binding="view.thresh2"}}
+            {{view view.content
+                modelBinding="view.model"
+                thresholdMinBinding="view.thresholdMin"
+                thresholdMaxBinding="view.thresholdMax"}}
           </div>
         {{else}}
           <div class="widget-content-isNA">{{t services.service.summary.notAvailable}}</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/common/not-scrollable-textarea.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/not-scrollable-textarea.js b/ambari-web/app/views/common/not-scrollable-textarea.js
index 1898714..d0e4178 100644
--- a/ambari-web/app/views/common/not-scrollable-textarea.js
+++ b/ambari-web/app/views/common/not-scrollable-textarea.js
@@ -26,7 +26,7 @@ var App = require('app');
  */
 App.NotScrollableTextArea = Em.TextArea.extend({
 
-  didInsertElement() {
+  didInsertElement: function() {
     this.fitHeight();
     this.$().select();
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widget.js b/ambari-web/app/views/main/dashboard/widget.js
index cc5be28..495db2e 100644
--- a/ambari-web/app/views/main/dashboard/widget.js
+++ b/ambari-web/app/views/main/dashboard/widget.js
@@ -24,26 +24,30 @@ App.DashboardWidgetView = Em.View.extend({
    * @type {string}
    * @default null
    */
-  title: null,
-  templateName: null, // each has specific template
+  title: Em.computed.alias('widget.title'),
+
+  templateName: null,
+
+  sourceName: Em.computed.alias('widget.sourceName'),
+
+  widget: null,
 
   /**
-   * Setup model for widget by `model_type`. Usually `model_type` is a lowercase service name,
-   * for example `hdfs`, `yarn`, etc. You need to set `model_type` in extended object View, for example
-   * look App.DataNodeUpView.
-   * @type {object} - model that set up in App.MainDashboardView.setWidgetsDataModel()
+   * @type {object} - record from model that serve as data source
    */
   model : function () {
-    if (!this.get('model_type')) return {};
-    return this.get('parentView').get(this.get('model_type') + '_model');
-  }.property(),
+    var model = Em.Object.create();
+    if (Em.isNone(this.get('sourceName'))) {
+      return model;
+    }
+    return this.findModelBySource(this.get('sourceName'));
+  }.property('sourceName'),
 
   /**
-   * id 1-10 used to identify
    * @type {number}
    * @default null
    */
-  id: null,
+  id: Em.computed.alias('widget.id'),
 
   /**
    * html id bind to view-class: widget-(1)
@@ -52,6 +56,8 @@ App.DashboardWidgetView = Em.View.extend({
    */
   viewID: Em.computed.format('widget-{0}', 'id'),
 
+  classNames: ['span2p4'],
+
   attributeBindings: ['viewID'],
 
   /**
@@ -74,15 +80,19 @@ App.DashboardWidgetView = Em.View.extend({
 
   /**
    * @type {number}
-   * @default null
+   * @default 0
    */
-  thresh1: null,
+  thresholdMin: function() {
+    return Em.isNone(this.get('widget.threshold')) ? 0 : this.get('widget.threshold')[0];
+  }.property('widget.threshold'),
 
   /**
    * @type {number}
-   * @default null
+   * @default 0
    */
-  thresh2: null,
+  thresholdMax: function() {
+    return Em.isNone(this.get('widget.threshold')) ? 0 : this.get('widget.threshold')[1];
+  }.property('widget.threshold'),
 
   /**
    * @type {Boolean}
@@ -95,8 +105,8 @@ App.DashboardWidgetView = Em.View.extend({
    * @class
    */
   widgetConfig: Ember.Object.extend({
-    thresh1: '',
-    thresh2: '',
+    thresholdMin: '',
+    thresholdMax: '',
     hintInfo: Em.computed.i18nFormat('dashboard.widgets.hintInfo.common', 'maxValue'),
     isThresh1Error: false,
     isThresh2Error: false,
@@ -104,15 +114,15 @@ App.DashboardWidgetView = Em.View.extend({
     errorMessage2: "",
     maxValue: 0,
     observeThresh1Value: function () {
-      var thresh1 = this.get('thresh1');
-      var thresh2 = this.get('thresh2');
+      var thresholdMin = this.get('thresholdMin');
+      var thresholdMax = this.get('thresholdMax');
       var maxValue = this.get('maxValue');
 
-      if (thresh1.trim() !== "") {
-        if (isNaN(thresh1) || thresh1 > maxValue || thresh1 < 0) {
+      if (thresholdMin.trim() !== "") {
+        if (isNaN(thresholdMin) || thresholdMin > maxValue || thresholdMin < 0) {
           this.set('isThresh1Error', true);
           this.set('errorMessage1', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
-        } else if (this.get('isThresh2Error') === false && parseFloat(thresh2) <= parseFloat(thresh1)) {
+        } else if (this.get('isThresh2Error') === false && parseFloat(thresholdMax) <= parseFloat(thresholdMin)) {
           this.set('isThresh1Error', true);
           this.set('errorMessage1', Em.I18n.t('dashboard.widgets.error.smaller'));
         } else {
@@ -124,13 +134,13 @@ App.DashboardWidgetView = Em.View.extend({
         this.set('errorMessage1', Em.I18n.t('admin.users.editError.requiredField'));
       }
       this.updateSlider();
-    }.observes('thresh1', 'maxValue'),
+    }.observes('thresholdMin', 'maxValue'),
     observeThresh2Value: function () {
-      var thresh2 = this.get('thresh2');
+      var thresholdMax = this.get('thresholdMax');
       var maxValue = this.get('maxValue');
 
-      if (thresh2.trim() !== "") {
-        if (isNaN(thresh2) || thresh2 > maxValue || thresh2 < 0) {
+      if (thresholdMax.trim() !== "") {
+        if (isNaN(thresholdMax) || thresholdMax > maxValue || thresholdMax < 0) {
           this.set('isThresh2Error', true);
           this.set('errorMessage2', Em.I18n.t('dashboard.widgets.error.invalid').format(maxValue));
         } else {
@@ -142,15 +152,15 @@ App.DashboardWidgetView = Em.View.extend({
         this.set('errorMessage2', Em.I18n.t('admin.users.editError.requiredField'));
       }
       this.updateSlider();
-    }.observes('thresh2', 'maxValue'),
+    }.observes('thresholdMax', 'maxValue'),
     updateSlider: function () {
-      var thresh1 = this.get('thresh1');
-      var thresh2 = this.get('thresh2');
+      var thresholdMin = this.get('thresholdMin');
+      var thresholdMax = this.get('thresholdMax');
       // update the slider handles and color
       if (this.get('isThresh1Error') === false && this.get('isThresh2Error') === false) {
         $("#slider-range")
-          .slider('values', 0, parseFloat(thresh1))
-          .slider('values', 1, parseFloat(thresh2));
+          .slider('values', 0, parseFloat(thresholdMin))
+          .slider('values', 1, parseFloat(thresholdMax));
       }
     }
   }),
@@ -162,46 +172,36 @@ App.DashboardWidgetView = Em.View.extend({
     });
   },
 
+  findModelBySource: function (source) {
+    if (source === 'HOST_METRICS' && App.get('services.hostMetrics').length > 0) {
+      return App.get('services.hostMetrics');
+    }
+    var extendedModel = App.Service.extendedModel[source];
+    if (extendedModel) {
+      return App[extendedModel].find(source);
+    } else {
+      return App.Service.find(source);
+    }
+  },
+
   willDestroyElement : function() {
     $("[rel='ZoomInTooltip']").tooltip('destroy');
   },
+
   /**
    * delete widget
-   * @param {object} event
    */
   deleteWidget: function () {
     var parent = this.get('parentView');
-    var self = this;
-
-    if (App.get('testMode')) {
-      //update view on dashboard
-      var objClass = parent.widgetsMapper(this.get('id'));
-      parent.get('visibleWidgets').removeObject(objClass);
-      parent.get('hiddenWidgets').pushObject(Em.Object.create({displayName: this.get('title'), id: this.get('id'), checked: false}));
-    } else {
-      //reconstruct new persist value then post in persist
-      parent.getUserPref(parent.get('persistKey')).complete(function () {
-        self.deleteWidgetComplete.apply(self);
-      });
-    }
-  },
-
-  /**
-   * delete widget complete callback
-   */
-  deleteWidgetComplete: function () {
-    var parent = this.get('parentView');
-    var oldValue = parent.get('currentPrefObject');
+    var userPreferences = parent.get('userPreferences');
     var deletedId = this.get('id');
-    var newValue = Em.Object.create({
-      dashboardVersion: oldValue.dashboardVersion,
-      visible: oldValue.visible.slice(0).without(deletedId),
-      hidden: oldValue.hidden,
-      threshold: oldValue.threshold
-    });
-    newValue.hidden.push([deletedId, this.get('title')]);
-    parent.postUserPref(parent.get('persistKey'), newValue);
-    parent.translateToReal(newValue);
+    var newValue = {
+      visible: userPreferences.visible.slice(0).without(deletedId),
+      hidden: userPreferences.hidden.concat([deletedId]),
+      threshold: userPreferences.threshold
+    };
+    parent.saveWidgetsSettings(newValue);
+    parent.renderWidgets();
   },
 
   /**
@@ -210,8 +210,8 @@ App.DashboardWidgetView = Em.View.extend({
    */
   editWidget: function (event) {
     var configObj = this.get('widgetConfig').create({
-      thresh1: this.get('thresh1') + '',
-      thresh2: this.get('thresh2') + '',
+      thresholdMin: this.get('thresholdMin') + '',
+      thresholdMax: this.get('thresholdMax') + '',
       maxValue: parseFloat(this.get('maxValue'))
     });
     this.showEditDialog(configObj)
@@ -239,18 +239,14 @@ App.DashboardWidgetView = Em.View.extend({
         configObj.observeThresh1Value();
         configObj.observeThresh2Value();
         if (!configObj.isThresh1Error && !configObj.isThresh2Error) {
-          self.set('thresh1', parseFloat(configObj.get('thresh1')));
-          self.set('thresh2', parseFloat(configObj.get('thresh2')));
-
-          if (!App.get('testMode')) {
-            // save to persist
-            var parent = self.get('parentView');
-            parent.getUserPref(parent.get('persistKey')).complete(function () {
-              var oldValue = parent.get('currentPrefObject');
-              oldValue.threshold[parseInt(self.get('id'), 10)] = [configObj.get('thresh1'), configObj.get('thresh2')];
-              parent.postUserPref(parent.get('persistKey'), oldValue);
-            });
-          }
+          self.set('thresholdMin', parseFloat(configObj.get('thresholdMin')));
+          self.set('thresholdMax', parseFloat(configObj.get('thresholdMax')));
+
+          var parent = self.get('parentView');
+          var userPreferences = parent.get('userPreferences');
+          userPreferences.threshold[Number(self.get('id'))] = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
+          parent.saveWidgetsSettings(userPreferences);
+          parent.renderWidgets();
 
           this.hide();
         }
@@ -259,7 +255,7 @@ App.DashboardWidgetView = Em.View.extend({
       didInsertElement: function () {
         this._super();
         var browserVersion = self.getInternetExplorerVersion();
-        var handlers = [configObj.get('thresh1'), configObj.get('thresh2')];
+        var handlers = [configObj.get('thresholdMin'), configObj.get('thresholdMax')];
         var colors = [App.healthStatusGreen, App.healthStatusOrange, App.healthStatusRed]; //color green, orange ,red
 
         if (browserVersion === -1 || browserVersion > 9) {
@@ -275,8 +271,8 @@ App.DashboardWidgetView = Em.View.extend({
             },
             slide: function (event, ui) {
               updateColors(ui.values);
-              configObj.set('thresh1', ui.values[0] + '');
-              configObj.set('thresh2', ui.values[1] + '');
+              configObj.set('thresholdMin', ui.values[0] + '');
+              configObj.set('thresholdMax', ui.values[1] + '');
             },
             change: function (event, ui) {
               updateColors(ui.values);
@@ -351,8 +347,3 @@ App.DashboardWidgetView = Em.View.extend({
   }.property('hiddenInfo.length')
 
 });
-
-
-App.DashboardWidgetView.reopenClass({
-  class: 'span2p4'
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets.js b/ambari-web/app/views/main/dashboard/widgets.js
index 999fc08..4e22aad 100644
--- a/ambari-web/app/views/main/dashboard/widgets.js
+++ b/ambari-web/app/views/main/dashboard/widgets.js
@@ -20,20 +20,187 @@ var App = require('app');
 var filters = require('views/common/filter_view');
 
 App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, App.TimeRangeMixin, {
-
   name: 'mainDashboardWidgetsView',
-
   templateName: require('templates/main/dashboard/widgets'),
 
-  didInsertElement: function () {
-    this._super();
-    this.setWidgetsDataModel();
-    this.setInitPrefObject();
-    this.setOnLoadVisibleWidgets();
-    this.set('isDataLoaded', true);
-    App.loadTimer.finish('Dashboard Metrics Page');
-    Em.run.next(this, 'makeSortable');
-  },
+  widgetsDefinition: [
+    {
+      id: 1,
+      viewName: 'NameNodeHeapPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeHeap'),
+      threshold: [80, 90]
+    },
+    {
+      id: 2,
+      viewName: 'NameNodeCapacityPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
+      threshold: [85, 95]
+    },
+    {
+      id: 3,
+      viewName: 'NameNodeCpuPieChartView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeCpu'),
+      threshold: [90, 95]
+    },
+    {
+      id: 4,
+      viewName: 'DataNodeUpView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.DataNodeUp'),
+      threshold: [80, 90]
+    },
+    {
+      id: 5,
+      viewName: 'NameNodeRpcView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeRpc'),
+      threshold: [1000, 3000]
+    },
+    {
+      id: 6,
+      viewName: 'ChartClusterMetricsMemoryWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.memory'),
+      threshold: []
+    },
+    {
+      id: 7,
+      viewName: 'ChartClusterMetricsNetworkWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.network'),
+      threshold: []
+    },
+    {
+      id: 8,
+      viewName: 'ChartClusterMetricsCPUWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.cpu'),
+      threshold: []
+    },
+    {
+      id: 9,
+      viewName: 'ChartClusterMetricsLoadWidgetView',
+      sourceName: 'HOST_METRICS',
+      title: Em.I18n.t('dashboard.clusterMetrics.load'),
+      threshold: []
+    },
+    {
+      id: 10,
+      viewName: 'NameNodeUptimeView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.NameNodeUptime'),
+      threshold: []
+    },
+    {
+      id: 11,
+      viewName: 'HDFSLinksView',
+      sourceName: 'HDFS',
+      title: Em.I18n.t('dashboard.widgets.HDFSLinks'),
+      threshold: []
+    },
+    {
+      id: 12,
+      viewName: 'HBaseLinksView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseLinks'),
+      threshold: []
+    },
+    {
+      id: 13,
+      viewName: 'HBaseMasterHeapPieChartView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseMasterHeap'),
+      threshold: [70, 90]
+    },
+    {
+      id: 14,
+      viewName: 'HBaseAverageLoadView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseAverageLoad'),
+      threshold: [150, 250]
+    },
+    {
+      id: 15,
+      viewName: 'HBaseRegionsInTransitionView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseRegionsInTransition'),
+      threshold: [3, 10],
+      isHiddenByDefault: true
+    },
+    {
+      id: 16,
+      viewName: 'HBaseMasterUptimeView',
+      sourceName: 'HBASE',
+      title: Em.I18n.t('dashboard.widgets.HBaseMasterUptime'),
+      threshold: []
+    },
+    {
+      id: 17,
+      viewName: 'ResourceManagerHeapPieChartView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.ResourceManagerHeap'),
+      threshold: [70, 90]
+    },
+    {
+      id: 18,
+      viewName: 'ResourceManagerUptimeView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.ResourceManagerUptime'),
+      threshold: []
+    },
+    {
+      id: 19,
+      viewName: 'NodeManagersLiveView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.NodeManagersLive'),
+      threshold: [50, 75]
+    },
+    {
+      id: 20,
+      viewName: 'YARNMemoryPieChartView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.YARNMemory'),
+      threshold: [50, 75]
+    },
+    {
+      id: 21,
+      viewName: 'SuperVisorUpView',
+      sourceName: 'STORM',
+      title: Em.I18n.t('dashboard.widgets.SuperVisorUp'),
+      threshold: [85, 95]
+    },
+    {
+      id: 22,
+      viewName: 'FlumeAgentUpView',
+      sourceName: 'FLUME',
+      title: Em.I18n.t('dashboard.widgets.FlumeAgentUp'),
+      threshold: [85, 95]
+    },
+    {
+      id: 23,
+      viewName: 'YARNLinksView',
+      sourceName: 'YARN',
+      title: Em.I18n.t('dashboard.widgets.YARNLinks'),
+      threshold: []
+    },
+    {
+      id: 24,
+      viewName: 'HawqSegmentUpView',
+      sourceName: 'HAWQ',
+      title: Em.I18n.t('dashboard.widgets.HawqSegmentUp'),
+      threshold: [75, 90]
+    },
+    {
+      id: 25,
+      viewName: 'PxfUpView',
+      sourceName: 'PXF',
+      title: Em.I18n.t('dashboard.widgets.PxfUp'),
+      threshold: []
+    }
+  ],
 
   /**
    * List of services
@@ -42,6 +209,12 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
   content: [],
 
   /**
+   * Key-name to store data in Local Storage and Persist
+   * @type {string}
+   */
+  persistKey: Em.computed.format('user-pref-{0}-dashboard', 'App.router.loginName'),
+
+  /**
    * @type {boolean}
    */
   isDataLoaded: false,
@@ -52,177 +225,6 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
    */
   isMoving: false,
 
-  timeRangeClassName: 'pull-left',
-
-  /**
-   * Make widgets' list sortable on New Dashboard style
-   */
-  makeSortable: function () {
-    var self = this;
-    $("#sortable").sortable({
-      items: "> div",
-      //placeholder: "sortable-placeholder",
-      cursor: "move",
-      tolerance: "pointer",
-      scroll: false,
-      update: function (event, ui) {
-        if (!App.get('testMode')) {
-          // update persist then translate to real
-          var widgetsArray = $('div[viewid]'); // get all in DOM
-          self.getUserPref(self.get('persistKey')).complete(function () {
-            var oldValue = self.get('currentPrefObject') || self.getDBProperty(self.get('persistKey'));
-            var newValue = Em.Object.create({
-              dashboardVersion: oldValue.dashboardVersion,
-              visible: [],
-              hidden: oldValue.hidden,
-              threshold: oldValue.threshold
-            });
-            var size = oldValue.visible.length;
-            for (var j = 0; j <= size - 1; j++) {
-              var viewID = widgetsArray.get(j).getAttribute('viewid');
-              var id = viewID.split("-").get(1);
-              newValue.visible.push(id);
-            }
-            self.postUserPref(self.get('persistKey'), newValue);
-            self.setDBProperty(self.get('persistKey'), newValue);
-            //self.translateToReal(newValue);
-          });
-        }
-      },
-      activate: function (event, ui) {
-        self.set('isMoving', true);
-      },
-      deactivate: function (event, ui) {
-        self.set('isMoving', false);
-      }
-    }).disableSelection();
-  },
-
-  /**
-   * Set Service model values
-   */
-  setWidgetsDataModel: function () {
-    if (App.get('services.hostMetrics').length > 0) {
-      this.set('host_metrics_model', App.get('services.hostMetrics'));
-    }
-    App.Service.find().forEach(function (item) {
-      var extendedModel = App.Service.extendedModel[item.get('serviceName')];
-      var key = item.get('serviceName').toLowerCase() + '_model';
-      if (extendedModel && App[extendedModel].find(item.get('id'))) {
-        this.set(key, App[extendedModel].find(item.get('id')));
-      } else {
-        this.set(key, item);
-      }
-    }, this);
-  },
-
-  resolveConfigDependencies: function(visibleFull, hiddenFull) {
-    var clusterEnv = App.router.get('clusterController.clusterEnv').properties;
-
-    if (clusterEnv['hide_yarn_memory_widget'] === 'true') {
-      hiddenFull.push(['20', 'YARN Memory']);
-    } else {
-      visibleFull.splice(visibleFull.indexOf('19'), 0, '20');
-    }
-  },
-
-  /**
-   * Load widget statuses to <code>initPrefObject</code>
-   */
-  setInitPrefObject: function () {
-    //in case of some service not installed
-    var visibleFull = [
-      '2', '4', '11', //hdfs
-      '6', '7', '8', '9', //host metrics
-      '1', '5', '3', '10', //hdfs
-      '13', '12', '14', '16', //hbase
-      '17', '18', '19', '23', // all yarn
-      '21', // storm
-      '22', // flume
-      '24', // hawq
-      '25' // pxf
-    ]; // all in order
-    var hiddenFull = [
-      ['15', 'Region In Transition']
-    ];
-    this.resolveConfigDependencies(visibleFull, hiddenFull);
-
-    // Display widgets for host metrics if the stack definition has a host metrics service to display it.
-    if (this.get('host_metrics_model') == null) {
-      var hostMetrics = ['6', '7', '8', '9'];
-      hostMetrics.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-
-    if (this.get('hdfs_model') == null) {
-      var hdfs = ['1', '2', '3', '4', '5', '10', '11'];
-      hdfs.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('hbase_model') == null) {
-      var hbase = ['12', '13', '14', '16'];
-      hbase.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-      hiddenFull = hiddenFull.filter(function(item) {
-        return item[0] !== '15';
-      });
-    }
-    if (this.get('yarn_model') == null) {
-      var yarn = ['17', '18', '19', '20', '23'];
-      yarn.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('storm_model') == null) {
-      var storm = ['21'];
-      storm.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('flume_model') == null) {
-      var flume = ['22'];
-      flume.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('hawq_model') == null) {
-      var hawq = ['24'];
-      hawq.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    if (this.get('pxf_model') == null) {
-      var pxf = ['25'];
-      pxf.forEach(function (item) {
-        visibleFull = visibleFull.without(item);
-      }, this);
-    }
-    var obj = this.get('initPrefObject');
-    obj.set('visible', visibleFull);
-    obj.set('hidden', hiddenFull);
-  },
-
-  host_metrics_model: null,
-
-  hdfs_model: null,
-
-  mapreduce2_model: null,
-
-  yarn_model: null,
-
-  hbase_model: null,
-
-  storm_model: null,
-
-  flume_model: null,
-
-  hawq_model: null,
-
-  pxf_model: null,
-
   /**
    * List of visible widgets
    * @type {Ember.Enumerable}
@@ -235,302 +237,162 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
    */
   hiddenWidgets: [], // widget child view will push object in this array if deleted
 
-  /**
-   * Submenu view for New Dashboard style
-   * @type {Ember.View}
-   * @class
-   */
-  plusButtonFilterView: Ember.View.extend({
-    tagName: 'ul',
-    classNames: ['dropdown-menu'],
-    templateName: require('templates/main/dashboard/plus_button_filter'),
-    hiddenWidgetsBinding: 'parentView.hiddenWidgets',
-    visibleWidgetsBinding: 'parentView.visibleWidgets',
-    valueBinding: '',
-    widgetCheckbox: App.CheckboxView.extend({
-      didInsertElement: function () {
-        $('.checkbox').click(function (event) {
-          event.stopPropagation();
-        });
-      }
-    }),
-    closeFilter: Em.K,
-    applyFilter: function () {
-      var self = this;
-      var parent = this.get('parentView');
-      var hiddenWidgets = this.get('hiddenWidgets');
-      var checkedWidgets = hiddenWidgets.filterProperty('checked', true);
-
-      if (App.get('testMode')) {
-        var visibleWidgets = this.get('visibleWidgets');
-        checkedWidgets.forEach(function (item) {
-          var newObj = parent.widgetsMapper(item.id);
-          visibleWidgets.pushObject(newObj);
-          hiddenWidgets.removeObject(item);
-        }, this);
-      } else {
-        //save in persist
-        parent.getUserPref(parent.get('persistKey')).complete(function(){
-          self.applyFilterComplete.apply(self);
-        });
-      }
-    },
-    applyFilterComplete: function () {
-      var parent = this.get('parentView'),
-        hiddenWidgets = this.get('hiddenWidgets'),
-        oldValue = parent.get('currentPrefObject'),
-        newValue = Em.Object.create({
-          dashboardVersion: oldValue.dashboardVersion,
-          visible: oldValue.visible,
-          hidden: [],
-          threshold: oldValue.threshold
-        });
-      hiddenWidgets.filterProperty('checked').forEach(function (item) {
-        newValue.visible.push(item.id);
-        hiddenWidgets.removeObject(item);
-      }, this);
-      hiddenWidgets.forEach(function (item) {
-        newValue.hidden.push([item.id, item.displayName]);
-      }, this);
-      parent.postUserPref(parent.get('persistKey'), newValue);
-      parent.translateToReal(newValue);
-    }
-  }),
+  timeRangeClassName: 'pull-left',
 
   /**
-   * Translate from Json value got from persist to real widgets view
+   * Example:
+   * {
+   *   visible: [1, 2, 4],
+   *   hidden: [3, 5],
+   *   threshold: {
+   *     1: [80, 90],
+   *     2: [],
+   *     3: [1, 2]
+   *   }
+   * }
+   * @type {Object|null}
    */
-  translateToReal: function (value) {
-    var version = value.dashboardVersion;
-    var visible = value.visible;
-    var hidden = value.hidden;
-    var threshold = value.threshold;
-
-    if (version === 'new') {
-      var visibleWidgets = [];
-      var hiddenWidgets = [];
-      // re-construct visibleWidgets and hiddenWidgets
-      for (var i = 0; i < visible.length; i++) {
-        var id = visible[i];
-        var widgetClass = this.widgetsMapper(id);
-        //override with new threshold
-        if (threshold[id].length > 0) {
-          widgetClass.reopen({
-            thresh1: threshold[id][0],
-            thresh2: threshold[id][1]
-          });
-        }
-        visibleWidgets.pushObject(widgetClass);
-      }
-      for (var j = 0; j < hidden.length; j++) {
-        var title = hidden[j][1];
-        hiddenWidgets.pushObject(Em.Object.create({displayName: title, id: hidden[j][0], checked: false}));
-      }
-      this.set('visibleWidgets', visibleWidgets);
-      this.set('hiddenWidgets', hiddenWidgets);
-    }
+  userPreferences: null,
+
+  didInsertElement: function () {
+    var self = this;
+
+    this._super();
+    this.loadWidgetsSettings().complete(function() {
+      self.checkServicesChange();
+      self.renderWidgets();
+      self.set('isDataLoaded', true);
+      App.loadTimer.finish('Dashboard Metrics Page');
+      Em.run.next(self, 'makeSortable');
+    });
   },
 
   /**
    * Set visibility-status for widgets
    */
-  setOnLoadVisibleWidgets: function () {
-    var self = this;
-    if (App.get('testMode')) {
-      this.translateToReal(this.get('initPrefObject'));
-    } else {
-      // called when first load/refresh/jump back page
-      this.getUserPref(this.get('persistKey')).complete(function () {
-        if (self.get('state') === 'inDOM') {
-          self.setOnLoadVisibleWidgetsComplete.apply(self);
-        }
-      });
-    }
+  loadWidgetsSettings: function () {
+    return this.getUserPref(this.get('persistKey'));
   },
 
   /**
-   * complete load of visible widgets
+   * make POST call to save settings
+   * @param {object} settings
    */
-  setOnLoadVisibleWidgetsComplete: function () {
-    var currentPrefObject = this.get('currentPrefObject') || this.getDBProperty(this.get('persistKey'));
-    if (currentPrefObject) { // fit for no dashboard version
-      if (!currentPrefObject.dashboardVersion) {
-        currentPrefObject.dashboardVersion = 'new';
-        this.postUserPref(this.get('persistKey'), currentPrefObject);
-        this.setDBProperty(this.get('persistKey'), currentPrefObject);
-      }
-      this.set('currentPrefObject', this.checkServicesChange(currentPrefObject));
-      this.translateToReal(this.get('currentPrefObject'));
-    }
-    else {
-      // post persist then translate init object
-      this.postUserPref(this.get('persistKey'), this.get('initPrefObject'));
-      this.setDBProperty(this.get('persistKey'), this.get('initPrefObject'));
-      this.translateToReal(this.get('initPrefObject'));
-    }
+  saveWidgetsSettings: function (settings) {
+    this.set('userPreferences', settings);
+    this.setDBProperty(this.get('persistKey'), settings);
+    this.postUserPref(this.get('persistKey'), settings);
   },
 
-  /**
-   * Remove widget from visible and hidden lists
-   * @param {Object} value
-   * @param {Object} widget
-   * @returns {*}
-   */
-  removeWidget: function (value, widget) {
-    value.visible = value.visible.without(widget);
-    for (var j = 0; j < value.hidden.length; j++) {
-      if (value.hidden[j][0] == widget) {
-        value.hidden.splice(j, 1);
-      }
+  getUserPrefSuccessCallback: function (response) {
+    if (response) {
+      this.set('userPreferences', response);
+    } else {
+      this.getUserPrefErrorCallback();
     }
-    return value;
   },
 
-  /**
-   * Check if widget is in visible or hidden list
-   * @param {Object} value
-   * @param {Object} widget
-   * @returns {bool}
-   */
-  containsWidget: function (value, widget) {
-    var flag = value.visible.contains(widget);
-    for (var j = 0; j < value.hidden.length; j++) {
-      if (!flag && value.hidden[j][0] == widget) {
-        flag = true;
-        break;
-      }
+  getUserPrefErrorCallback: function () {
+    var userPreferences = this.generateDefaultUserPreferences();
+    this.saveWidgetsSettings(userPreferences);
+  },
+
+  resolveConfigDependencies: function(widgetsDefinition) {
+    var clusterEnv = App.router.get('clusterController.clusterEnv').properties;
+    var yarnMemoryWidget = widgetsDefinition.findProperty('id', 20);
+
+    if (clusterEnv['hide_yarn_memory_widget'] === 'true') {
+      yarnMemoryWidget.isHiddenByDefault = true;
     }
-    return flag;
   },
 
-  /**
-   * check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services.
-   * Update the value on server if true.
-   * @param {Object} currentPrefObject
-   * @return {Object}
-   */
-  checkServicesChange: function (currentPrefObject) {
-    var toDelete = $.extend(true, {}, currentPrefObject);
-    var toAdd = [];
-    var serviceWidgetsMap = {
-      hdfs_model: ['1', '2', '3', '4', '5', '10', '11'],
-      host_metrics_model: ['6', '7', '8', '9'],
-      hbase_model: ['12', '13', '14', '15', '16'],
-      yarn_model: ['17', '18', '19', '20', '23'],
-      storm_model: ['21'],
-      flume_model: ['22'],
-      hawq_model: ['24'],
-      pxf_model: ['25']
+  generateDefaultUserPreferences: function() {
+    var widgetsDefinition = this.get('widgetsDefinition');
+    var preferences = {
+      visible: [],
+      hidden: [],
+      threshold: {}
     };
 
-    // check each service, find out the newly added service and already deleted service
-    Em.keys(serviceWidgetsMap).forEach(function (modelName) {
-      if (!Em.isNone(this.get(modelName))) {
-        var ids = serviceWidgetsMap[modelName];
-        var flag = this.containsWidget(toDelete, ids[0]);
-        if (flag) {
-          ids.forEach(function (item) {
-            toDelete = this.removeWidget(toDelete, item);
-          }, this);
+    this.resolveConfigDependencies(widgetsDefinition);
+
+    widgetsDefinition.forEach(function(widget) {
+      if (App.Service.find(widget.sourceName).get('isLoaded') || widget.sourceName === 'HOST_METRICS') {
+        if (widget.isHiddenByDefault) {
+          preferences.hidden.push(widget.id);
         } else {
-          toAdd = toAdd.concat(ids);
+          preferences.visible.push(widget.id);
         }
       }
-    }, this);
+      preferences.threshold[widget.id] = widget.threshold;
+    });
 
-    var value = currentPrefObject;
-    if (toDelete.visible.length || toDelete.hidden.length) {
-      toDelete.visible.forEach(function (item) {
-        value = this.removeWidget(value, item);
-      }, this);
-      toDelete.hidden.forEach(function (item) {
-        value = this.removeWidget(value, item[0]);
-      }, this);
-    }
-    if (toAdd.length) {
-      value.visible = value.visible.concat(toAdd);
-      var allThreshold = this.get('initPrefObject').threshold;
-      // add new threshold OR override with default value
-      toAdd.forEach(function (item) {
-        value.threshold[item] = allThreshold[item];
-      }, this);
-    }
-    return value;
+    return preferences;
   },
 
   /**
-   * Get view for widget by widget's id
-   * @param {string} id
-   * @returns {Ember.View}
+   * set widgets to view in order to render
    */
-  widgetsMapper: function (id) {
-    return Em.get({
-      '1': App.NameNodeHeapPieChartView,
-      '2': App.NameNodeCapacityPieChartView,
-      '3': App.NameNodeCpuPieChartView,
-      '4': App.DataNodeUpView,
-      '5': App.NameNodeRpcView,
-      '6': App.ChartClusterMetricsMemoryWidgetView,
-      '7': App.ChartClusterMetricsNetworkWidgetView,
-      '8': App.ChartClusterMetricsCPUWidgetView,
-      '9': App.ChartClusterMetricsLoadWidgetView,
-      '10': App.NameNodeUptimeView,
-      '11': App.HDFSLinksView,
-      '12': App.HBaseLinksView,
-      '13': App.HBaseMasterHeapPieChartView,
-      '14': App.HBaseAverageLoadView,
-      '15': App.HBaseRegionsInTransitionView,
-      '16': App.HBaseMasterUptimeView,
-      '17': App.ResourceManagerHeapPieChartView,
-      '18': App.ResourceManagerUptimeView,
-      '19': App.NodeManagersLiveView,
-      '20': App.YARNMemoryPieChartView,
-      '21': App.SuperVisorUpView,
-      '22': App.FlumeAgentUpView,
-      '23': App.YARNLinksView,
-      '24': App.HawqSegmentUpView,
-      '25': App.PxfUpView
-    }, id);
-  },
+  renderWidgets: function () {
+    var widgetsDefinitionMap = this.get('widgetsDefinition').toMapByProperty('id');
+    var userPreferences = this.get('userPreferences');
+    var visibleWidgets = [];
+    var hiddenWidgets = [];
+
+    userPreferences.visible.forEach(function(id) {
+      var widget = widgetsDefinitionMap[id];
+      visibleWidgets.push(Em.Object.create({
+        id: id,
+        threshold: userPreferences.threshold[id],
+        viewClass: App[widget.viewName],
+        sourceName: widget.sourceName,
+        title: widget.title
+      }));
+    });
 
-  /**
-   * @type {Object|null}
-   */
-  currentPrefObject: null,
+    userPreferences.hidden.forEach(function(id) {
+      var widget = widgetsDefinitionMap[id];
+      hiddenWidgets.push(Em.Object.create({
+        id: id,
+        title: widget.title,
+        checked: false
+      }));
+    });
 
-  /**
-   * @type {Ember.Object}
-   */
-  initPrefObject: Em.Object.create({
-    dashboardVersion: 'new',
-    visible: [],
-    hidden: [],
-    threshold: {1: [80, 90], 2: [85, 95], 3: [90, 95], 4: [80, 90], 5: [1000, 3000], 6: [], 7: [], 8: [], 9: [], 10: [], 11: [], 12: [], 13: [70, 90], 14: [150, 250], 15: [3, 10], 16: [],
-      17: [70, 90], 18: [], 19: [50, 75], 20: [50, 75], 21: [85, 95], 22: [85, 95], 23: [], 24: [75, 90], 25: []} // id:[thresh1, thresh2]
-  }),
+    this.set('visibleWidgets', visibleWidgets);
+    this.set('hiddenWidgets', hiddenWidgets);
+  },
 
   /**
-   * Key-name to store data in Local Storage and Persist
-   * @type {string}
+   * check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services.
+   * Update the value on server if true.
    */
-  persistKey: Em.computed.format('user-pref-{0}-dashboard', 'App.router.loginName'),
+  checkServicesChange: function () {
+    var userPreferences = this.get('userPreferences');
+    var defaultPreferences = this.generateDefaultUserPreferences();
+    var newValue = {
+      visible: userPreferences.visible.slice(0),
+      hidden: userPreferences.hidden.slice(0),
+      threshold: userPreferences.threshold
+    };
+    var isChanged = false;
 
-  getUserPrefSuccessCallback: function (response, request, data) {
-    if (response) {
-      var initPrefObject = this.get('initPrefObject');
-      initPrefObject.get('threshold');
-      for(var k in response.threshold) {
-        if (response.threshold.hasOwnProperty(k)) {
-          if (response.threshold[k].length === 0 && initPrefObject.get('threshold')[k] && initPrefObject.get('threshold')[k].length) {
-            response.threshold[k] = initPrefObject.get('threshold')[k];
-          }
-        }
+    defaultPreferences.visible.forEach(function(id) {
+      if (!userPreferences.visible.contains(id) && !userPreferences.hidden.contains(id)) {
+        isChanged = true;
+        newValue.visible.push(id);
       }
-      this.set('currentPrefObject', response);
-    }
-  },
+    });
 
-  getUserPrefErrorCallback: function (request) {
+    defaultPreferences.hidden.forEach(function(id) {
+      if (!userPreferences.visible.contains(id) && !userPreferences.hidden.contains(id)) {
+        isChanged = true;
+        newValue.hidden.push(id);
+      }
+    });
+    if (isChanged) {
+      this.saveWidgetsSettings(newValue);
+    }
   },
 
   /**
@@ -539,19 +401,91 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, Ap
   resetAllWidgets: function () {
     var self = this;
     App.showConfirmationPopup(function () {
-      if (!App.get('testMode')) {
-        self.postUserPref(self.get('persistKey'), self.get('initPrefObject'));
-        self.setDBProperty(self.get('persistKey'), self.get('initPrefObject'));
-      }
+      self.saveWidgetsSettings(self.generateDefaultUserPreferences());
       self.setProperties({
         currentTimeRangeIndex: 0,
         customStartTime: null,
         customEndTime: null
       });
-      self.translateToReal(self.get('initPrefObject'));
+      self.renderWidgets();
     });
   },
 
+  /**
+   * Make widgets' list sortable on New Dashboard style
+   */
+  makeSortable: function () {
+    var self = this;
+    return $("#sortable").sortable({
+      items: "> div",
+      cursor: "move",
+      tolerance: "pointer",
+      scroll: false,
+      update: function () {
+        var widgetsArray = $('div[viewid]');
+
+        var userPreferences = self.get('userPreferences') || self.getDBProperty(self.get('persistKey'));
+        var newValue = Em.Object.create({
+          visible: [],
+          hidden: userPreferences.hidden,
+          threshold: userPreferences.threshold
+        });
+        var size = userPreferences.visible.length;
+        for (var j = 0; j <= size - 1; j++) {
+          var viewID = widgetsArray.get(j).getAttribute('viewid');
+          var id = Number(viewID.split("-").get(1));
+          newValue.visible.push(id);
+        }
+        self.saveWidgetsSettings(newValue);
+      },
+      activate: function (event, ui) {
+        self.set('isMoving', true);
+      },
+      deactivate: function (event, ui) {
+        self.set('isMoving', false);
+      }
+    }).disableSelection();
+  },
+
+  /**
+   * Submenu view for New Dashboard style
+   * @type {Ember.View}
+   * @class
+   */
+  plusButtonFilterView: Ember.View.extend({
+    tagName: 'ul',
+    classNames: ['dropdown-menu'],
+    templateName: require('templates/main/dashboard/plus_button_filter'),
+    hiddenWidgetsBinding: 'parentView.hiddenWidgets',
+    valueBinding: '',
+    widgetCheckbox: App.CheckboxView.extend({
+      didInsertElement: function () {
+        $('.checkbox').click(function (event) {
+          event.stopPropagation();
+        });
+      }
+    }),
+    closeFilter: Em.K,
+    applyFilter: function () {
+      var parent = this.get('parentView'),
+        hiddenWidgets = this.get('hiddenWidgets'),
+        userPreferences = parent.get('userPreferences'),
+        newValue = {
+          visible: userPreferences.visible.slice(0),
+          hidden: userPreferences.hidden.slice(0),
+          threshold: userPreferences.threshold
+        };
+
+      hiddenWidgets.filterProperty('checked').forEach(function (item) {
+        newValue.visible.push(item.id);
+        newValue.hidden = newValue.hidden.without(item.id);
+        hiddenWidgets.removeObject(item);
+      }, this);
+      parent.saveWidgetsSettings(newValue);
+      parent.renderWidgets();
+    }
+  }),
+
   showAlertsPopup: Em.K
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/datanode_live.js b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
index 184b046..ff1daaa 100644
--- a/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/datanode_live.js
@@ -30,11 +30,6 @@ function counterOrNA(key) {
 
 App.DataNodeUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.DataNodeUp'),
-  id: '4',
-
-  model_type: 'hdfs',
-
   hiddenInfo: function () {
     return [
       this.get('dataNodesLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -45,8 +40,6 @@ App.DataNodeUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWid
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   dataNodesLive: counterOrNA('liveDataNodes'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js b/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
index e8169c9..280c25d 100644
--- a/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/flume_agent_live.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.FlumeAgentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.FlumeAgentUp'),
-  id: '22',
-
-  model_type: 'flume',
-
   hiddenInfo: function () {
     return [
       this.get('flumeAgentsLive.length') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -34,8 +29,6 @@ App.FlumeAgentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitW
 
   hiddenInfoClass: "hidden-info-two-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   flumeAgentComponents: Em.computed.filterBy('model.hostComponents', 'componentName', 'FLUME_HANDLER'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
index 04e7d66..ac35c07 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hawqsegment_live.js
@@ -31,11 +31,6 @@ function counterOrNA(key) {
 
 App.HawqSegmentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.HawqSegmentUp'),
-  id: '24',
-
-  model_type: 'hawq',
-
   hiddenInfo: function () {
     return [
       this.get('hawqSegmentsStarted') + ' ' + Em.I18n.t('dashboard.services.components.started'),
@@ -46,8 +41,6 @@ App.HawqSegmentUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimit
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 75,
-  thresh2: 90,
   maxValue: 100,
 
   hawqSegmentsStarted: counterOrNA('hawqSegmentsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js b/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
index 48c4de0..986953f 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_average_load.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.HBaseAverageLoad'),
-  id: '14',
-
-  model_type: 'hbase',
-
   hiddenInfo: function () {
     var avgLoad = this.get('model.averageLoad');
     if (isNaN(avgLoad)) {
@@ -33,15 +28,13 @@ App.HBaseAverageLoadView = App.TextDashboardWidgetView.extend(App.EditableWidget
     return [Em.I18n.t('dashboard.services.hbase.averageLoadPerServer').format(avgLoad)];
   }.property("model.averageLoad"),
 
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
 
   isNA: function (){
     return this.get('data') === null || isNaN(this.get('data'));
   }.property('data'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
   data: Em.computed.alias('model.averageLoad'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_links.js b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
index 4f2053a..9600094 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_links.js
@@ -21,10 +21,6 @@ var App = require('app');
 App.HBaseLinksView = App.LinkDashboardWidgetView.extend({
 
   templateName: require('templates/main/dashboard/widgets/hbase_links'),
-  title: Em.I18n.t('dashboard.widgets.HBaseLinks'),
-  id: '12',
-
-  model_type: 'hbase',
 
   port: function() {
     return App.StackService.find('HBASE').compareCurrentVersion('1.1') > -1 ? '16010' : '60010';

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js b/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
index 63b1cc2..4ddba36 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_master_heap.js
@@ -21,10 +21,6 @@ var numberUtils = require('utils/number_utils');
 
 App.HBaseMasterHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HBaseMasterHeap'),
-  id: '13',
-
-  model_type: 'hbase',
   modelFieldMax: 'heapMemoryMax',
   modelFieldUsed: 'heapMemoryUsed',
   widgetHtmlId: 'widget-hbase-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
index 0801ac2..ea338dd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_master_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.HBaseMasterUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HBaseMasterUptime'),
-  id: '16',
-
-  model_type: 'hbase',
-
   component: 'Hbase Master',
   modelField: 'masterStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js b/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
index 1f225c6..922a10e 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hbase_regions_in_transition.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.HBaseRegionsInTransition'),
-  id: '15',
-
-  model_type: 'hbase',
   hiddenInfo: function () {
     return [
       this.get("model.regionsInTransition") + " regions",
@@ -32,15 +28,13 @@ App.HBaseRegionsInTransitionView = App.TextDashboardWidgetView.extend(App.Editab
   }.property("model.regionsInTransition"),
 
   classNameBindings: ['isRed', 'isOrange', 'isGreen', 'isNA'],
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
   isOrange: Em.computed.and('!isGreen', '!isRed'),
   isNA: function () {
     return this.get('data') === null;
   }.property('data'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
   data: Em.computed.alias('model.regionsInTransition'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
index e64534d..6bc19d9 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_capacity.js
@@ -21,10 +21,6 @@ var numberUtils = require('utils/number_utils');
 
 App.NameNodeCapacityPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.HDFSDiskUsage'),
-  id: '2',
-
-  model_type: 'hdfs',
   modelFieldMax: 'capacityTotal',
   /**
    * HDFS model has 'remaining' value, but not 'used'

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
index cfe5eb1..900a900 100644
--- a/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/hdfs_links.js
@@ -21,10 +21,6 @@ var App = require('app');
 App.HDFSLinksView = App.LinkDashboardWidgetView.extend({
 
   templateName: require('templates/main/dashboard/widgets/hdfs_links'),
-  title: Em.I18n.t('dashboard.widgets.HDFSLinks'),
-  id: '11',
-
-  model_type: 'hdfs',
 
   port: '50070',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
index 72ef1c2..b7efaab 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_cpu.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsCPUWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.cpu'),
-  id: '8',
-
   content: App.ChartClusterMetricsCPU.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_load.js b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
index c357934..c13e047 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_load.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsLoadWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.load'),
-  id: '9',
-
   content: App.ChartClusterMetricsLoad.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
index 659d647..824c9dd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_memory.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsMemoryWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.memory'),
-  id: '6',
-
   content: App.ChartClusterMetricsMemory.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/metrics_network.js b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
index 40fdb0b..8f9e6cd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
+++ b/ambari-web/app/views/main/dashboard/widgets/metrics_network.js
@@ -20,9 +20,6 @@ var App = require('app');
 
 App.ChartClusterMetricsNetworkWidgetView = App.ClusterMetricsDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.clusterMetrics.network'),
-  id: '7',
-
   content: App.ChartClusterMetricsNetwork.extend({
     noTitleUnderGraph: true,
     inWidget: true

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
index 161b5c0..d6a3ebd 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_cpu.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeCpuPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeCpu'),
-  id: '3',
-
-  model_type: 'hdfs',
   widgetHtmlId: 'widget-nn-cpu',
   cpuWio: null,
   nnHostName: "",

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
index 731143c..2ef6470 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_heap.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeHeap'),
-  id: '1',
-
-  model_type: 'hdfs',
   modelFieldMax: 'jvmMemoryHeapMax',
   modelFieldUsed: 'jvmMemoryHeapUsed',
   widgetHtmlId: 'widget-nn-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
index 58b86d9..769fd22 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_rpc.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.NameNodeRpcView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeRpc'),
-  id: '5',
-
-  model_type: 'hdfs',
   hiddenInfo: function () {
     return [
       this.get('content') + ' average RPC',
@@ -31,13 +27,11 @@ App.NameNodeRpcView = App.TextDashboardWidgetView.extend(App.EditableWidgetMixin
     ];
   }.property('content'),
 
-  thresh1: 0.5,
-  thresh2: 2,
   maxValue: 'infinity',
 
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
 
-  isRed: Em.computed.gtProperties('data', 'thresh2'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMax'),
 
   data: function () {
     if (this.get('model.nameNodeRpc')) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
index e55f871..30ae592 100644
--- a/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/namenode_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.NameNodeUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.NameNodeUptime'),
-  id: '10',
-
-  model_type: 'hdfs',
-
   component: 'NameNode',
   modelField: 'nameNodeStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js b/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
index d5bf50b..5dc5430 100644
--- a/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.NodeManagersLiveView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.NodeManagersLive'),
-  id: '19',
-
-  model_type: 'yarn',
-
   hiddenInfo: function () {
     var nmActive = this.get('model.nodeManagersCountActive') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountActive');
     var nmLost = this.get('model.nodeManagersCountLost') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.nodeManagersCountLost');
@@ -43,8 +38,6 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend(App.EditableWithLi
 
   hiddenInfoClass: "hidden-info-five-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   isDataAvailable: Em.computed.and('!model.metricsNotAvailable', 'App.router.clusterController.isComponentsStateLoaded'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js b/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
index 8f2dc90..5dd85d1 100644
--- a/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/pie_chart_widget.js
@@ -85,8 +85,8 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
     model: null,  //data bind here
     id: Em.computed.alias('parentView.widgetHtmlId'), // html id
     stroke: '#D6DDDF', //light grey
-    thresh1: null, //bind from parent
-    thresh2: null,
+    thresholdMin: null, //bind from parent
+    thresholdMax: null,
     innerR: 25,
 
     existCenterText: true,
@@ -107,15 +107,15 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
 
     contentColor: function () {
       var used = parseFloat(this.get('parentView.dataForPieChart')[1]);
-      var thresh1 = parseFloat(this.get('thresh1'));
-      var thresh2 = parseFloat(this.get('thresh2'));
-      if (used <= thresh1) {
+      var thresholdMin = parseFloat(this.get('thresholdMin'));
+      var thresholdMax = parseFloat(this.get('thresholdMax'));
+      if (used <= thresholdMin) {
         this.set('palette', new Rickshaw.Color.Palette({
           scheme: ['#FFFFFF', App.healthStatusGreen].reverse()
         }));
         return App.healthStatusGreen;
       }
-      if (used <= thresh2) {
+      if (used <= thresholdMax) {
         this.set('palette', new Rickshaw.Color.Palette({
           scheme: ['#FFFFFF', App.healthStatusOrange].reverse()
         }));
@@ -125,7 +125,7 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
         scheme: ['#FFFFFF', App.healthStatusRed].reverse()
       }));
       return App.healthStatusRed;
-    }.property('data', 'thresh1', 'thresh2'),
+    }.property('data', 'thresholdMin', 'thresholdMax'),
 
     // refresh text and color when data in model changed
     refreshSvg: function () {
@@ -137,6 +137,6 @@ App.PieChartDashboardWidgetView = App.DashboardWidgetView.extend({
 
       // draw new svg
       this.appendSvg();
-    }.observes('data', 'thresh1', 'thresh2')
+    }.observes('data', 'thresholdMin', 'thresholdMax')
   })
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/pxf_live.js b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
index 74b2096..a002fe3 100644
--- a/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/pxf_live.js
@@ -31,11 +31,6 @@ function counterOrNA(key) {
 
 App.PxfUpView = App.TextDashboardSingleThresholdWidgetView.extend(App.SingleNumericThresholdMixin,{
 
-  title: Em.I18n.t('dashboard.widgets.PxfUp'),
-  id: '25',
-
-  model_type: 'pxf',
-
   hiddenInfo: function () {
     return [
       this.get('pxfsStarted') + ' ' + Em.I18n.t('dashboard.services.components.started'),
@@ -46,7 +41,6 @@ App.PxfUpView = App.TextDashboardSingleThresholdWidgetView.extend(App.SingleNume
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 0,
   maxValue: counterOrNA('pxfsTotal'),
 
   pxfsStarted: counterOrNA('pxfsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
index 9509053..e0e6514 100644
--- a/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
+++ b/ambari-web/app/views/main/dashboard/widgets/resource_manager_heap.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.ResourceManagerHeapPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.ResourceManagerHeap'),
-  id: '17',
-
-  model_type: 'yarn',
   modelFieldMax: 'jvmMemoryHeapMax',
   modelFieldUsed: 'jvmMemoryHeapUsed',
   widgetHtmlId: 'widget-rm-heap',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
index 6d87741..72f2ca3 100644
--- a/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
+++ b/ambari-web/app/views/main/dashboard/widgets/resource_manager_uptime.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.ResourceManagerUptimeView = App.UptimeTextDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.ResourceManagerUptime'),
-  id: '18',
-
-  model_type: 'yarn',
-
   component: 'ResourceManager',
   modelField: 'resourceManagerStartTime',
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
index b8e36ca..9158e59 100644
--- a/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
+++ b/ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
@@ -20,11 +20,6 @@ var App = require('app');
 
 App.SuperVisorUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitWidgetMixin, {
 
-  title: Em.I18n.t('dashboard.widgets.SuperVisorUp'),
-  id: '21',
-
-  model_type: 'storm',
-
   hiddenInfo: function () {
     return [
       this.get('superVisorsLive') + ' ' + Em.I18n.t('dashboard.services.hdfs.nodes.live'),
@@ -34,8 +29,6 @@ App.SuperVisorUpView = App.TextDashboardWidgetView.extend(App.EditableWithLimitW
 
   hiddenInfoClass: "hidden-info-two-line",
 
-  thresh1: 40,
-  thresh2: 70,
   maxValue: 100,
 
   superVisorsLive: Em.computed.alias('model.superVisorsStarted'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/text_widget.js b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
index 388ea52..daa354c 100644
--- a/ambari-web/app/views/main/dashboard/widgets/text_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/text_widget.js
@@ -24,9 +24,9 @@ App.TextDashboardWidgetView = App.DashboardWidgetView.extend({
 
   classNameBindings: ['isRed', 'isOrange', 'isGreen', 'isNA'],
 
-  isRed: Em.computed.lteProperties('data', 'thresh1'),
+  isRed: Em.computed.lteProperties('data', 'thresholdMin'),
   isOrange: Em.computed.and('!isGreen', '!isRed'),
-  isGreen: Em.computed.gtProperties('data', 'thresh2'),
+  isGreen: Em.computed.gtProperties('data', 'thresholdMax'),
 
   isNA: function () {
     return this.get('data') === null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
index 69c5821..e079446 100644
--- a/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
+++ b/ambari-web/app/views/main/dashboard/widgets/text_widget_single_threshold.js
@@ -23,8 +23,8 @@ App.TextDashboardSingleThresholdWidgetView = App.DashboardWidgetView.extend({
   templateName: require('templates/main/dashboard/widgets/simple_text'),
 
   classNameBindings: ['isRed', 'isGreen', 'isNA'],
-  isGreen: Em.computed.lteProperties('data', 'thresh1'),
-  isRed: Em.computed.gtProperties('data', 'thresh1'),
+  isGreen: Em.computed.lteProperties('data', 'thresholdMin'),
+  isRed: Em.computed.gtProperties('data', 'thresholdMin'),
 
   isNA: function () {
     return this.get('data') === null;
@@ -32,6 +32,6 @@ App.TextDashboardSingleThresholdWidgetView = App.DashboardWidgetView.extend({
 
   hiddenInfo: [],
 
-  maxValue: null,
+  maxValue: null
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
index 792aa70..74d59f1 100644
--- a/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
+++ b/ambari-web/app/views/main/dashboard/widgets/uptime_text_widget.js
@@ -27,8 +27,6 @@ App.UptimeTextDashboardWidgetView = App.TextDashboardWidgetView.extend({
 
   hiddenInfoClass: "hidden-info-three-line",
 
-  thresh1: 5,
-  thresh2: 10,
   maxValue: 'infinity',
 
   component: null,

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/yarn_links.js b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
index d7b6488..e7be6d2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
+++ b/ambari-web/app/views/main/dashboard/widgets/yarn_links.js
@@ -20,10 +20,6 @@ var App = require('app');
 
 App.YARNLinksView = App.LinkDashboardWidgetView.extend({
   templateName: require('templates/main/dashboard/widgets/yarn_links'),
-  title: Em.I18n.t('dashboard.widgets.YARNLinks'),
-  id: '23',
-
-  model_type: 'yarn',
 
   componentName : 'NODEMANAGER'
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9348725b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
index b4dc9b7..be3beb2 100644
--- a/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
+++ b/ambari-web/app/views/main/dashboard/widgets/yarn_memory.js
@@ -20,11 +20,7 @@ var App = require('app');
 
 App.YARNMemoryPieChartView = App.PieChartDashboardWidgetView.extend({
 
-  title: Em.I18n.t('dashboard.widgets.YARNMemory'),
-  id: '20',
-
   widgetHtmlId: 'widget-yarn-memory',
-  model_type: 'yarn',
   modelFieldUsed: 'allocatedMemory',
   modelFieldMax: 'maxMemory',
 


[04/24] ambari git commit: AMBARI-19032 HDFS Metric alerts turns to UNKNOWN state with error "'NoneType' object has no attribute 'split'" (dsen)

Posted by jo...@apache.org.
AMBARI-19032 HDFS Metric alerts turns to UNKNOWN state with error "'NoneType' object has no attribute 'split'" (dsen)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/406b245e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/406b245e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/406b245e

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 406b245ef9ed3a43fdf4d974dc1a7fc467c576a4
Parents: 63c0f2e
Author: Dmytro Sen <ds...@apache.org>
Authored: Thu Dec 1 22:15:26 2016 +0200
Committer: Dmytro Sen <ds...@apache.org>
Committed: Thu Dec 1 22:15:26 2016 +0200

----------------------------------------------------------------------
 .../ambari_commons/ambari_metrics_helper.py     | 45 +++++++++++---------
 .../timeline/AbstractTimelineMetricsSink.java   |  6 +--
 .../AbstractTimelineMetricSinkTest.java         | 10 ++---
 .../timeline/HadoopTimelineMetricsSink.java     |  4 +-
 .../timeline/HadoopTimelineMetricsSinkTest.java |  6 +--
 .../src/main/python/core/config_reader.py       |  9 ++--
 .../src/test/python/core/TestEmitter.py         |  2 +-
 .../1.6.1.2.2.0/package/scripts/params.py       |  2 +-
 .../0.1.0/package/scripts/params.py             |  2 +-
 .../0.1.0/package/scripts/service_check.py      |  2 +-
 .../FLUME/1.4.0.2.0/package/scripts/params.py   |  2 +-
 .../0.96.0.2.0/package/scripts/params_linux.py  |  2 +-
 .../package/alerts/alert_metrics_deviation.py   |  2 +-
 .../KAFKA/0.8.1/package/scripts/params.py       |  2 +-
 .../STORM/0.9.1/package/scripts/params_linux.py |  2 +-
 .../2.0.6/hooks/before-START/scripts/params.py  |  2 +-
 .../2.1/hooks/before-START/scripts/params.py    |  4 +-
 17 files changed, 51 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-common/src/main/python/ambari_commons/ambari_metrics_helper.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_commons/ambari_metrics_helper.py b/ambari-common/src/main/python/ambari_commons/ambari_metrics_helper.py
index 2eb0b6d..f6f4068 100644
--- a/ambari-common/src/main/python/ambari_commons/ambari_metrics_helper.py
+++ b/ambari-common/src/main/python/ambari_commons/ambari_metrics_helper.py
@@ -22,38 +22,41 @@ import os
 import random
 from resource_management.libraries.functions import conf_select
 
-DEFAULT_COLLECTOR_SUFFIX = '.sink.timeline.collector'
+DEFAULT_COLLECTOR_SUFFIX = '.sink.timeline.collector.hosts'
 DEFAULT_METRICS2_PROPERTIES_FILE_NAME = 'hadoop-metrics2.properties'
 
 def select_metric_collector_for_sink(sink_name):
-    # TODO check '*' sink_name
+  # TODO check '*' sink_name
 
-    all_collectors_string = get_metric_collectors_from_properties_file(sink_name)
+  all_collectors_string = get_metric_collectors_from_properties_file(sink_name)
+  if all_collectors_string:
     all_collectors_list = all_collectors_string.split(',')
     return select_metric_collector_hosts_from_hostnames(all_collectors_list)
+  else:
+    return 'localhost'
 
 def select_metric_collector_hosts_from_hostnames(hosts):
-    return get_random_host(hosts)
+  return get_random_host(hosts)
 
 def get_random_host(hosts):
-    return random.choice(hosts)
+  return random.choice(hosts)
 
 def get_metric_collectors_from_properties_file(sink_name):
-    hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
-    props = load_properties_from_file(os.path.join(hadoop_conf_dir, DEFAULT_METRICS2_PROPERTIES_FILE_NAME))
-    return props.get(sink_name + DEFAULT_COLLECTOR_SUFFIX)
+  hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
+  props = load_properties_from_file(os.path.join(hadoop_conf_dir, DEFAULT_METRICS2_PROPERTIES_FILE_NAME))
+  return props.get(sink_name + DEFAULT_COLLECTOR_SUFFIX)
 
 def load_properties_from_file(filepath, sep='=', comment_char='#'):
-    """
-    Read the file passed as parameter as a properties file.
-    """
-    props = {}
-    with open(filepath, "rt") as f:
-        for line in f:
-            l = line.strip()
-            if l and not l.startswith(comment_char):
-                key_value = l.split(sep)
-                key = key_value[0].strip()
-                value = sep.join(key_value[1:]).strip('" \t')
-                props[key] = value
-    return props
+  """
+  Read the file passed as parameter as a properties file.
+  """
+  props = {}
+  with open(filepath, "rt") as f:
+    for line in f:
+        l = line.strip()
+        if l and not l.startswith(comment_char):
+          key_value = l.split(sep)
+          key = key_value[0].strip()
+          value = sep.join(key_value[1:]).strip('" \t')
+          props[key] = value
+  return props

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java b/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java
index 769d0c1..2c0c822 100644
--- a/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java
+++ b/ambari-metrics/ambari-metrics-common/src/main/java/org/apache/hadoop/metrics2/sink/timeline/AbstractTimelineMetricsSink.java
@@ -477,7 +477,7 @@ public abstract class AbstractTimelineMetricsSink {
     return sb.toString();
   }
   /**
-   * Parses input Sting of format "['host1', 'host2']" into Collection of hostnames
+   * Parses input Sting of format "host1,host2" into Collection of hostnames
    */
   public Collection<String> parseHostsStringIntoCollection(String hostsString) {
     Set<String> hosts = new HashSet<>();
@@ -487,10 +487,8 @@ public abstract class AbstractTimelineMetricsSink {
       return hosts;
     }
 
-    String[] untrimmedHosts = hostsString.split(",");
 
-    for (String host : untrimmedHosts) {
-      host = StringUtils.substringBetween(host, "'");
+    for (String host : hostsString.split(",")) {
       if (StringUtils.isEmpty(host))
         continue;
       hosts.add(host.trim());

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/AbstractTimelineMetricSinkTest.java
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/AbstractTimelineMetricSinkTest.java b/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/AbstractTimelineMetricSinkTest.java
index 5e016f8..9b0cdbe 100644
--- a/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/AbstractTimelineMetricSinkTest.java
+++ b/ambari-metrics/ambari-metrics-common/src/test/java/org/apache/hadoop/metrics2/sink/timeline/availability/AbstractTimelineMetricSinkTest.java
@@ -32,21 +32,21 @@ public class AbstractTimelineMetricSinkTest {
     AbstractTimelineMetricsSink sink = new TestTimelineMetricsSink();
     Collection<String> hosts;
 
-    hosts = sink.parseHostsStringIntoCollection("[]");
+    hosts = sink.parseHostsStringIntoCollection("");
     Assert.assertTrue(hosts.isEmpty());
 
-    hosts = sink.parseHostsStringIntoCollection("[u'test1.123.abc.def.local']");
+    hosts = sink.parseHostsStringIntoCollection("test1.123.abc.def.local");
     Assert.assertTrue(hosts.size() == 1);
     Assert.assertTrue(hosts.contains("test1.123.abc.def.local"));
 
-    hosts = sink.parseHostsStringIntoCollection("['test1.123.abc.def.local']");
+    hosts = sink.parseHostsStringIntoCollection("test1.123.abc.def.local ");
     Assert.assertTrue(hosts.size() == 1);
     Assert.assertTrue(hosts.contains("test1.123.abc.def.local"));
 
-    hosts = sink.parseHostsStringIntoCollection("[u'test1.123.abc.def.local', u'test1.456.abc.def.local']");
+    hosts = sink.parseHostsStringIntoCollection("test1.123.abc.def.local,test1.456.abc.def.local");
     Assert.assertTrue(hosts.size() == 2);
 
-    hosts = sink.parseHostsStringIntoCollection("['test1.123.abc.def.local', 'test1.456.abc.def.local']");
+    hosts = sink.parseHostsStringIntoCollection("test1.123.abc.def.local, test1.456.abc.def.local");
     Assert.assertTrue(hosts.size() == 2);
     Assert.assertTrue(hosts.contains("test1.123.abc.def.local"));
     Assert.assertTrue(hosts.contains("test1.456.abc.def.local"));

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-hadoop-sink/src/main/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSink.java
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-hadoop-sink/src/main/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSink.java b/ambari-metrics/ambari-metrics-hadoop-sink/src/main/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSink.java
index 2bfc6db..7c85171 100644
--- a/ambari-metrics/ambari-metrics-hadoop-sink/src/main/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSink.java
+++ b/ambari-metrics/ambari-metrics-hadoop-sink/src/main/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSink.java
@@ -194,13 +194,13 @@ public class HadoopTimelineMetricsSink extends AbstractTimelineMetricsSink imple
   }
 
   /**
-   * Parses input Stings array of format "['host1'", '"host2']" into Collection of hostnames
+   * Parses input Stings array of format "host1,host2" into Collection of hostnames
    */
   protected Collection<String> parseHostsStringArrayIntoCollection(String[] hostStrings) {
     Collection<String> result = new HashSet<>();
     if (hostStrings == null) return result;
     for (String s : hostStrings) {
-      result.addAll(parseHostsStringIntoCollection(s));
+      result.add(s.trim());
     }
     return result;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-hadoop-sink/src/test/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSinkTest.java
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-hadoop-sink/src/test/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSinkTest.java b/ambari-metrics/ambari-metrics-hadoop-sink/src/test/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSinkTest.java
index 3259c18..5777639 100644
--- a/ambari-metrics/ambari-metrics-hadoop-sink/src/test/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSinkTest.java
+++ b/ambari-metrics/ambari-metrics-hadoop-sink/src/test/java/org/apache/hadoop/metrics2/sink/timeline/HadoopTimelineMetricsSinkTest.java
@@ -99,7 +99,7 @@ public class HadoopTimelineMetricsSinkTest {
     expect(conf.getString("slave.host.name")).andReturn("localhost").anyTimes();
     expect(conf.getParent()).andReturn(null).anyTimes();
     expect(conf.getPrefix()).andReturn("service").anyTimes();
-    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"['localhost", "'localhost2']"}).anyTimes();
+    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"localhost"," localhost2"}).anyTimes();
     expect(conf.getString(eq("serviceName-prefix"), eq(""))).andReturn("").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PROTOCOL), eq("http"))).andReturn("http").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PORT), eq("6188"))).andReturn("6188").anyTimes();
@@ -171,7 +171,7 @@ public class HadoopTimelineMetricsSinkTest {
     expect(conf.getString("slave.host.name")).andReturn("localhost").anyTimes();
     expect(conf.getParent()).andReturn(null).anyTimes();
     expect(conf.getPrefix()).andReturn("service").anyTimes();
-    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"['localhost", "'localhost2']"}).anyTimes();
+    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"localhost", "localhost2"}).anyTimes();
     expect(conf.getString(eq("serviceName-prefix"), eq(""))).andReturn("").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PROTOCOL), eq("http"))).andReturn("http").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PORT), eq("6188"))).andReturn("6188").anyTimes();
@@ -301,7 +301,7 @@ public class HadoopTimelineMetricsSinkTest {
     expect(conf.getString("slave.host.name")).andReturn("localhost").anyTimes();
     expect(conf.getParent()).andReturn(null).anyTimes();
     expect(conf.getPrefix()).andReturn("service").anyTimes();
-    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"['localhost", "'localhost2']"}).anyTimes();
+    expect(conf.getStringArray(eq(COLLECTOR_HOSTS_PROPERTY))).andReturn(new String[]{"localhost", "localhost2"}).anyTimes();
     expect(conf.getString(eq("serviceName-prefix"), eq(""))).andReturn("").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PROTOCOL), eq("http"))).andReturn("http").anyTimes();
     expect(conf.getString(eq(COLLECTOR_PORT), eq("6188"))).andReturn("6188").anyTimes();

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/config_reader.py
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/config_reader.py b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/config_reader.py
index 890d3ce..b84979a 100644
--- a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/config_reader.py
+++ b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/core/config_reader.py
@@ -102,7 +102,7 @@ config_content = """
 [default]
 debug_level = INFO
 hostname = localhost
-metrics_servers = ['localhost','host1','host2']
+metrics_servers = localhost
 enable_time_threshold = false
 enable_value_threshold = false
 
@@ -217,10 +217,7 @@ class Configuration:
 
   def get_metrics_collector_hosts(self):
     hosts = self.get("default", "metrics_servers", "localhost")
-    if hosts is not "localhost":
-      return ast.literal_eval(hosts)
-    else:
-      return hosts
+    return hosts.split(",")
 
   def get_failover_strategy(self):
     return self.get("collector", "failover_strategy", ROUND_ROBIN_FAILOVER_STRATEGY)
@@ -256,4 +253,4 @@ class Configuration:
     return self._ca_cert_file_path
 
   def get_disk_metrics_skip_pattern(self):
-    return self.get("default", "skip_disk_patterns")
\ No newline at end of file
+    return self.get("default", "skip_disk_patterns")

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestEmitter.py
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestEmitter.py b/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestEmitter.py
index de97292..4056ae3 100644
--- a/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestEmitter.py
+++ b/ambari-metrics/ambari-metrics-host-monitoring/src/test/python/core/TestEmitter.py
@@ -83,7 +83,7 @@ class TestEmitter(TestCase):
     emitter.RETRY_SLEEP_INTERVAL = .001
     emitter.submit_metrics()
 
-    self.assertEqual(request_mock.call_count, 9)
+    self.assertEqual(request_mock.call_count, 3)
     self.assertUrlData(request_mock)
 
   def assertUrlData(self, request_mock):

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/package/scripts/params.py
index e00c1f5..53cf002 100644
--- a/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/package/scripts/params.py
@@ -122,7 +122,7 @@ info_num_logs = config['configurations']['accumulo-log4j']['info_num_logs']
 # metrics2 properties
 ganglia_server_hosts = default('/clusterHostInfo/ganglia_server_host', []) # is not passed when ganglia is not present
 ganglia_server_host = '' if len(ganglia_server_hosts) == 0 else ganglia_server_hosts[0]
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 if has_metric_collector:
   if 'cluster-env' in config['configurations'] and \

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
index acc3763..4bda033 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
@@ -58,7 +58,7 @@ ams_pid_dir = status_params.ams_collector_pid_dir
 
 ams_collector_script = "/usr/sbin/ambari-metrics-collector"
 ams_collector_pid_dir = status_params.ams_collector_pid_dir
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 failover_strategy_blacklisted_interval_seconds = default("/configurations/ams-env/failover_strategy_blacklisted_interval", "600")
 failover_strategy = default("/configurations/ams-site/failover.strategy", "round-robin")
 if default("/configurations/ams-site/timeline.metrics.service.http.policy", "HTTP_ONLY") == "HTTPS_ONLY":

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/service_check.py
index 56ca4a1..b4e9b8f 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/service_check.py
@@ -146,7 +146,7 @@ class AMSServiceCheck(Script):
 
     results = execute_in_parallel(self.service_check_for_single_host, params.ams_collector_hosts, params)
 
-    for host in params.ams_collector_hosts:
+    for host in str(params.ams_collector_hosts).split(","):
       if host in results:
         if results[host].status == SUCCESS:
           Logger.info("Ambari Metrics service check passed on host " + host)

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/FLUME/1.4.0.2.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/FLUME/1.4.0.2.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/FLUME/1.4.0.2.0/package/scripts/params.py
index 008e9d6..a44b461 100644
--- a/ambari-server/src/main/resources/common-services/FLUME/1.4.0.2.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/FLUME/1.4.0.2.0/package/scripts/params.py
@@ -85,7 +85,7 @@ hostname = None
 if config.has_key('hostname'):
   hostname = config['hostname']
 
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 metric_collector_port = None
 if has_metric_collector:

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py
index 1f32c41..f47dc8f 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py
@@ -151,7 +151,7 @@ has_ganglia_server = not len(ganglia_server_hosts) == 0
 if has_ganglia_server:
   ganglia_server_host = ganglia_server_hosts[0]
 
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 if has_metric_collector:
   if 'cluster-env' in config['configurations'] and \

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/alerts/alert_metrics_deviation.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/alerts/alert_metrics_deviation.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/alerts/alert_metrics_deviation.py
index 4efdae5..8a06f56 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/alerts/alert_metrics_deviation.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/alerts/alert_metrics_deviation.py
@@ -178,7 +178,7 @@ def execute(configurations={}, parameters={}, host_name=None):
     else:
       collector_webapp_address = configurations[METRICS_COLLECTOR_WEBAPP_ADDRESS_KEY].split(":")
       if valid_collector_webapp_address(collector_webapp_address):
-        collector_host = select_metric_collector_for_sink(app_id.lower()).split(":")[0]
+        collector_host = select_metric_collector_for_sink(app_id.lower())
         collector_port = int(collector_webapp_address[1])
       else:
         return (RESULT_STATE_UNKNOWN, ['{0} value should be set as "fqdn_hostname:port", but set to {1}'.format(

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/params.py b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/params.py
index 0cb88fe..5635fe3 100644
--- a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1/package/scripts/params.py
@@ -120,7 +120,7 @@ metric_truststore_path= default("/configurations/ams-ssl-client/ssl.client.trust
 metric_truststore_type= default("/configurations/ams-ssl-client/ssl.client.truststore.type", "")
 metric_truststore_password= default("/configurations/ams-ssl-client/ssl.client.truststore.password", "")
 
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 
 if has_metric_collector:

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/common-services/STORM/0.9.1/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/STORM/0.9.1/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/STORM/0.9.1/package/scripts/params_linux.py
index e753e98..aca0681 100644
--- a/ambari-server/src/main/resources/common-services/STORM/0.9.1/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/STORM/0.9.1/package/scripts/params_linux.py
@@ -170,7 +170,7 @@ if stack_supports_storm_kerberos:
   else:
     storm_thrift_transport = config['configurations']['storm-site']['_storm.thrift.nonsecure.transport']
 
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 metric_collector_port = None
 if has_metric_collector:

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
index 4603c8b..4a5ee25 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
@@ -90,7 +90,7 @@ jtnode_host = default("/clusterHostInfo/jtnode_host", [])
 namenode_host = default("/clusterHostInfo/namenode_host", [])
 zk_hosts = default("/clusterHostInfo/zookeeper_hosts", [])
 ganglia_server_hosts = default("/clusterHostInfo/ganglia_server_host", [])
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 
 has_namenode = not len(namenode_host) == 0
 has_resourcemanager = not len(rm_host) == 0

http://git-wip-us.apache.org/repos/asf/ambari/blob/406b245e/ambari-server/src/main/resources/stacks/HDPWIN/2.1/hooks/before-START/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDPWIN/2.1/hooks/before-START/scripts/params.py b/ambari-server/src/main/resources/stacks/HDPWIN/2.1/hooks/before-START/scripts/params.py
index 7cd9340..a22eb90 100644
--- a/ambari-server/src/main/resources/stacks/HDPWIN/2.1/hooks/before-START/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/HDPWIN/2.1/hooks/before-START/scripts/params.py
@@ -22,14 +22,14 @@ import nturl2path
 from ambari_commons.ambari_metrics_helper import select_metric_collector_hosts_from_hostnames
 
 config = Script.get_config()
-ams_collector_hosts = default("/clusterHostInfo/metrics_collector_hosts", [])
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
 has_metric_collector = not len(ams_collector_hosts) == 0
 if has_metric_collector:
   if 'cluster-env' in config['configurations'] and \
       'metrics_collector_vip_host' in config['configurations']['cluster-env']:
     metric_collector_host = config['configurations']['cluster-env']['metrics_collector_vip_host']
   else:
-    metric_collector_host = select_metric_collector_hosts_from_hostnames(ams_collector_hosts)
+    metric_collector_host = select_metric_collector_hosts_from_hostnames(ams_collector_hosts.split(","))
   if 'cluster-env' in config['configurations'] and \
       'metrics_collector_vip_port' in config['configurations']['cluster-env']:
     metric_collector_port = config['configurations']['cluster-env']['metrics_collector_vip_port']


[05/24] ambari git commit: AMBARI-19054 : Grafana failed to start at deployment (avijayan)

Posted by jo...@apache.org.
AMBARI-19054 : Grafana failed to start at deployment (avijayan)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7577ebb2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7577ebb2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7577ebb2

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 7577ebb264ae71f81e6572510500f1b87ac46a18
Parents: 406b245
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Thu Dec 1 13:27:16 2016 -0800
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Thu Dec 1 13:27:16 2016 -0800

----------------------------------------------------------------------
 .../ambari-metrics-grafana/conf/unix/ambari-metrics-grafana    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7577ebb2/ambari-metrics/ambari-metrics-grafana/conf/unix/ambari-metrics-grafana
----------------------------------------------------------------------
diff --git a/ambari-metrics/ambari-metrics-grafana/conf/unix/ambari-metrics-grafana b/ambari-metrics/ambari-metrics-grafana/conf/unix/ambari-metrics-grafana
index 472942e..8a8ac8f 100644
--- a/ambari-metrics/ambari-metrics-grafana/conf/unix/ambari-metrics-grafana
+++ b/ambari-metrics/ambari-metrics-grafana/conf/unix/ambari-metrics-grafana
@@ -104,7 +104,7 @@ case "$1" in
 
     # Prepare environment
     # mkdir -p "$LOG_DIR" "$DATA_DIR" && chown "$GRAFANA_USER":"$GRAFANA_GROUP" "$LOG_DIR" "$DATA_DIR"
-    # touch "$PID_FILE" && chown "$GRAFANA_USER":"$GRAFANA_GROUP" "$PID_FILE"
+    touch "$PID_FILE" && chown "$GRAFANA_USER":"$GRAFANA_GROUP" "$PID_FILE"
 
     # if [ -n "$MAX_OPEN_FILES" ]; then
     #   ulimit -n $MAX_OPEN_FILES
@@ -116,10 +116,10 @@ case "$1" in
     return=$?
     if [ $return -eq 0 ]
     then
-      sleep 1
+      sleep 5
       # check if pid file has been written two
       if ! [[ -s $PID_FILE ]]; then
-        echo "Start FAILED" >> $LOG_FILE
+        echo "Start FAILED because daemon did not write pid in pid_file" >> $LOG_FILE
         exit 1
       fi
       i=0


[03/24] ambari git commit: AMBARI-19052. Re-arrange "Role Based Access Control" info table (akovalenko)

Posted by jo...@apache.org.
AMBARI-19052. Re-arrange "Role Based Access Control" info table (akovalenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/63c0f2e5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/63c0f2e5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/63c0f2e5

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 63c0f2e58fc09b709e890923752c4ccb04181180
Parents: 63938e0
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Thu Dec 1 19:22:02 2016 +0200
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Thu Dec 1 20:20:33 2016 +0200

----------------------------------------------------------------------
 .../admin-web/app/scripts/services/Cluster.js   | 51 --------------------
 .../app/scripts/services/RoleDetailsModal.js    | 31 +++++++-----
 .../app/views/modals/RoleDetailsModal.html      |  6 +--
 3 files changed, 23 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/63c0f2e5/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
index 02c231a..0f9b582 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js
@@ -30,57 +30,6 @@ angular.module('ambariAdminConsole')
       'CLUSTER.USER'
     ],
 
-    orderedAuthorizations : [
-      "SERVICE.VIEW_METRICS",
-      "SERVICE.VIEW_STATUS_INFO",
-      "SERVICE.VIEW_CONFIGS",
-      "SERVICE.COMPARE_CONFIGS",
-      "SERVICE.VIEW_ALERTS",
-      "SERVICE.START_STOP",
-      "SERVICE.DECOMMISSION_RECOMMISSION",
-      "SERVICE.RUN_SERVICE_CHECK",
-      "SERVICE.TOGGLE_MAINTENANCE",
-      "SERVICE.RUN_CUSTOM_COMMAND",
-      "SERVICE.MODIFY_CONFIGS",
-      "SERVICE.MANAGE_CONFIG_GROUPS",
-      "SERVICE.MOVE",
-      "SERVICE.ENABLE_HA",
-      "SERVICE.MANAGE_ALERTS",
-      "SERVICE.TOGGLE_ALERTS",
-      "SERVICE.ADD_DELETE_SERVICES",
-      "SERVICE.VIEW_OPERATIONAL_LOGS",
-      "HOST.VIEW_CONFIGS",
-      "HOST.VIEW_METRICS",
-      "HOST.VIEW_STATUS_INFO",
-      "HOST.ADD_DELETE_COMPONENTS",
-      "HOST.ADD_DELETE_HOSTS",
-      "HOST.TOGGLE_MAINTENANCE",
-      "CLUSTER.VIEW_ALERTS",
-      "CLUSTER.VIEW_CONFIGS",
-      "CLUSTER.VIEW_METRICS",
-      "CLUSTER.VIEW_STACK_DETAILS",
-      "CLUSTER.VIEW_STATUS_INFO",
-      "CLUSTER.MANAGE_ALERTS",
-      "CLUSTER.MANAGE_CONFIG_GROUPS",
-      "CLUSTER.MANAGE_CREDENTIALS",
-      "CLUSTER.MODIFY_CONFIGS",
-      "CLUSTER.TOGGLE_ALERTS",
-      "CLUSTER.TOGGLE_KERBEROS",
-      "CLUSTER.UPGRADE_DOWNGRADE_STACK",
-      "CLUSTER.RUN_CUSTOM_COMMAND",
-      "AMBARI.ADD_DELETE_CLUSTERS",
-      "AMBARI.ASSIGN_ROLES",
-      "AMBARI.EDIT_STACK_REPOS",
-      "AMBARI.MANAGE_GROUPS",
-      "AMBARI.MANAGE_SETTINGS",
-      "AMBARI.MANAGE_STACK_VERSIONS",
-      "AMBARI.MANAGE_USERS",
-      "AMBARI.MANAGE_VIEWS",
-      "AMBARI.RENAME_CLUSTER",
-      "AMBARI.RUN_CUSTOM_COMMAND",
-      "SERVICE.SET_SERVICE_USERS_GROUPS"
-    ],
-
     orderedLevels: ['SERVICE', 'HOST', 'CLUSTER', 'AMBARI'],
 
     ineditableRoles : ['VIEW.USER', 'AMBARI.ADMINISTRATOR'],

http://git-wip-us.apache.org/repos/asf/ambari/blob/63c0f2e5/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js
index 5a14b33..06019c2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js
@@ -33,9 +33,9 @@ angular.module('ambariAdminConsole')
         templateUrl: 'views/modals/RoleDetailsModal.html',
         size: 'lg',
         controller: function($scope, $modalInstance) {
+          var authorizationsOrder;
           $scope.title = '';
           $scope.orderedRoles = ['AMBARI.ADMINISTRATOR'].concat(Cluster.orderedRoles).reverse();
-          $scope.orderedAuthorizations = Cluster.orderedAuthorizations;
           $scope.orderedLevels = Cluster.orderedLevels;
           $scope.authHash = {};
           $scope.getLevelName = function (key) {
@@ -44,25 +44,34 @@ angular.module('ambariAdminConsole')
           angular.forEach(roles, function (r) {
             angular.forEach(r.authorizations, function (auth) {
               var match = auth.authorization_id.match(/(\w+)\./),
-                levelKey = match && match[1],
-                isLevelDisplayed = $scope.orderedAuthorizations.some(function (item) {
-                  return !item.indexOf(levelKey);
-                });
+                  levelKey = match && match[1],
+                  isLevelDisplayed = $scope.orderedLevels.indexOf(levelKey) !== -1;
               if (isLevelDisplayed) {
                 if (!$scope.authHash[levelKey]) {
                   $scope.authHash[levelKey] = {};
                 }
                 if (!$scope.authHash[levelKey][auth.authorization_id]) {
-                  $scope.authHash[levelKey][auth.authorization_id] = auth.authorization_name;
+                  $scope.authHash[levelKey][auth.authorization_id] = {
+                    name: auth.authorization_name,
+                    roles: {}
+                  };
                 }
-                if (!r.authHash) {
-                  r.authHash = {};
-                }
-                r.authHash[auth.authorization_id] = true;
+                $scope.authHash[levelKey][auth.authorization_id].roles[r.permission_name] = true;
               }
             });
           });
-          $scope.roles = roles.sort(function(a, b) {
+
+          // sort authorizations for each level by number of roles permissions
+          for (var level in $scope.authHash) {
+            if ($scope.authHash.hasOwnProperty(level)) {
+              authorizationsOrder = Object.keys($scope.authHash[level]).sort(function (a, b) {
+                return Object.keys($scope.authHash[level][b].roles).length - Object.keys($scope.authHash[level][a].roles).length;
+              });
+              $scope.authHash[level].order = authorizationsOrder;
+            }
+          }
+
+          $scope.roles = roles.sort(function (a, b) {
             return $scope.orderedRoles.indexOf(a.permission_name) - $scope.orderedRoles.indexOf(b.permission_name);
           });
           $scope.ok = function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/63c0f2e5/ambari-admin/src/main/resources/ui/admin-web/app/views/modals/RoleDetailsModal.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/modals/RoleDetailsModal.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/modals/RoleDetailsModal.html
index 926bea9..942a733 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/modals/RoleDetailsModal.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/modals/RoleDetailsModal.html
@@ -40,10 +40,10 @@
         </div>
       </div>
       <div class="table-row-wrapper">
-        <div class="table-row" ng-repeat="auth in orderedAuthorizations" ng-if="authHash[level][auth]">
-          <div class="table-cell">{{authHash[level][auth]}}</div>
+        <div class="table-row" ng-repeat="auth_id in authHash[level].order">
+          <div class="table-cell">{{authHash[level][auth_id].name}}</div>
           <div class="table-cell text-center" ng-repeat="role in roles">
-            <i class="glyphicon glyphicon-ok green-icon" ng-show="role.authHash[auth]"></i>
+            <i class="glyphicon glyphicon-ok green-icon" ng-show="authHash[level][auth_id].roles[role.permission_name]"></i>
           </div>
         </div>
       </div>


[07/24] ambari git commit: AMBARI-19051. Stage is sometimes marked as failed on command reschedule. (mpapirkovskyy)

Posted by jo...@apache.org.
AMBARI-19051. Stage is sometimes marked as failed on command reschedule. (mpapirkovskyy)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d24beb17
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d24beb17
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d24beb17

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: d24beb17e238391b196a2bfae1217035678a0a14
Parents: 615438b
Author: Myroslav Papirkovskyi <mp...@hortonworks.com>
Authored: Thu Dec 1 18:48:25 2016 +0200
Committer: Myroslav Papirkovskyi <mp...@hortonworks.com>
Committed: Fri Dec 2 09:51:16 2016 +0200

----------------------------------------------------------------------
 .../src/main/python/ambari_agent/ActionQueue.py | 11 +++++
 .../test/python/ambari_agent/TestActionQueue.py | 48 ++++++++++++++++++++
 2 files changed, 59 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d24beb17/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/ActionQueue.py b/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
index 4416b9a..cb4fcb9 100644
--- a/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
+++ b/ambari-agent/src/main/python/ambari_agent/ActionQueue.py
@@ -300,6 +300,7 @@ class ActionQueue(threading.Thread):
 
     logger.info("Command execution metadata - taskId = {taskId}, retry enabled = {retryAble}, max retry duration (sec) = {retryDuration}, log_output = {log_command_output}".
                  format(taskId=taskId, retryAble=retryAble, retryDuration=retryDuration, log_command_output=log_command_output))
+    command_canceled = False
     while retryDuration >= 0:
       numAttempts += 1
       start = 0
@@ -328,6 +329,7 @@ class ActionQueue(threading.Thread):
           status = self.FAILED_STATUS
           if (commandresult['exitcode'] == -signal.SIGTERM) or (commandresult['exitcode'] == -signal.SIGKILL):
             logger.info('Command with taskId = {cid} was canceled!'.format(cid=taskId))
+            command_canceled = True
             break
 
       if status != self.COMPLETED_STATUS and retryAble and retryDuration > 0:
@@ -344,6 +346,15 @@ class ActionQueue(threading.Thread):
                     .format(cid=taskId, status=status, retryAble=retryAble, retryDuration=retryDuration, delay=delay))
         break
 
+    # do not fail task which was rescheduled from server
+    if command_canceled:
+      with self.commandQueue.mutex:
+        for com in self.commandQueue.queue:
+          if com['taskId'] == command['taskId']:
+            logger.info('Command with taskId = {cid} was rescheduled by server. '
+                        'Fail report on cancelled command won\'t be sent with heartbeat.'.format(cid=taskId))
+            return
+
     # final result to stdout
     commandresult['stdout'] += '\n\nCommand completed successfully!\n' if status == self.COMPLETED_STATUS else '\n\nCommand failed after ' + str(numAttempts) + ' tries\n'
     logger.info('Command with taskId = {cid} completed successfully!'.format(cid=taskId) if status == self.COMPLETED_STATUS else 'Command with taskId = {cid} failed after {attempts} tries'.format(cid=taskId, attempts=numAttempts))

http://git-wip-us.apache.org/repos/asf/ambari/blob/d24beb17/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
index 4a63f7c..65127f2 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
@@ -27,6 +27,7 @@ import os, errno, time, pprint, tempfile, threading
 import sys
 from threading import Thread
 import copy
+import signal
 
 from mock.mock import patch, MagicMock, call
 from ambari_agent.CustomServiceOrchestrator import CustomServiceOrchestrator
@@ -690,6 +691,53 @@ class TestActionQueue(TestCase):
     report = actionQueue.result()
     self.assertEqual(len(report['reports']), 0)
 
+  def test_cancel_with_reschedule_command(self):
+    config = AmbariConfig()
+    tempdir = tempfile.gettempdir()
+    config.set('agent', 'prefix', tempdir)
+    config.set('agent', 'cache_dir', "/var/lib/ambari-agent/cache")
+    config.set('agent', 'tolerate_download_failures', "true")
+    dummy_controller = MagicMock()
+    actionQueue = ActionQueue(config, dummy_controller)
+    unfreeze_flag = threading.Event()
+    python_execution_result_dict = {
+      'stdout': 'out',
+      'stderr': 'stderr',
+      'structuredOut' : '',
+      'status' : '',
+      'exitcode' : -signal.SIGTERM
+    }
+
+    def side_effect(command, tmpoutfile, tmperrfile, override_output_files=True, retry=False):
+      unfreeze_flag.wait()
+      return python_execution_result_dict
+    def patched_aq_execute_command(command):
+      # We have to perform patching for separate thread in the same thread
+      with patch.object(CustomServiceOrchestrator, "runCommand") as runCommand_mock:
+        runCommand_mock.side_effect = side_effect
+        actionQueue.execute_command(command)
+
+    # We call method in a separate thread
+    execution_thread = Thread(target = patched_aq_execute_command ,
+                              args = (self.datanode_install_command, ))
+    execution_thread.start()
+    #  check in progress report
+    # wait until ready
+    while True:
+      time.sleep(0.1)
+      report = actionQueue.result()
+      if len(report['reports']) != 0:
+        break
+
+    unfreeze_flag.set()
+    # wait until ready
+    while len(report['reports']) != 0:
+      time.sleep(0.1)
+      report = actionQueue.result()
+
+    # check report
+    self.assertEqual(len(report['reports']), 0)
+
 
   @patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = os_distro_value))
   @patch.object(CustomServiceOrchestrator, "runCommand")


[11/24] ambari git commit: AMBARI-19063. Do not change timeline.metrics.service.webapp.address in move wizard (akovalenko)

Posted by jo...@apache.org.
AMBARI-19063. Do not change timeline.metrics.service.webapp.address in move wizard (akovalenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e242fc09
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e242fc09
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e242fc09

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: e242fc091abe15bc59e8572c43d9227c97e7a247
Parents: 2de7ee8
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Fri Dec 2 15:43:15 2016 +0200
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Fri Dec 2 15:44:42 2016 +0200

----------------------------------------------------------------------
 .../main/service/reassign/step4_controller.js    | 19 ++++++++++---------
 .../service/reassign/step4_controller_test.js    |  2 +-
 2 files changed, 11 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e242fc09/ambari-web/app/controllers/main/service/reassign/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step4_controller.js b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
index 26ac68c..64c2a8e 100644
--- a/ambari-web/app/controllers/main/service/reassign/step4_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
@@ -71,6 +71,12 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
   hostComponents: [],
 
   /**
+   * List of components, that do not need reconfiguration for moving to another host
+   * Reconfigure command will be skipped
+   */
+  componentsWithoutReconfiguration: ['METRICS_COLLECTOR'],
+
+  /**
    * Map with lists of related services.
    * Used to define list of services to stop/start.
    */
@@ -189,14 +195,6 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
       }
     },
     {
-      componentName: 'METRICS_COLLECTOR',
-      configs: {
-        'ams-site': {
-          'timeline.metrics.service.webapp.address': '<replace-value>:6188'
-        }
-      }
-    },
-    {
       componentName: 'HISTORYSERVER',
       configs: {
         'mapred-site': {
@@ -398,6 +396,10 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
       this.removeTasks(['startZooKeeperServers', 'startNameNode']);
     }
 
+    if (this.get('componentsWithoutReconfiguration').contains(componentName)) {
+      this.removeTasks(['reconfigure']);
+    }
+
     if (!this.get('content.reassignComponentsInMM.length')) {
       this.removeTasks(['stopHostComponentsInMaintenanceMode']);
     }
@@ -542,7 +544,6 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     'HIVE_SERVER': ['hive-site', 'webhcat-site', 'hive-env', 'core-site'],
     'HIVE_METASTORE': ['hive-site', 'webhcat-site', 'hive-env', 'core-site'],
     'MYSQL_SERVER': ['hive-site'],
-    'METRICS_COLLECTOR': ['ams-site'],
     'HISTORYSERVER': ['mapred-site']
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e242fc09/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
index 5e7b0e3..9a73524 100644
--- a/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
@@ -295,7 +295,7 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
 
       controller.set('tasks', commandsForDB);
       controller.removeUnneededTasks();
-      expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,5,6,8,9,10,12]);
+      expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,5,6,8,10,12]);
     });
 
     it('reassign component is Mysql Server', function () {


[08/24] ambari git commit: AMBARI-18956. Ambari attempts to commit transactions marked as rollback-only (magyari_sandor)

Posted by jo...@apache.org.
AMBARI-18956. Ambari attempts to commit transactions marked as rollback-only (magyari_sandor)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/73d372b8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/73d372b8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/73d372b8

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 73d372b8db6b4809fac98338aef1c04ae4c95c92
Parents: d24beb1
Author: Sandor Magyari <sm...@hortonworks.com>
Authored: Fri Dec 2 09:43:24 2016 +0100
Committer: Sandor Magyari <sm...@hortonworks.com>
Committed: Fri Dec 2 09:43:24 2016 +0100

----------------------------------------------------------------------
 .../orm/AmbariJpaLocalTxnInterceptor.java       |   9 +-
 .../orm/AmbariJpaLocalTxnInterceptorTest.java   | 155 +++++++++++++++++++
 2 files changed, 162 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/73d372b8/ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptor.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptor.java
index d7ba463..e19192a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptor.java
@@ -218,12 +218,17 @@ public class AmbariJpaLocalTxnInterceptor implements MethodInterceptor {
   /**
    * Returns True if rollback DID NOT HAPPEN (i.e. if commit should continue).
    *
-   * @param transactional The metadata annotaiton of the method
+   * @param transactional The metadata annotation of the method
    * @param e             The exception to test for rollback
    * @param txn           A JPA Transaction to issue rollbacks on
    */
-  private boolean rollbackIfNecessary(Transactional transactional, Exception e,
+  static boolean rollbackIfNecessary(Transactional transactional, Exception e,
                                       EntityTransaction txn) {
+    if (txn.getRollbackOnly()) {
+      txn.rollback();
+      return false;
+    }
+
     boolean commit = true;
 
     //check rollback clauses

http://git-wip-us.apache.org/repos/asf/ambari/blob/73d372b8/ambari-server/src/test/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptorTest.java
new file mode 100644
index 0000000..ea7ea53
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/AmbariJpaLocalTxnInterceptorTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.orm;
+
+import com.google.inject.persist.Transactional;
+import org.easymock.EasyMockSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.persistence.EntityTransaction;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import static org.apache.ambari.server.orm.AmbariJpaLocalTxnInterceptor.rollbackIfNecessary;
+import static org.easymock.EasyMock.expect;
+
+public class AmbariJpaLocalTxnInterceptorTest extends EasyMockSupport {
+
+  @Test
+  public void canBeCommittedIfExceptionsToBeRolledBackOnIsEmpty() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[0]);
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new RuntimeException(), transaction);
+    Assert.assertTrue("Should be allowed to commit, since rollbackOn clause is empty", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void canBeCommittedIfUnknownExceptionThrown() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[] { IllegalArgumentException.class });
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new RuntimeException(), transaction);
+    Assert.assertTrue("Should be allowed to commit, exception thrown does not match rollbackOn clause", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void rolledBackForKnownException() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[] {
+      NullPointerException.class, IllegalArgumentException.class
+    });
+    expect(transactional.ignore()).andReturn(new Class[0]);
+    transaction.rollback();
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new IllegalArgumentException("rolling back"), transaction);
+    Assert.assertFalse("Should be rolled back, since exception matches rollbackOn clause", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void rolledBackForSubclassOfKnownException() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[] { RuntimeException.class });
+    expect(transactional.ignore()).andReturn(new Class[0]);
+    transaction.rollback();
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new IllegalArgumentException("rolling back"), transaction);
+    Assert.assertFalse("Should be rolled back, since exception is subclass of the one in rollbackOn clause", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void canBeCommittedIfIgnoredExceptionThrown() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[] { IllegalArgumentException.class });
+    expect(transactional.ignore()).andReturn(new Class[] { NumberFormatException.class });
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new NumberFormatException("rolling back"), transaction);
+    Assert.assertTrue("Should be allowed to commit, since ignored exception was thrown", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void canBeCommittedIfSubclassOfIgnoredExceptionThrown() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(false);
+    expect(transactional.rollbackOn()).andReturn(new Class[] { Exception.class });
+    expect(transactional.ignore()).andReturn(new Class[] { IOException.class });
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, new FileNotFoundException("rolling back"), transaction);
+    Assert.assertTrue("Should be allowed to commit, since subclass of ignored exception was thrown", canCommit);
+
+    verifyAll();
+  }
+
+  @Test
+  public void rolledBackIfTransactionMarkedRollbackOnly() {
+    Transactional transactional = createNiceMock(Transactional.class);
+    EntityTransaction transaction = createStrictMock(EntityTransaction.class);
+
+    expect(transaction.getRollbackOnly()).andReturn(true);
+    transaction.rollback();
+
+    replayAll();
+
+    boolean canCommit = rollbackIfNecessary(transactional, null, transaction);
+    Assert.assertFalse("Should be rolled back, since transaction was marked rollback-only", canCommit);
+
+    verifyAll();
+  }
+
+}


[12/24] ambari git commit: AMBARI-18951. Force InnoDB usage for MySQL. Fix for MySQL < 5.6. (mpapirkovskyy)

Posted by jo...@apache.org.
AMBARI-18951. Force InnoDB usage for MySQL. Fix for MySQL < 5.6. (mpapirkovskyy)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/80084a9d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/80084a9d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/80084a9d

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 80084a9d8de9110365c6f1ef68362b502e07cf28
Parents: e242fc0
Author: Myroslav Papirkovskyi <mp...@hortonworks.com>
Authored: Fri Dec 2 16:41:40 2016 +0200
Committer: Myroslav Papirkovskyi <mp...@hortonworks.com>
Committed: Fri Dec 2 16:52:55 2016 +0200

----------------------------------------------------------------------
 .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql       | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/80084a9d/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index b01ed2f..82ce31e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -26,7 +26,16 @@ delimiter ;
 
 # USE @schema;
 
-SET default_storage_engine=INNODB;
+-- Set default_storage_engine to InnoDB
+-- storage_engine variable should be used for versions prior to MySQL 5.6
+set @version_short = substring_index(@@version, '.', 2);
+set @major = cast(substring_index(@version_short, '.', 1) as SIGNED);
+set @minor = cast(substring_index(@version_short, '.', -1) as SIGNED);
+set @engine_stmt = IF(@major >= 5 AND @minor>=6, 'SET default_storage_engine=INNODB', 'SET storage_engine=INNODB');
+prepare statement from @engine_stmt;
+execute statement;
+DEALLOCATE PREPARE statement;
+
 
 CREATE TABLE stack(
   stack_id BIGINT NOT NULL,


[23/24] ambari git commit: AMBARI-18936. DataNode JVM heap settings should include CMSInitiatingOccupancy (Arpit Agarwal via smohanty)

Posted by jo...@apache.org.
AMBARI-18936. DataNode JVM heap settings should include CMSInitiatingOccupancy (Arpit Agarwal via smohanty)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0c837a60
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0c837a60
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0c837a60

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 0c837a60c6bbe7c6fb7c5586963520957bb4146f
Parents: 05fe423
Author: Sumit Mohanty <sm...@hortonworks.com>
Authored: Fri Dec 2 13:13:35 2016 -0800
Committer: Sumit Mohanty <sm...@hortonworks.com>
Committed: Fri Dec 2 13:13:35 2016 -0800

----------------------------------------------------------------------
 .../services/HDFS/configuration/hadoop-env.xml  | 176 +++++++++++++++++++
 1 file changed, 176 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0c837a60/ambari-server/src/main/resources/stacks/HDP/2.4/services/HDFS/configuration/hadoop-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/services/HDFS/configuration/hadoop-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/services/HDFS/configuration/hadoop-env.xml
new file mode 100644
index 0000000..24e0193
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/services/HDFS/configuration/hadoop-env.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<configuration supports_adding_forbidden="true">
+  <!-- hadoop-env.sh -->
+  <property>
+    <name>content</name>
+    <display-name>hadoop-env template</display-name>
+    <description>This is the jinja template for hadoop-env.sh file</description>
+    <value>
+# Set Hadoop-specific environment variables here.
+
+# The only required environment variable is JAVA_HOME.  All others are
+# optional.  When running a distributed configuration it is best to
+# set JAVA_HOME in this file, so that it is correctly defined on
+# remote nodes.
+
+# The java implementation to use.  Required.
+export JAVA_HOME={{java_home}}
+export HADOOP_HOME_WARN_SUPPRESS=1
+
+# Hadoop home directory
+export HADOOP_HOME=${HADOOP_HOME:-{{hadoop_home}}}
+
+# Hadoop Configuration Directory
+
+{# this is different for HDP1 #}
+# Path to jsvc required by secure HDP 2.0 datanode
+export JSVC_HOME={{jsvc_path}}
+
+
+# The maximum amount of heap to use, in MB. Default is 1000.
+export HADOOP_HEAPSIZE="{{hadoop_heapsize}}"
+
+export HADOOP_NAMENODE_INIT_HEAPSIZE="-Xms{{namenode_heapsize}}"
+
+# Extra Java runtime options.  Empty by default.
+export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true ${HADOOP_OPTS}"
+
+# Command specific options appended to HADOOP_OPTS when specified
+HADOOP_JOBTRACKER_OPTS="-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{jtnode_opt_newsize}} -XX:MaxNewSize={{jtnode_opt_maxnewsize}} -Xloggc:{{hdfs_log_dir_prefix}}/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xmx{{jtnode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dmapred.audit.logger=INFO,MRAUDIT -Dhadoop.mapreduce.jobsummary.logger=INFO,JSA ${HADOOP_JOBTRACKER_OPTS}"
+
+HADOOP_TASKTRACKER_OPTS="-server -Xmx{{ttnode_heapsize}} -Dhadoop.security.logger=ERROR,console -Dmapred.audit.logger=ERROR,console ${HADOOP_TASKTRACKER_OPTS}"
+
+{% if java_version &lt; 8 %}
+SHARED_HADOOP_NAMENODE_OPTS="-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{namenode_opt_newsize}} -XX:MaxNewSize={{namenode_opt_maxnewsize}} -XX:PermSize={{namenode_opt_permsize}} -XX:MaxPermSize={{namenode_opt_maxpermsize}} -Xloggc:{{hdfs_log_dir_prefix}}/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -Xms{{namenode_heapsize}} -Xmx{{namenode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT"
+export HADOOP_NAMENODE_OPTS="${SHARED_HADOOP_NAMENODE_OPTS} -XX:OnOutOfMemoryError=\"/usr/hdp/current/hadoop-hdfs-namenode/bin/kill-name-node\" -Dorg.mortbay.jetty.Request.maxFormContentSize=-1 ${HADOOP_NAMENODE_OPTS}"
+export HADOOP_DATANODE_OPTS="-server -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:NewSize=200m -XX:MaxNewSize=200m -XX:PermSize=128m -XX:MaxPermSize=256m -Xloggc:/var/log/hadoop/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xms{{dtnode_heapsize}} -Xmx{{dtnode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT ${HADOOP_DATANODE_OPTS} -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
+
+export HADOOP_SECONDARYNAMENODE_OPTS="${SHARED_HADOOP_NAMENODE_OPTS} -XX:OnOutOfMemoryError=\"/usr/hdp/current/hadoop-hdfs-secondarynamenode/bin/kill-secondary-name-node\" ${HADOOP_SECONDARYNAMENODE_OPTS}"
+
+# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
+export HADOOP_CLIENT_OPTS="-Xmx${HADOOP_HEAPSIZE}m -XX:MaxPermSize=512m $HADOOP_CLIENT_OPTS"
+
+{% else %}
+SHARED_HADOOP_NAMENODE_OPTS="-server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -XX:ErrorFile={{hdfs_log_dir_prefix}}/$USER/hs_err_pid%p.log -XX:NewSize={{namenode_opt_newsize}} -XX:MaxNewSize={{namenode_opt_maxnewsize}} -Xloggc:{{hdfs_log_dir_prefix}}/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -Xms{{namenode_heapsize}} -Xmx{{namenode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT"
+export HADOOP_NAMENODE_OPTS="${SHARED_HADOOP_NAMENODE_OPTS} -XX:OnOutOfMemoryError=\"/usr/hdp/current/hadoop-hdfs-namenode/bin/kill-name-node\" -Dorg.mortbay.jetty.Request.maxFormContentSize=-1 ${HADOOP_NAMENODE_OPTS}"
+export HADOOP_DATANODE_OPTS="-server -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:ErrorFile=/var/log/hadoop/$USER/hs_err_pid%p.log -XX:NewSize=200m -XX:MaxNewSize=200m -Xloggc:/var/log/hadoop/$USER/gc.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xms{{dtnode_heapsize}} -Xmx{{dtnode_heapsize}} -Dhadoop.security.logger=INFO,DRFAS -Dhdfs.audit.logger=INFO,DRFAAUDIT ${HADOOP_DATANODE_OPTS} -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
+
+export HADOOP_SECONDARYNAMENODE_OPTS="${SHARED_HADOOP_NAMENODE_OPTS} -XX:OnOutOfMemoryError=\"/usr/hdp/current/hadoop-hdfs-secondarynamenode/bin/kill-secondary-name-node\" ${HADOOP_SECONDARYNAMENODE_OPTS}"
+
+# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
+export HADOOP_CLIENT_OPTS="-Xmx${HADOOP_HEAPSIZE}m $HADOOP_CLIENT_OPTS"
+{% endif %}
+
+HADOOP_NFS3_OPTS="-Xmx{{nfsgateway_heapsize}}m -Dhadoop.security.logger=ERROR,DRFAS ${HADOOP_NFS3_OPTS}"
+HADOOP_BALANCER_OPTS="-server -Xmx{{hadoop_heapsize}}m ${HADOOP_BALANCER_OPTS}"
+
+
+# On secure datanodes, user to run the datanode as after dropping privileges
+export HADOOP_SECURE_DN_USER=${HADOOP_SECURE_DN_USER:-{{hadoop_secure_dn_user}}}
+
+# Extra ssh options.  Empty by default.
+export HADOOP_SSH_OPTS="-o ConnectTimeout=5 -o SendEnv=HADOOP_CONF_DIR"
+
+# Where log files are stored.  $HADOOP_HOME/logs by default.
+export HADOOP_LOG_DIR={{hdfs_log_dir_prefix}}/$USER
+
+# History server logs
+export HADOOP_MAPRED_LOG_DIR={{mapred_log_dir_prefix}}/$USER
+
+# Where log files are stored in the secure data environment.
+export HADOOP_SECURE_DN_LOG_DIR={{hdfs_log_dir_prefix}}/$HADOOP_SECURE_DN_USER
+
+# File naming remote slave hosts.  $HADOOP_HOME/conf/slaves by default.
+# export HADOOP_SLAVES=${HADOOP_HOME}/conf/slaves
+
+# host:path where hadoop code should be rsync'd from.  Unset by default.
+# export HADOOP_MASTER=master:/home/$USER/src/hadoop
+
+# Seconds to sleep between slave commands.  Unset by default.  This
+# can be useful in large clusters, where, e.g., slave rsyncs can
+# otherwise arrive faster than the master can service them.
+# export HADOOP_SLAVE_SLEEP=0.1
+
+# The directory where pid files are stored. /tmp by default.
+export HADOOP_PID_DIR={{hadoop_pid_dir_prefix}}/$USER
+export HADOOP_SECURE_DN_PID_DIR={{hadoop_pid_dir_prefix}}/$HADOOP_SECURE_DN_USER
+
+# History server pid
+export HADOOP_MAPRED_PID_DIR={{mapred_pid_dir_prefix}}/$USER
+
+YARN_RESOURCEMANAGER_OPTS="-Dyarn.server.resourcemanager.appsummary.logger=INFO,RMSUMMARY"
+
+# A string representing this instance of hadoop. $USER by default.
+export HADOOP_IDENT_STRING=$USER
+
+# The scheduling priority for daemon processes.  See 'man nice'.
+
+# export HADOOP_NICENESS=10
+
+# Add database libraries
+JAVA_JDBC_LIBS=""
+if [ -d "/usr/share/java" ]; then
+  for jarFile in `ls /usr/share/java | grep -E "(mysql|ojdbc|postgresql|sqljdbc)" 2&gt;/dev/null`
+  do
+    JAVA_JDBC_LIBS=${JAVA_JDBC_LIBS}:$jarFile
+  done
+fi
+
+# Add libraries to the hadoop classpath - some may not need a colon as they already include it
+export HADOOP_CLASSPATH=${HADOOP_CLASSPATH}${JAVA_JDBC_LIBS}
+
+# Setting path to hdfs command line
+export HADOOP_LIBEXEC_DIR={{hadoop_libexec_dir}}
+
+# Mostly required for hadoop 2.0
+export JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}
+
+export HADOOP_OPTS="-Dhdp.version=$HDP_VERSION $HADOOP_OPTS"
+
+
+# Fix temporary bug, when ulimit from conf files is not picked up, without full relogin. 
+# Makes sense to fix only when runing DN as root 
+if [ "$command" == "datanode" ] &amp;&amp; [ "$EUID" -eq 0 ] &amp;&amp; [ -n "$HADOOP_SECURE_DN_USER" ]; then
+  {% if is_datanode_max_locked_memory_set %}
+  ulimit -l {{datanode_max_locked_memory}}
+  {% endif %}
+  ulimit -n {{hdfs_user_nofile_limit}}
+fi
+    </value>
+    <value-attributes>
+      <type>content</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>nfsgateway_heapsize</name>
+    <display-name>NFSGateway maximum Java heap size</display-name>
+    <value>1024</value>
+    <description>Maximum Java heap size for NFSGateway (Java option -Xmx)</description>
+    <value-attributes>
+      <type>int</type>
+      <unit>MB</unit>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+</configuration>


[13/24] ambari git commit: AMBARI-18441 - upgrade ambari to 2.1.1 error (Wang Yaoxin via jonathanhurley)

Posted by jo...@apache.org.
AMBARI-18441 - upgrade ambari to 2.1.1 error (Wang Yaoxin via jonathanhurley)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ae3ff2a0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ae3ff2a0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ae3ff2a0

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: ae3ff2a09b6b36f8a456987c60fc695dd262b6bb
Parents: 80084a9
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Dec 2 10:13:22 2016 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Dec 2 10:13:45 2016 -0500

----------------------------------------------------------------------
 .../server/upgrade/UpgradeCatalog211.java       | 24 ++++++++++++--------
 1 file changed, 15 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ae3ff2a0/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog211.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog211.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog211.java
index db13612..eb835ef 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog211.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog211.java
@@ -212,8 +212,8 @@ public class UpgradeCatalog211 extends AbstractUpgradeCatalog {
         statement = dbAccessor.getConnection().createStatement();
         if (statement != null) {
           String selectSQL = MessageFormat.format(
-              "SELECT cluster_id, service_name, component_name, host_id FROM {0}",
-              HOST_COMPONENT_STATE_TABLE);
+              "SELECT id, cluster_id, service_name, component_name, host_id FROM {0} ORDER BY {1} {2}",
+              HOST_COMPONENT_STATE_TABLE, "id", "DESC");
 
           resultSet = statement.executeQuery(selectSQL);
           while (resultSet.next()) {
@@ -221,13 +221,19 @@ public class UpgradeCatalog211 extends AbstractUpgradeCatalog {
             final String serviceName = resultSet.getString("service_name");
             final String componentName = resultSet.getString("component_name");
             final Long hostId = resultSet.getLong("host_id");
-
-            String updateSQL = MessageFormat.format(
-                "UPDATE {0} SET {1} = {2,number,#} WHERE cluster_id = {3} AND service_name = ''{4}'' AND component_name = ''{5}'' and host_id = {6,number,#}",
-                HOST_COMPONENT_STATE_TABLE, HOST_COMPONENT_STATE_ID_COLUMN, m_hcsId.getAndIncrement(),
-                clusterId, serviceName, componentName, hostId);
-
-            dbAccessor.executeQuery(updateSQL);
+            final Long idKey = resultSet.getLong("id");
+
+            if (idKey != 0 && m_hcsId.get() == 1) {
+              m_hcsId.set(idKey);
+              m_hcsId.getAndIncrement();
+            } else if(idKey == 0) {
+              String updateSQL = MessageFormat.format(
+                  "UPDATE {0} SET {1} = {2,number,#} WHERE cluster_id = {3} AND service_name = ''{4}'' AND component_name = ''{5}'' and host_id = {6,number,#}",
+                  HOST_COMPONENT_STATE_TABLE, HOST_COMPONENT_STATE_ID_COLUMN, m_hcsId.getAndIncrement(),
+                  clusterId, serviceName, componentName, hostId);
+
+              dbAccessor.executeQuery(updateSQL);
+            }
           }
         }
       } finally {


[09/24] ambari git commit: AMBARI-18975 Remove Zeppelin View from Ambari (r-kamath)

Posted by jo...@apache.org.
AMBARI-18975 Remove Zeppelin View from Ambari (r-kamath)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c2dc7538
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c2dc7538
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c2dc7538

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: c2dc7538b65ab9f045010b7964ba00551b0ea099
Parents: 73d372b
Author: Renjith Kamath <re...@gmail.com>
Authored: Fri Dec 2 14:39:28 2016 +0530
Committer: Renjith Kamath <re...@gmail.com>
Committed: Fri Dec 2 14:52:51 2016 +0530

----------------------------------------------------------------------
 .../server/upgrade/UpgradeCatalog250.java       |   6 +
 .../server/upgrade/UpgradeCatalog250Test.java   |  17 +-
 contrib/views/pom.xml                           |   1 -
 contrib/views/zeppelin/pom.xml                  | 190 -------------------
 .../view/zeppelin/ZeppelinServiceCheck.java     |  55 ------
 .../ambari/view/zeppelin/ZeppelinServlet.java   | 113 -----------
 .../zeppelin/src/main/resources/WEB-INF/web.xml |  40 ----
 .../src/main/resources/view.log4j.properties    |  27 ---
 .../views/zeppelin/src/main/resources/view.xml  |  48 -----
 9 files changed, 17 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
index 3b2cdd3..837f340 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog250.java
@@ -136,6 +136,7 @@ public class UpgradeCatalog250 extends AbstractUpgradeCatalog {
     updateAMSConfigs();
     updateKafkaConfigs();
     updateHiveLlapConfigs();
+    updateTablesForZeppelinViewRemoval();
   }
 
   protected void updateHostVersionTable() throws SQLException {
@@ -227,6 +228,11 @@ public class UpgradeCatalog250 extends AbstractUpgradeCatalog {
     }
   }
 
+  protected void updateTablesForZeppelinViewRemoval() throws SQLException {
+    dbAccessor.executeQuery("DELETE from viewinstance WHERE view_name='ZEPPELIN{1.0.0}'", true);
+    dbAccessor.executeQuery("DELETE from viewmain WHERE view_name='ZEPPELIN{1.0.0}'", true);
+    dbAccessor.executeQuery("DELETE from viewparameter WHERE view_name='ZEPPELIN{1.0.0}'", true);
+  }
 
   protected String updateAmsEnvContent(String content) {
     if (content == null) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
index 978e2dc..0b2b32d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog250Test.java
@@ -210,16 +210,18 @@ public class UpgradeCatalog250Test {
   @Test
   public void testExecuteDMLUpdates() throws Exception {
     Method updateAmsConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateAMSConfigs");
-    Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml");
     Method updateKafkaConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateKafkaConfigs");
     Method updateHiveLlapConfigs = UpgradeCatalog250.class.getDeclaredMethod("updateHiveLlapConfigs");
+    Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml");
+    Method updateTablesForZeppelinViewRemoval = UpgradeCatalog250.class.getDeclaredMethod("updateTablesForZeppelinViewRemoval");
 
     UpgradeCatalog250 upgradeCatalog250 = createMockBuilder(UpgradeCatalog250.class)
-        .addMockedMethod(updateAmsConfigs)
-        .addMockedMethod(addNewConfigurationsFromXml)
-        .addMockedMethod(updateKafkaConfigs)
-        .addMockedMethod(updateHiveLlapConfigs)
-        .createMock();
+      .addMockedMethod(updateAmsConfigs)
+      .addMockedMethod(updateKafkaConfigs)
+      .addMockedMethod(updateHiveLlapConfigs)
+      .addMockedMethod(addNewConfigurationsFromXml)
+      .addMockedMethod(updateTablesForZeppelinViewRemoval)
+      .createMock();
 
     upgradeCatalog250.updateAMSConfigs();
     expectLastCall().once();
@@ -233,6 +235,9 @@ public class UpgradeCatalog250Test {
     upgradeCatalog250.updateHiveLlapConfigs();
     expectLastCall().once();
 
+    upgradeCatalog250.updateTablesForZeppelinViewRemoval();
+    expectLastCall().once();
+
     replay(upgradeCatalog250);
 
     upgradeCatalog250.executeDMLUpdates();

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pom.xml b/contrib/views/pom.xml
index fb7d8fa..ea426cd 100644
--- a/contrib/views/pom.xml
+++ b/contrib/views/pom.xml
@@ -46,7 +46,6 @@
     <module>tez</module>
     <module>hawq</module>
     <module>storm</module>
-    <module>zeppelin</module>
     <module>hueambarimigration</module>
     <module>hive-next</module>
     <module>hive</module>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/pom.xml b/contrib/views/zeppelin/pom.xml
deleted file mode 100644
index 2a52ce7..0000000
--- a/contrib/views/zeppelin/pom.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<!--
-   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.
--->
-<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.apache.ambari.contrib.views</groupId>
-  <artifactId>zeppelin-view</artifactId>
-  <version>1.0.0.0</version>
-  <name>Zeppelin</name>
-
-  <parent>
-    <groupId>org.apache.ambari.contrib.views</groupId>
-    <artifactId>ambari-contrib-views</artifactId>
-    <version>2.0.0.0-SNAPSHOT</version>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.8.1</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.easymock</groupId>
-      <artifactId>easymock</artifactId>
-      <version>3.1</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.ambari</groupId>
-      <artifactId>ambari-views</artifactId>
-      <version>${ambari.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-server</artifactId>
-      <version>1.8</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
-      <version>2.5</version>
-      <scope>provided</scope>
-    </dependency>
-
-
-    <dependency>
-      <groupId>commons-configuration</groupId>
-      <artifactId>commons-configuration</artifactId>
-      <version>1.6</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-csv</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-collections4</artifactId>
-      <version>4.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <version>1.7.5</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.ambari.contrib.views</groupId>
-      <artifactId>ambari-views-utils</artifactId>
-      <version>2.0.0.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.json</groupId>
-      <artifactId>json</artifactId>
-      <version>20160212</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-      <version>4.5.2</version>
-    </dependency>
-
-
-  </dependencies>
-
-  <properties>
-    <ambari.dir>${project.parent.parent.parent.basedir}</ambari.dir>
-    <hive-version>1.0.0</hive-version>
-    <ambari.version>2.0.0.0-SNAPSHOT</ambari.version>
-  </properties>
-  <build>
-    <plugins>
-
-      <!-- Building frontend -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.1</version>
-        <configuration>
-          <source>1.7</source>
-          <target>1.7</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>generate-resources</phase>
-            <goals>
-              <goal>copy-dependencies</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${project.build.directory}/lib</outputDirectory>
-              <includeScope>runtime</includeScope>
-            </configuration>
-          </execution>
-          <execution>
-            <id>copy-artifact</id>
-            <phase>package</phase>
-            <goals>
-              <goal>copy</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>${project.groupId}</groupId>
-                  <artifactId>${project.artifactId}</artifactId>
-                  <version>${project.version}</version>
-                  <type>${project.packaging}</type>
-                </artifactItem>
-              </artifactItems>
-              <outputDirectory>${views.jars.dir.rel}</outputDirectory>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.vafer</groupId>
-        <artifactId>jdeb</artifactId>
-        <version>1.0.1</version>
-        <executions>
-          <execution>
-            <phase>none</phase>
-            <goals>
-              <goal>jdeb</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <submodules>false</submodules>
-        </configuration>
-      </plugin>
-    </plugins>
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-        <includes>
-          <include>WEB-INF/web.xml</include>
-          <include>META-INF/**/*</include>
-          <include>view.xml</include>
-          <include>WEB-INF/index.jsp</include>
-        </includes>
-      </resource>
-      <resource>
-        <targetPath>WEB-INF/lib</targetPath>
-        <filtering>false</filtering>
-        <directory>target/lib</directory>
-      </resource>
-    </resources>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServiceCheck.java
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServiceCheck.java b/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServiceCheck.java
deleted file mode 100644
index 8f94260..0000000
--- a/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServiceCheck.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.view.zeppelin;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.json.JSONObject;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-
-public class ZeppelinServiceCheck {
-    static String check(String host, String port) {
-        String url = "http://" + host + ":" + port;
-        JSONObject json = new JSONObject();
-        json.put("url", url);
-        try {
-            HttpClient httpclient = HttpClientBuilder.create().build();
-            HttpGet httpget = new HttpGet(url);
-            HttpResponse httpresponse = httpclient.execute(httpget);
-            if (httpresponse.getStatusLine().getStatusCode() == 200) {
-                json.put("status", "SUCCESS");
-                json.put("message", "Zeppelin is running");
-            }
-        } catch (Exception e) {
-            json.put("status", "ERROR");
-            json.put("message", "Zeppelin is not running");
-        }
-        return json.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServlet.java
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServlet.java b/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServlet.java
deleted file mode 100644
index ab61a3d..0000000
--- a/contrib/views/zeppelin/src/main/java/org/apache/ambari/view/zeppelin/ZeppelinServlet.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.view.zeppelin;
-
-import org.apache.ambari.view.ViewContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.List;
-
-
-public class ZeppelinServlet extends HttpServlet {
-  private ViewContext viewContext;
-  private final static Logger LOG = LoggerFactory.getLogger(ZeppelinServlet.class);
-
-  @Override
-  public void init(ServletConfig config) throws ServletException {
-    super.init(config);
-
-    ServletContext context = config.getServletContext();
-    viewContext = (ViewContext) context.getAttribute(ViewContext.CONTEXT_ATTRIBUTE);
-  }
-
-  public void service(HttpServletRequest req,
-                      HttpServletResponse res) throws IOException {
-    res.setContentType("text/html");
-    PrintWriter out = res.getWriter();
-    String publicName = "";
-    String port = "";
-    try {
-      port = viewContext.getProperties().get("zeppelin.server.port");
-      if (viewContext.getCluster() != null) {
-        List<String> hostsForServiceComponents = viewContext.getCluster().getHostsForServiceComponent
-            ("ZEPPELIN", "ZEPPELIN_MASTER");
-        publicName = hostsForServiceComponents.get(0);
-      } else {
-        publicName = viewContext.getProperties().get("zeppelin.host.publicname");
-      }
-    } catch (Exception e) {
-      LOG.error("Zeppelin view servlet failed", e);
-    }
-    out.println("<html lang=\"en\">" +
-        "<head>" +
-        "    <meta charset=\"utf-8\"/>" +
-        "    <link rel=\"stylesheet\" href=\"/stylesheets/vendor.css\">" +
-        "</head>" +
-        "<body>" +
-        "" +
-        "<div class=\"container-fluid\" id=\"messageContainer\" style=\"display:none;\">" +
-        "    <h1>Welcome to the Zeppelin View</h1>" +
-        "    <h3>Service check failed</h3>" +
-        "" +
-        "    <table class=\"table\">" +
-        "        <tbody>" +
-        "        <tr>" +
-        "            <td>zeppelin service is not running</td>" +
-        "        </tr>" +
-        "        </tbody>" +
-        "    </table>" +
-        "" +
-        "</div>" +
-        "" +
-        "<iframe id='zeppelinIFrame' width=\"100%\" seamless=\"seamless\" style=\"border: 0px;\"></iframe>" +
-        "<script>" +
-        "var $ = jQuery = parent.jQuery;" +
-        "var iframe = document.querySelector('#zeppelinIFrame');" +
-        "var messageContainer = document.querySelector('#messageContainer');" +
-        "" +
-        "var serviceCheckResponse = $.parseJSON(' " + ZeppelinServiceCheck.check(publicName, port) + "');" +
-        "" +
-        "if (serviceCheckResponse.status === \"SUCCESS\") {" +
-        "    messageContainer.style.display = \"none\";" +
-        "    iframe.style.display = \"block\";" +
-        "    iframe.src = serviceCheckResponse.url;" +
-        "    iframe.height = window.innerHeight;" +
-        "} else {" +
-        "    messageContainer.style.display = \"block\";" +
-        "    iframe.style.display = \"none\";" +
-        "}" +
-        "" +
-        "$(window).resize(function () {" +
-        "    iframe.height = window.innerHeight;" +
-        "});" +
-        "</script>" +
-        "</body>" +
-        "</html>");
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/src/main/resources/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/src/main/resources/WEB-INF/web.xml b/contrib/views/zeppelin/src/main/resources/WEB-INF/web.xml
deleted file mode 100644
index 6b2d156..0000000
--- a/contrib/views/zeppelin/src/main/resources/WEB-INF/web.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-
-<!--
-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. Kerberos, LDAP, Custom. Binary/Htt
--->
-
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
-         version="2.4">
-
-  <display-name>Zeppelin view servlet</display-name>
-  <description>
-    This is the Zeppelin view servlet application.
-  </description>
-
-  <servlet>
-    <servlet-name>ZeppelinServlet</servlet-name>
-    <servlet-class>org.apache.ambari.view.zeppelin.ZeppelinServlet</servlet-class>
-  </servlet>
-
-  <servlet-mapping>
-    <servlet-name>ZeppelinServlet</servlet-name>
-    <url-pattern>/</url-pattern>
-  </servlet-mapping>
-
-</web-app>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/src/main/resources/view.log4j.properties
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/src/main/resources/view.log4j.properties b/contrib/views/zeppelin/src/main/resources/view.log4j.properties
deleted file mode 100644
index 15d264e..0000000
--- a/contrib/views/zeppelin/src/main/resources/view.log4j.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2011 The Apache Software Foundation
-#
-# 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.
-
-log4j.appender.zeppelinView=org.apache.log4j.RollingFileAppender
-log4j.appender.zeppelinView.File=${ambari.log.dir}/zeppelin-view/zeppelin-view.log
-log4j.appender.zeppelinView.MaxFileSize=80MB
-log4j.appender.zeppelinView.MaxBackupIndex=60
-log4j.appender.zeppelinView.layout=org.apache.log4j.PatternLayout
-log4j.appender.zeppelinView.layout.ConversionPattern=%d{DATE} %5p [%t] [%X{viewName} %X{viewVersion} %X{viewInstanceName}] %c{1}:%L - %m%n
-
-log4j.logger.org.apache.ambari.view.zeppelin=INFO,zeppelinView
-log4j.additivity.org.apache.ambari.view.zeppelin=false
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c2dc7538/contrib/views/zeppelin/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/zeppelin/src/main/resources/view.xml b/contrib/views/zeppelin/src/main/resources/view.xml
deleted file mode 100644
index 197c397..0000000
--- a/contrib/views/zeppelin/src/main/resources/view.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-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. Kerberos, LDAP, Custom. Binary/Htt
--->
-<view>
-  <name>ZEPPELIN</name>
-  <label>Zeppelin View!</label>
-  <version>1.0.0</version>
-  <build>${env.BUILD_NUMBER}</build>
-  <description>Ambari view for Apache Zeppelin</description>
-
-  <parameter>
-    <name>zeppelin.server.port</name>
-    <description>Zeppelin Http port (example: 9995).</description>
-    <label>Zeppelin Http port</label>
-    <cluster-config>zeppelin-config/zeppelin.server.port</cluster-config>
-    <required>true</required>
-  </parameter>
-  <parameter>
-    <name>zeppelin.host.publicname</name>
-    <description>Zeppelin host name</description>
-    <label>Zeppelin host name</label>
-    <cluster-config>fake</cluster-config>
-    <required>true</required>
-  </parameter>
-
-  <auto-instance>
-    <name>AUTO_ZEPPELIN_INSTANCE</name>
-    <label>Zeppelin View</label>
-    <description>This view instance is auto created when the Zeppelin service is added to a cluster.</description>
-    <stack-id>HDP-2.*</stack-id>
-    <services>
-      <service>ZEPPELIN</service>
-    </services>
-  </auto-instance>
-</view>
\ No newline at end of file