summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ambari-agent/src/main/python/ambari_agent/RecoveryManager.py41
-rw-r--r--ambari-agent/src/test/python/ambari_agent/TestActionQueue.py2
-rw-r--r--ambari-agent/src/test/python/ambari_agent/TestRecoveryManager.py88
-rw-r--r--ambari-common/src/main/python/ambari_commons/os_check.py73
-rw-r--r--ambari-common/src/main/python/ambari_commons/resources/os_family.json137
-rw-r--r--ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py7
-rw-r--r--ambari-funtest/pom.xml5
-rw-r--r--ambari-funtest/src/test/resources/stacks/HDP/2.1.1/services/AMBARI_METRICS/metainfo.xml2
-rw-r--r--ambari-metrics/ambari-metrics-grafana/README.md20
-rw-r--r--ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js127
-rw-r--r--ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html6
-rw-r--r--ambari-metrics/ambari-metrics-grafana/pom.xml16
-rw-r--r--ambari-metrics/ambari-metrics-grafana/screenshots/20-templating.pngbin0 -> 694376 bytes
-rw-r--r--ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java18
-rw-r--r--ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java21
-rw-r--r--ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TimelineMetricConfiguration.java10
-rw-r--r--ambari-metrics/pom.xml1
-rw-r--r--ambari-project/pom.xml2
-rw-r--r--ambari-server/pom.xml5
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java39
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java18
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcher.java18
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java2
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/state/services/CachedAlertFlushService.java2
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/state/stack/JsonOsFamilyRoot.java38
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java8
-rw-r--r--ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog222.java116
-rw-r--r--ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/configuration/accumulo-site.xml2
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-site.xml37
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/metainfo.xml2
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_collector.py4
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana.py5
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana_util.py6
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_monitor.py2
-rw-r--r--ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/templates/metrics_grafana_datasource.json.j22
-rw-r--r--ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/configuration/application-properties.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/configuration/falcon-startup.properties.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/HAWQ/2.0.0/metainfo.xml10
-rw-r--r--ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawq_constants.py1
-rw-r--r--ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawqstandby.py6
-rw-r--r--ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/configuration/hbase-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml3
-rw-r--r--ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml3
-rw-r--r--ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/webhcat-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/configuration/kafka-broker.xml2
-rw-r--r--ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/configuration/ranger-knox-plugin-properties.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/configuration/oozie-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/configuration/oozie-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/configuration/kms-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/configuration/storm-site.xml1
-rw-r--r--ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml2
-rw-r--r--ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml8
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py5
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/configuration/hive-site.xml2
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.1/services/OOZIE/configuration/oozie-site.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.1/services/YARN/configuration/yarn-site.xml3
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml12
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/configuration/ranger-hbase-plugin-properties.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/ranger-hdfs-plugin-properties.xml4
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-env.xml20
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-site.xml18
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/ranger-hive-plugin-properties.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/ranger-storm-plugin-properties.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml2
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py13
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml12
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/kafka-broker.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/ranger-kafka-plugin-properties.xml1
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml2
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.3/services/STORM/configuration/storm-site.xml2
-rw-r--r--ambari-server/src/main/resources/stacks/HDP/2.4/repos/repoinfo.xml12
-rw-r--r--ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-env.xml20
-rw-r--r--ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-site.xml8
-rw-r--r--ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/stack_advisor.py13
-rw-r--r--ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java78
-rw-r--r--ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcherTest.java61
-rw-r--r--ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog222Test.java21
-rw-r--r--ambari-server/src/test/python/TestOSCheck.py37
-rw-r--r--ambari-server/src/test/python/stacks/2.1/configs/hive-metastore-upgrade.json3
-rw-r--r--ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py17
-rw-r--r--ambari-server/src/test/python/stacks/2.3/common/services-sparkts-hive.json47
-rw-r--r--ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py5
-rw-r--r--ambari-web/app/controllers/main/admin/service_auto_start.js161
-rw-r--r--ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js74
-rw-r--r--ambari-web/app/messages.js1
-rw-r--r--ambari-web/app/mixins/common/widgets/widget_mixin.js49
-rw-r--r--ambari-web/app/routes/main.js13
-rw-r--r--ambari-web/app/styles/application.less10
-rw-r--r--ambari-web/app/templates/main/admin/service_auto_start.hbs46
-rw-r--r--ambari-web/app/templates/main/admin/service_auto_start/component_auto_start.hbs19
-rw-r--r--ambari-web/app/templates/main/host/log_metrics.hbs26
-rw-r--r--ambari-web/app/templates/main/host/summary.hbs24
-rw-r--r--ambari-web/app/utils/ajax/ajax.js21
-rw-r--r--ambari-web/app/utils/ember_reopen.js46
-rw-r--r--ambari-web/app/views.js2
-rw-r--r--ambari-web/app/views/common/chart/pie.js11
-rw-r--r--ambari-web/app/views/common/widget/graph_widget_view.js4
-rw-r--r--ambari-web/app/views/main/admin/service_auto_start.js14
-rw-r--r--ambari-web/app/views/main/admin/service_auto_start/component_auto_start.js57
-rw-r--r--ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js10
-rw-r--r--ambari-web/app/views/main/host/log_metrics.js141
-rw-r--r--ambari-web/app/views/main/host/logs_view.js12
-rw-r--r--ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js121
-rw-r--r--ambari-web/test/mixins/common/widget_mixin_test.js124
-rw-r--r--ambari-web/test/utils/ember_reopen_test.js57
-rw-r--r--ambari-web/test/views/common/log_file_search_view_test.js3
108 files changed, 1732 insertions, 665 deletions
diff --git a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
index b5795b235c..ed537ca692 100644
--- a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
+++ b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
@@ -88,7 +88,6 @@ class RecoveryManager:
self.allowed_desired_states = [self.STARTED, self.INSTALLED]
self.allowed_current_states = [self.INIT, self.INSTALLED]
self.enabled_components = []
- self.disabled_components = []
self.statuses = {}
self.__status_lock = threading.RLock()
self.__command_lock = threading.RLock()
@@ -107,7 +106,7 @@ class RecoveryManager:
self.actions = {}
- self.update_config(6, 60, 5, 12, recovery_enabled, auto_start_only, "", "")
+ self.update_config(6, 60, 5, 12, recovery_enabled, auto_start_only, "")
pass
@@ -213,19 +212,12 @@ class RecoveryManager:
pass
"""
- Whether specific components are enabled/disabled for recovery. Being enabled takes
- precedence over being disabled. When specific components are enabled then only
- those components are enabled. When specific components are disabled then all of
- the other components are enabled.
+ Whether specific components are enabled for recovery.
"""
def configured_for_recovery(self, component):
- if len(self.disabled_components) == 0 and len(self.enabled_components) == 0:
- return True
- if len(self.disabled_components) > 0 and component not in self.disabled_components \
- and len(self.enabled_components) == 0:
- return True
if len(self.enabled_components) > 0 and component in self.enabled_components:
return True
+
return False
def requires_recovery(self, component):
@@ -547,8 +539,8 @@ class RecoveryManager:
"maxCount" : 10,
"windowInMinutes" : 60,
"retryGap" : 0,
- "disabledComponents" : "a,b",
- "enabledComponents" : "c,d"}
+ "components" : "a,b"
+ }
"""
recovery_enabled = False
@@ -558,7 +550,6 @@ class RecoveryManager:
retry_gap = 5
max_lifetime_count = 12
enabled_components = ""
- disabled_components = ""
if reg_resp and "recoveryConfig" in reg_resp:
@@ -578,17 +569,16 @@ class RecoveryManager:
if 'maxLifetimeCount' in config:
max_lifetime_count = self._read_int_(config['maxLifetimeCount'], max_lifetime_count)
- if 'enabledComponents' in config:
- enabled_components = config['enabledComponents']
- if 'disabledComponents' in config:
- disabled_components = config['disabledComponents']
+ if 'components' in config:
+ enabled_components = config['components']
+
self.update_config(max_count, window_in_min, retry_gap, max_lifetime_count, recovery_enabled, auto_start_only,
- enabled_components, disabled_components)
+ enabled_components)
pass
def update_config(self, max_count, window_in_min, retry_gap, max_lifetime_count, recovery_enabled,
- auto_start_only, enabled_components, disabled_components):
+ auto_start_only, enabled_components):
"""
Update recovery configuration, recovery is disabled if configuration values
are not correct
@@ -619,7 +609,6 @@ class RecoveryManager:
self.retry_gap_in_sec = retry_gap * 60
self.auto_start_only = auto_start_only
self.max_lifetime_count = max_lifetime_count
- self.disabled_components = []
self.enabled_components = []
self.allowed_desired_states = [self.STARTED, self.INSTALLED]
@@ -635,19 +624,13 @@ class RecoveryManager:
if len(component.strip()) > 0:
self.enabled_components.append(component.strip())
- if disabled_components is not None and len(disabled_components) > 0:
- components = disabled_components.split(",")
- for component in components:
- if len(component.strip()) > 0:
- self.disabled_components.append(component.strip())
-
self.recovery_enabled = recovery_enabled
if self.recovery_enabled:
logger.info(
"==> Auto recovery is enabled with maximum %s in %s minutes with gap of %s minutes between and"
- " lifetime max being %s. Enabled components - %s and Disabled components - %s",
+ " lifetime max being %s. Enabled components - %s",
self.max_count, self.window_in_min, self.retry_gap, self.max_lifetime_count,
- ', '.join(self.enabled_components), ', '.join(self.disabled_components))
+ ', '.join(self.enabled_components))
pass
diff --git a/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
index 715a60cb8c..f7e28949cc 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
@@ -338,7 +338,7 @@ class TestActionQueue(TestCase):
config.set('agent', 'tolerate_download_failures', "true")
dummy_controller = MagicMock()
dummy_controller.recovery_manager = RecoveryManager(tempfile.mktemp())
- dummy_controller.recovery_manager.update_config(5, 5, 1, 11, True, False, "", "")
+ dummy_controller.recovery_manager.update_config(5, 5, 1, 11, True, False, "")
actionQueue = ActionQueue(config, dummy_controller)
unfreeze_flag = threading.Event()
diff --git a/ambari-agent/src/test/python/ambari_agent/TestRecoveryManager.py b/ambari-agent/src/test/python/ambari_agent/TestRecoveryManager.py
index 0321a20964..ef81704f21 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestRecoveryManager.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestRecoveryManager.py
@@ -141,6 +141,7 @@ class _TestRecoveryManager(TestCase):
mock_uds.reset_mock()
+ rm.update_config(12, 5, 1, 15, True, False, "NODEMANAGER")
rm.process_execution_commands([self.exec_command1, self.exec_command2, self.exec_command3])
mock_uds.assert_has_calls([call("NODEMANAGER", "INSTALLED")], [call("NODEMANAGER", "STARTED")])
@@ -173,32 +174,29 @@ class _TestRecoveryManager(TestCase):
rm = RecoveryManager(tempfile.mktemp(), True, False)
self.assertTrue(rm.enabled())
- rm.update_config(0, 60, 5, 12, True, False, "", "")
+ config = rm.update_config(0, 60, 5, 12, True, False, "")
self.assertFalse(rm.enabled())
- rm.update_config(6, 60, 5, 12, True, False, "", "")
+ rm.update_config(6, 60, 5, 12, True, False, "")
self.assertTrue(rm.enabled())
- rm.update_config(6, 0, 5, 12, True, False, "", "")
+ rm.update_config(6, 0, 5, 12, True, False, "")
self.assertFalse(rm.enabled())
- rm.update_config(6, 60, 0, 12, True, False, "", "")
+ rm.update_config(6, 60, 0, 12, True, False, "")
self.assertFalse(rm.enabled())
- rm.update_config(6, 60, 1, 12, True, False, None, None)
+ rm.update_config(6, 60, 1, 12, True, False, None)
self.assertTrue(rm.enabled())
- rm.update_config(6, 60, 61, 12, True, False, "", None)
+ rm.update_config(6, 60, 61, 12, True, False, None)
self.assertFalse(rm.enabled())
- rm.update_config(6, 60, 5, 0, True, False, None, "")
- self.assertFalse(rm.enabled())
-
- rm.update_config(6, 60, 5, 4, True, False, "", "")
+ rm.update_config(6, 60, 5, 4, True, False, "")
self.assertFalse(rm.enabled())
# maximum 2 in 2 minutes and at least 1 minute wait
- rm.update_config(2, 5, 1, 4, True, False, "", "")
+ rm.update_config(2, 5, 1, 4, True, False, "")
self.assertTrue(rm.enabled())
# T = 1000-2
@@ -224,7 +222,7 @@ class _TestRecoveryManager(TestCase):
self.assertFalse(rm.may_execute("NODEMANAGER")) # too soon
# maximum 2 in 2 minutes and no min wait
- rm.update_config(2, 5, 1, 5, True, True, "", "")
+ rm.update_config(2, 5, 1, 5, True, True, "")
# T = 1500-3
self.assertTrue(rm.execute("NODEMANAGER2"))
@@ -244,7 +242,7 @@ class _TestRecoveryManager(TestCase):
def test_recovery_required(self):
rm = RecoveryManager(tempfile.mktemp(), True, False)
-
+ rm.update_config(12, 5, 1, 15, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "INSTALLED")
self.assertFalse(rm.requires_recovery("NODEMANAGER"))
@@ -292,13 +290,13 @@ class _TestRecoveryManager(TestCase):
def test_recovery_required2(self):
rm = RecoveryManager(tempfile.mktemp(), True, True)
- rm.update_config(15, 5, 1, 16, True, False, "", "")
+ rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
self.assertTrue(rm.requires_recovery("NODEMANAGER"))
rm = RecoveryManager(tempfile.mktemp(), True, True)
- rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER", "")
+ rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
self.assertTrue(rm.requires_recovery("NODEMANAGER"))
@@ -308,26 +306,16 @@ class _TestRecoveryManager(TestCase):
self.assertFalse(rm.requires_recovery("DATANODE"))
rm = RecoveryManager(tempfile.mktemp(), True, True)
- rm.update_config(15, 5, 1, 16, True, False, "", "NODEMANAGER")
+ rm.update_config(15, 5, 1, 16, True, False, "")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
self.assertFalse(rm.requires_recovery("NODEMANAGER"))
rm.update_current_status("DATANODE", "INSTALLED")
rm.update_desired_status("DATANODE", "STARTED")
- self.assertTrue(rm.requires_recovery("DATANODE"))
-
- rm.update_config(15, 5, 1, 16, True, False, "", "NODEMANAGER")
- rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER", "")
- rm.update_current_status("NODEMANAGER", "INSTALLED")
- rm.update_desired_status("NODEMANAGER", "STARTED")
- self.assertTrue(rm.requires_recovery("NODEMANAGER"))
-
- rm.update_current_status("DATANODE", "INSTALLED")
- rm.update_desired_status("DATANODE", "STARTED")
self.assertFalse(rm.requires_recovery("DATANODE"))
- rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER", "NODEMANAGER")
+ rm.update_config(15, 5, 1, 16, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
self.assertTrue(rm.requires_recovery("NODEMANAGER"))
@@ -392,12 +380,12 @@ class _TestRecoveryManager(TestCase):
4200, 4201, 4202,
4300, 4301, 4302]
rm = RecoveryManager(tempfile.mktemp(), True)
- rm.update_config(15, 5, 1, 16, True, False, "", "")
+ rm.update_config(15, 5, 1, 16, True, False, "")
command1 = copy.deepcopy(self.command)
rm.store_or_update_command(command1)
-
+ rm.update_config(12, 5, 1, 15, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
self.assertEqual("INSTALLED", rm.get_current_status("NODEMANAGER"))
@@ -423,14 +411,14 @@ class _TestRecoveryManager(TestCase):
self.assertEqual(1, len(commands))
self.assertEqual("INSTALL", commands[0]["roleCommand"])
- rm.update_config(2, 5, 1, 5, True, True, "", "")
+ rm.update_config(2, 5, 1, 5, True, True, "")
rm.update_current_status("NODEMANAGER", "INIT")
rm.update_desired_status("NODEMANAGER", "INSTALLED")
commands = rm.get_recovery_commands()
self.assertEqual(0, len(commands))
- rm.update_config(12, 5, 1, 15, True, False, "", "")
+ rm.update_config(12, 5, 1, 15, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INIT")
rm.update_desired_status("NODEMANAGER", "INSTALLED")
@@ -471,25 +459,25 @@ class _TestRecoveryManager(TestCase):
def test_update_rm_config(self, mock_uc):
rm = RecoveryManager(tempfile.mktemp())
rm.update_configuration_from_registration(None)
- mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "", "")])
+ mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "")])
mock_uc.reset_mock()
rm.update_configuration_from_registration({})
- mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "", "")])
+ mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "")])
mock_uc.reset_mock()
rm.update_configuration_from_registration(
{"recoveryConfig": {
"type" : "DEFAULT"}}
)
- mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "", "")])
+ mock_uc.assert_has_calls([call(6, 60, 5, 12, False, True, "")])
mock_uc.reset_mock()
rm.update_configuration_from_registration(
{"recoveryConfig": {
"type" : "FULL"}}
)
- mock_uc.assert_has_calls([call(6, 60, 5, 12, True, False, "", "")])
+ mock_uc.assert_has_calls([call(6, 60, 5, 12, True, False, "")])
mock_uc.reset_mock()
rm.update_configuration_from_registration(
@@ -497,7 +485,7 @@ class _TestRecoveryManager(TestCase):
"type" : "AUTO_START",
"max_count" : "med"}}
)
- mock_uc.assert_has_calls([call(6, 60, 5, 12, True, True, "", "")])
+ mock_uc.assert_has_calls([call(6, 60, 5, 12, True, True, "")])
mock_uc.reset_mock()
rm.update_configuration_from_registration(
@@ -507,10 +495,9 @@ class _TestRecoveryManager(TestCase):
"windowInMinutes" : 20,
"retryGap" : 2,
"maxLifetimeCount" : 5,
- "enabledComponents" : " A,B",
- "disabledComponents" : "C"}}
+ "components" : " A,B"}}
)
- mock_uc.assert_has_calls([call(5, 20, 2, 5, True, True, " A,B", "C")])
+ mock_uc.assert_has_calls([call(5, 20, 2, 5, True, True, " A,B")])
pass
@patch.object(RecoveryManager, "_now_")
@@ -522,7 +509,7 @@ class _TestRecoveryManager(TestCase):
rec_st = rm.get_recovery_status()
self.assertEquals(rec_st, {"summary": "DISABLED"})
- rm.update_config(2, 5, 1, 4, True, True, "", "")
+ rm.update_config(2, 5, 1, 4, True, True, "")
rec_st = rm.get_recovery_status()
self.assertEquals(rec_st, {"summary": "RECOVERABLE", "componentReports": []})
@@ -566,12 +553,12 @@ class _TestRecoveryManager(TestCase):
[1000, 1001, 1002, 1003, 1104, 1105, 1106, 1807, 1808, 1809, 1810, 1811, 1812]
rm = RecoveryManager(tempfile.mktemp(), True)
- rm.update_config(5, 5, 1, 11, True, False, "", "")
+ rm.update_config(5, 5, 1, 11, True, False, "")
command1 = copy.deepcopy(self.command)
rm.store_or_update_command(command1)
-
+ rm.update_config(12, 5, 1, 15, True, False, "NODEMANAGER")
rm.update_current_status("NODEMANAGER", "INSTALLED")
rm.update_desired_status("NODEMANAGER", "STARTED")
@@ -607,23 +594,24 @@ class _TestRecoveryManager(TestCase):
def test_configured_for_recovery(self):
rm = RecoveryManager(tempfile.mktemp(), True)
+ rm.update_config(12, 5, 1, 15, True, False, "A,B")
self.assertTrue(rm.configured_for_recovery("A"))
self.assertTrue(rm.configured_for_recovery("B"))
- rm.update_config(5, 5, 1, 11, True, False, "", "")
- self.assertTrue(rm.configured_for_recovery("A"))
- self.assertTrue(rm.configured_for_recovery("B"))
+ rm.update_config(5, 5, 1, 11, True, False, "")
+ self.assertFalse(rm.configured_for_recovery("A"))
+ self.assertFalse(rm.configured_for_recovery("B"))
- rm.update_config(5, 5, 1, 11, True, False, "A", "")
+ rm.update_config(5, 5, 1, 11, True, False, "A")
self.assertTrue(rm.configured_for_recovery("A"))
self.assertFalse(rm.configured_for_recovery("B"))
- rm.update_config(5, 5, 1, 11, True, False, "", "B,C")
+ rm.update_config(5, 5, 1, 11, True, False, "A")
self.assertTrue(rm.configured_for_recovery("A"))
self.assertFalse(rm.configured_for_recovery("B"))
self.assertFalse(rm.configured_for_recovery("C"))
- rm.update_config(5, 5, 1, 11, True, False, "A, D, F ", "B,C")
+ rm.update_config(5, 5, 1, 11, True, False, "A, D, F ")
self.assertTrue(rm.configured_for_recovery("A"))
self.assertFalse(rm.configured_for_recovery("B"))
self.assertFalse(rm.configured_for_recovery("C"))
@@ -637,7 +625,7 @@ class _TestRecoveryManager(TestCase):
[1000, 1071, 1372]
rm = RecoveryManager(tempfile.mktemp(), True)
- rm.update_config(2, 5, 1, 4, True, True, "", "")
+ rm.update_config(2, 5, 1, 4, True, True, "")
rm.execute("COMPONENT")
actions = rm.get_actions_copy()["COMPONENT"]
@@ -655,7 +643,7 @@ class _TestRecoveryManager(TestCase):
def test_is_action_info_stale(self, time_mock):
rm = RecoveryManager(tempfile.mktemp(), True)
- rm.update_config(5, 60, 5, 16, True, False, "", "")
+ rm.update_config(5, 60, 5, 16, True, False, "")
time_mock.return_value = 0
self.assertFalse(rm.is_action_info_stale("COMPONENT_NAME"))
diff --git a/ambari-common/src/main/python/ambari_commons/os_check.py b/ambari-common/src/main/python/ambari_commons/os_check.py
index c5457bb2a5..b430c869d0 100644
--- a/ambari-common/src/main/python/ambari_commons/os_check.py
+++ b/ambari-common/src/main/python/ambari_commons/os_check.py
@@ -56,6 +56,8 @@ RESOURCES_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "resou
# family JSON data
OSFAMILY_JSON_RESOURCE = "os_family.json"
+JSON_OS_MAPPING = "mapping"
+JSON_OS_ALIASES = "aliases"
JSON_OS_TYPE = "distro"
JSON_OS_VERSION = "versions"
JSON_EXTENDS = "extends"
@@ -76,6 +78,8 @@ VER_NT_SERVER = 3
_IS_ORACLE_LINUX = os.path.exists('/etc/oracle-release')
_IS_REDHAT_LINUX = os.path.exists('/etc/redhat-release')
+SYSTEM_RELEASE_FILE = "/etc/system-release"
+
def _is_oracle_linux():
return _IS_ORACLE_LINUX
@@ -84,16 +88,16 @@ def _is_redhat_linux():
def advanced_check(distribution):
distribution = list(distribution)
- if os.path.exists("/etc/issue"):
- with open("/etc/issue", "rb") as fp:
+ if os.path.exists(SYSTEM_RELEASE_FILE):
+ with open(SYSTEM_RELEASE_FILE, "rb") as fp:
issue_content = fp.read()
if "Amazon" in issue_content:
distribution[0] = "amazon"
- search_groups = re.search('(\d+)\.(\d+)', issue_content)
+ search_groups = re.search('(\d+\.\d+)', issue_content)
if search_groups:
- distribution[1] = search_groups.group(1) # if version is 2015.09 only get 2015.
+ distribution[1] = search_groups.group(1)
return tuple(distribution)
@@ -114,16 +118,24 @@ class OS_CONST_TYPE(type):
f = open(os.path.join(RESOURCES_DIR, OSFAMILY_JSON_RESOURCE))
json_data = eval(f.read())
f.close()
- for family in json_data:
+
+ if JSON_OS_MAPPING not in json_data:
+ raise Exception("Invalid {0}".format(OSFAMILY_JSON_RESOURCE))
+
+ json_mapping_data = json_data[JSON_OS_MAPPING]
+
+ for family in json_mapping_data:
cls.FAMILY_COLLECTION += [family]
- cls.OS_COLLECTION += json_data[family][JSON_OS_TYPE]
+ cls.OS_COLLECTION += json_mapping_data[family][JSON_OS_TYPE]
cls.OS_FAMILY_COLLECTION += [{
'name': family,
- 'os_list': json_data[family][JSON_OS_TYPE]
+ 'os_list': json_mapping_data[family][JSON_OS_TYPE]
}]
- if JSON_EXTENDS in json_data[family]:
- cls.OS_FAMILY_COLLECTION[-1][JSON_EXTENDS] = json_data[family][JSON_EXTENDS]
+ if JSON_EXTENDS in json_mapping_data[family]:
+ cls.OS_FAMILY_COLLECTION[-1][JSON_EXTENDS] = json_mapping_data[family][JSON_EXTENDS]
+
+ cls.OS_TYPE_ALIASES = json_data[JSON_OS_ALIASES] if JSON_OS_ALIASES in json_data else {}
except:
raise Exception("Couldn't load '%s' file" % OSFAMILY_JSON_RESOURCE)
@@ -194,7 +206,24 @@ class OSCheck:
distribution = ("Darwin", "TestOnly", "1.1.1", "1.1.1", "1.1")
return distribution
-
+
+ @staticmethod
+ def get_alias(os_type, os_version):
+ version_parts = os_version.split('.')
+ full_os_and_major_version = os_type + version_parts[0]
+
+ if full_os_and_major_version in OSConst.OS_TYPE_ALIASES:
+ alias = OSConst.OS_TYPE_ALIASES[full_os_and_major_version]
+ re_groups = re.search('(\D+)(\d+)$', alias).groups()
+ os_type = re_groups[0]
+ os_major_version = re_groups[1]
+
+ version_parts[0] = os_major_version
+ os_version = '.'.join(version_parts)
+
+ return os_type, os_version
+
+
@staticmethod
def get_os_type():
"""
@@ -205,6 +234,10 @@ class OSCheck:
In case cannot detect - exit.
"""
+ return OSCheck.get_alias(OSCheck._get_os_type(), OSCheck._get_os_version())[0]
+
+ @staticmethod
+ def _get_os_type():
# Read content from /etc/*-release file
# Full release name
dist = OSCheck.os_distribution()
@@ -212,18 +245,18 @@ class OSCheck:
# special cases
if _is_oracle_linux():
- return 'oraclelinux'
+ operatingSystem = 'oraclelinux'
elif operatingSystem.startswith('suse linux enterprise server'):
- return 'sles'
+ operatingSystem = 'sles'
elif operatingSystem.startswith('red hat enterprise linux'):
- return 'redhat'
+ operatingSystem = 'redhat'
elif operatingSystem.startswith('darwin'):
- return 'mac'
+ operatingSystem = 'mac'
- if operatingSystem != '':
- return operatingSystem
- else:
+ if operatingSystem == '':
raise Exception("Cannot detect os type. Exiting...")
+
+ return operatingSystem
@staticmethod
def get_os_family():
@@ -257,11 +290,15 @@ class OSCheck:
In case cannot detect raises exception.
"""
+ return OSCheck.get_alias(OSCheck._get_os_type(), OSCheck._get_os_version())[1]
+
+ @staticmethod
+ def _get_os_version():
# Read content from /etc/*-release file
# Full release name
dist = OSCheck.os_distribution()
dist = dist[1]
-
+
if dist:
return dist
else:
diff --git a/ambari-common/src/main/python/ambari_commons/resources/os_family.json b/ambari-common/src/main/python/ambari_commons/resources/os_family.json
index 13014fc3a0..1558c1b101 100644
--- a/ambari-common/src/main/python/ambari_commons/resources/os_family.json
+++ b/ambari-common/src/main/python/ambari_commons/resources/os_family.json
@@ -1,72 +1,69 @@
{
- "redhat": {
- "distro": [
- "redhat",
- "fedora",
- "centos",
- "oraclelinux",
- "ascendos",
- "xenserver",
- "oel",
- "ovs",
- "cloudlinux",
- "slc",
- "scientific",
- "psbm",
- "centos linux"
- ],
- "versions": [
- 6,
- 7
- ]
- },
- "amazon": {
- "extends" : "redhat",
- "distro": [
- "amazon"
- ],
- "versions": [
- 2015
- ]
- },
- "debian": {
- "extends" : "ubuntu",
- "distro": [
- "debian"
- ],
- "versions": [
- 7
- ]
- },
- "ubuntu": {
- "distro": [
- "ubuntu"
- ],
- "versions": [
- 12,
- 14
- ]
- },
- "suse": {
- "distro": [
- "sles",
- "sled",
- "opensuse",
- "suse"
- ],
- "versions": [
- 11
- ]
- },
- "winsrv": {
- "distro": [
- "win2008server",
- "win2008serverr2",
- "win2012server",
- "win2012serverr2"
- ],
- "versions": [
- 6
- ]
- }
+ "mapping": {
+ "redhat": {
+ "distro": [
+ "redhat",
+ "fedora",
+ "centos",
+ "oraclelinux",
+ "amazon",
+ "ascendos",
+ "xenserver",
+ "oel",
+ "ovs",
+ "cloudlinux",
+ "slc",
+ "scientific",
+ "psbm",
+ "centos linux"
+ ],
+ "versions": [
+ 6,
+ 7
+ ]
+ },
+ "debian": {
+ "extends" : "ubuntu",
+ "distro": [
+ "debian"
+ ],
+ "versions": [
+ 7
+ ]
+ },
+ "ubuntu": {
+ "distro": [
+ "ubuntu"
+ ],
+ "versions": [
+ 12,
+ 14
+ ]
+ },
+ "suse": {
+ "distro": [
+ "sles",
+ "sled",
+ "opensuse",
+ "suse"
+ ],
+ "versions": [
+ 11
+ ]
+ },
+ "winsrv": {
+ "distro": [
+ "win2008server",
+ "win2008serverr2",
+ "win2012server",
+ "win2012serverr2"
+ ],
+ "versions": [
+ 6
+ ]
+ }
+ },
+ "aliases": {
+ "amazon2015": "amazon6"
+ }
}
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
index 0fb0fe4b5c..4ca3b7b5f6 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
@@ -19,7 +19,8 @@ limitations under the License.
Ambari Agent
"""
-__all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_mysql", "should_install_mysl_connector"]
+__all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
+ "should_install_mysql", "should_install_mysl_connector"]
import os
from resource_management.libraries.script import Script
@@ -41,6 +42,10 @@ def should_install_ams_collector():
config = Script.get_config()
return 'role' in config and config['role'] == "METRICS_COLLECTOR"
+def should_install_ams_grafana():
+ config = Script.get_config()
+ return 'role' in config and config['role'] == "METRICS_GRAFANA"
+
def should_install_mysql():
config = Script.get_config()
hive_database = config['configurations']['hive-env']['hive_database']
diff --git a/ambari-funtest/pom.xml b/ambari-funtest/pom.xml
index b9c591fc68..4fa342f07f 100644
--- a/ambari-funtest/pom.xml
+++ b/ambari-funtest/pom.xml
@@ -496,11 +496,6 @@
<version>4.2.5</version>
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>14.0.1</version>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
diff --git a/ambari-funtest/src/test/resources/stacks/HDP/2.1.1/services/AMBARI_METRICS/metainfo.xml b/ambari-funtest/src/test/resources/stacks/HDP/2.1.1/services/AMBARI_METRICS/metainfo.xml
index be99b830d3..fe3b860318 100644
--- a/ambari-funtest/src/test/resources/stacks/HDP/2.1.1/services/AMBARI_METRICS/metainfo.xml
+++ b/ambari-funtest/src/test/resources/stacks/HDP/2.1.1/services/AMBARI_METRICS/metainfo.xml
@@ -69,7 +69,7 @@
<packages>
<package>
<name>ambari-metrics-collector</name>
- <condition>package_chooser.should_install_ams_collector()</condition>
+ <condition>should_install_ams_collector</condition>
</package>
<package>
<name>ambari-metrics-monitor</name>
diff --git a/ambari-metrics/ambari-metrics-grafana/README.md b/ambari-metrics/ambari-metrics-grafana/README.md
index 0a138e8f8c..7eb84a7024 100644
--- a/ambari-metrics/ambari-metrics-grafana/README.md
+++ b/ambari-metrics/ambari-metrics-grafana/README.md
@@ -240,4 +240,24 @@ http://GRAFANA_HOST:3000
---
+<a name="templating"></a>
+### Templating
+**Templating allows you to dynamically change graphs by selecting your host from dropdown. To created a templated dashboard, you can follow these steps.**
+
+> 1. Click on the "cog" on the top, select "Templating"
+> 2. Click on "+ New"
+> 3. Enter a name for your variable. Ex: "hosts".
+> 4. Type: query
+> 5. Datasource: This should be set to the name you had chosen for your Datasource. Default is "AMBARI_METRICS"
+> 6. Query: This needs to be "hosts". It is case sensitive as well.
+> 7. Once you've entered the query and you focus your cursor anywhere else, you should see the "Preview of values" updated with the hostnames in your cluster.
+> 8. You can close the Templating Variables section.
+> 9. You should now have a dropdown on your dashboard with hosts from your cluster.
+> 10. When you now add a graph, and select your component and metric, the plotted graph will show you metrics for the selected hostname from the dropdown.
+> 11. The legend on the graph will also now update with the selected host.
+
+**Templalted dashboards do support multiple metrics in a single graph.**
+
+
+![Templating](screenshots/20-templating.png)
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
index 374501c200..e89ad0e73c 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
@@ -27,7 +27,7 @@ define([
var module = angular.module('grafana.services');
- module.factory('AmbariMetricsDatasource', function ($q, backendSrv) {
+ module.factory('AmbariMetricsDatasource', function ($q, backendSrv, templateSrv) {
/**
* AMS Datasource Constructor
*/
@@ -43,7 +43,9 @@ define([
.then(function (items) {
allMetrics = [];
appIds = [];
- var fake = "timeline_metric_store_watcher"; delete items[fake];
+ //We remove a couple of components from the list that do not contain any
+ //pertinent metrics.
+ delete items.timeline_metric_store_watcher; delete items.amssmoketestfake;
for (var key in items) {
if (items.hasOwnProperty(key)) {
items[key].forEach(function (_item) {
@@ -97,10 +99,11 @@ define([
}
var series = [];
var metricData = res.metrics[0].metrics;
+ var hostLegend = res.metrics[0].hostname ? ' on ' + res.metrics[0].hostname : '';
var timeSeries = {};
if (target.hosts === undefined || target.hosts.trim() === "") {
timeSeries = {
- target: target.metric,
+ target: target.metric + hostLegend,
datapoints: []
};
} else {
@@ -119,81 +122,42 @@ define([
};
};
- var precisionSetting = '';
+
var getHostAppIdData = function(target) {
- if (target.shouldAddPrecision) {
- precisionSetting = '&precision=' + target.precision;
- } else {
- precisionSetting = '';
- }
- if (target.shouldAddPrecision && target.shouldComputeRate) {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._rate._"
- + target.aggregator + "&hostname=" + target.hosts + '&appId=' + target.app + '&startTime=' + from
- + '&endTime=' + to + precisionSetting).then(
- getMetricsData(target)
- );
- } else if (target.shouldComputeRate) {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._rate._"
- + target.aggregator + "&hostname=" + target.hosts + '&appId=' + target.app + '&startTime=' + from
- + '&endTime=' + to).then(
- getMetricsData(target)
- );
- } else if (target.shouldAddPrecision){
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._"
- + target.aggregator + "&hostname=" + target.hosts + '&appId=' + target.app + '&startTime=' + from
- + '&endTime=' + to + precisionSetting).then(
- getMetricsData(target)
- );
- } else {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._"
- + target.aggregator + "&hostname=" + target.hosts + '&appId=' + target.app + '&startTime=' + from
- + '&endTime=' + to).then(
+ var precision = target.shouldAddPrecision ? '&precision=' + target.precision : '';
+ var rate = target.shouldComputeRate ? '._rate._' : '._';
+ return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + rate +
+ target.aggregator + "&hostname=" + target.hosts + '&appId=' + target.app + '&startTime=' + from +
+ '&endTime=' + to + precision).then(
getMetricsData(target)
- );
- }
+ );
};
var getServiceAppIdData = function(target) {
- if (target.shouldAddPrecision) { precisionSetting = '&precision=' + target.precision;
- } else { precisionSetting = ''; }
- if (target.shouldAddPrecision && target.shouldComputeRate) {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._rate._"
- + target.aggregator + '&appId=' + target.app + '&startTime=' + from + '&endTime=' + to + precisionSetting)
- .then(
- getMetricsData(target)
- );
- } else if (target.shouldAddPrecision) {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._"
- + target.aggregator + '&appId=' + target.app + '&startTime=' + from + '&endTime=' + to + precisionSetting)
- .then(
- getMetricsData(target)
- );
- } else if (target.shouldComputeRate) {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._rate._"
- + target.aggregator + '&appId=' + target.app + '&startTime=' + from + '&endTime=' + to).then(
- getMetricsData(target)
- );
- } else {
- return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + "._"
- + target.aggregator + '&appId=' + target.app + '&startTime=' + from + '&endTime=' + to).then(
- getMetricsData(target)
- );
- }
+ var templatedHost = (_.isEmpty(templateSrv.variables)) ? "" : templateSrv.variables[0].options.filter(function(host)
+ { return host.selected; }).map(function(hostName) { return hostName.value; });
+ var precision = target.shouldAddPrecision ? '&precision=' + target.precision : '';
+ var rate = target.shouldComputeRate ? '._rate._' : '._';
+ return backendSrv.get(self.url + '/ws/v1/timeline/metrics?metricNames=' + target.metric + rate
+ + target.aggregator + '&hostname=' + templatedHost + '&appId=' + target.app + '&startTime=' + from +
+ '&endTime=' + to + precision).then(
+ getMetricsData(target)
+ );
};
// Time Ranges
var from = Math.floor(options.range.from.valueOf() / 1000);
var to = Math.floor(options.range.to.valueOf() / 1000);
-
var metricsPromises = _.map(options.targets, function(target) {
- console.debug('target app=' + target.app + ',' +
- 'target metric=' + target.metric + ' on host=' + target.hosts);
- if (!!target.hosts) {
- return getHostAppIdData(target);
- } else {
- return getServiceAppIdData(target);
- }
- });
+ console.debug('target app=' + target.app + ',' +
+ 'target metric=' + target.metric + ' on host=' + target.hosts);
+ if (!!target.hosts) {
+ return getHostAppIdData(target);
+ } else {
+ return getServiceAppIdData(target);
+ }
+ });
+
return $q.all(metricsPromises).then(function(metricsDataArray) {
var data = _.map(metricsDataArray, function(metricsData) {
return metricsData.data;
@@ -215,6 +179,32 @@ define([
};
/**
+ * AMS Datasource Templating Variables.
+ */
+ AmbariMetricsDatasource.prototype.metricFindQuery = function (query) {
+ var interpolated;
+ try {
+ interpolated = templateSrv.replace(query);
+ } catch (err) {
+ return $q.reject(err);
+ }
+ return this.doAmbariRequest({
+ method: 'GET',
+ url: '/ws/v1/timeline/metrics/' + interpolated
+ })
+ .then(function (results) {
+ //Remove fakehostname from the list of hosts on the cluster.
+ var fake = "fakehostname"; delete results.data[fake];
+ return _.map(_.keys(results.data), function (hostName) {
+ return {
+ text: hostName,
+ expandable: hostName.expandable ? true : false
+ };
+ });
+ });
+ };
+
+ /**
* AMS Datasource - Test Data Source Connection.
*
* Added Check to see if Datasource is working. Throws up an error in the
@@ -277,6 +267,7 @@ define([
console.log(query);
return this.doAmbariRequest({method: 'GET', url: '/ws/v1/timeline/metrics/hosts'})
.then(function (results) {
+ //Remove fakehostname from the list of hosts on the cluster.
var fake = "fakehostname"; delete results.data[fake];
return _.map(Object.keys(results.data), function (hostName) {
return {text: hostName};
@@ -301,4 +292,4 @@ define([
return AmbariMetricsDatasource;
});
}
-);
+); \ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
index d4dffb4bdf..f51866e626 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
@@ -82,10 +82,10 @@
</li>
- <li class="tight-form-item" style="width: 86px">
- Hosts <a bs-tooltip="'if host is selected, aggregator is ignored.'" data-placement="bottom"><i class="fa fa-info-circle"></i></a>
+ <li class="tight-form-item" style="width: 86px" ng-hide="dashboard.templating.list.length > 0">
+ Hosts
</li>
- <li>
+ <li ng-hide="dashboard.templating.list.length > 0">
<input type="text" class="input-large tight-form-input" ng-model="target.hosts"
spellcheck='false' bs-typeahead="suggestHosts" placeholder="host name" data-min-length=0 data-items=100
ng-blur="targetBlur()">
diff --git a/ambari-metrics/ambari-metrics-grafana/pom.xml b/ambari-metrics/ambari-metrics-grafana/pom.xml
index 8304416ccc..c737b2b026 100644
--- a/ambari-metrics/ambari-metrics-grafana/pom.xml
+++ b/ambari-metrics/ambari-metrics-grafana/pom.xml
@@ -103,16 +103,12 @@
dest="${project.build.directory}/grafana"
compression="gzip"
/>
- <get
- src="${ambari-grafana.tar}"
- dest="${project.build.directory}/grafana/ambari-grafana.tgz"
- usetimestamp="true"
- />
- <untar
- src="${project.build.directory}/grafana/ambari-grafana.tgz"
- dest="${project.build.directory}/grafana/${grafana.folder}/public/app/plugins/datasource"
- compression="gzip"
- />
+ <copy
+ todir="${project.build.directory}/grafana/${grafana.folder}/public/app/plugins/datasource">
+ <fileset dir="${project.build.directory}/../">
+ <include name="ambari-metrics/"/>
+ </fileset>
+ </copy>
</target>
</configuration>
</execution>
diff --git a/ambari-metrics/ambari-metrics-grafana/screenshots/20-templating.png b/ambari-metrics/ambari-metrics-grafana/screenshots/20-templating.png
new file mode 100644
index 0000000000..71b8b9f87d
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/screenshots/20-templating.png
Binary files differ
diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java
index 5ee8b44480..b5ec6e8d83 100644
--- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java
+++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/HBaseTimelineMetricStore.java
@@ -143,14 +143,16 @@ public class HBaseTimelineMetricStore extends AbstractService implements Timelin
aggregatorDailyThread.start();
}
- int initDelay = configuration.getTimelineMetricsServiceWatcherInitDelay();
- int delay = configuration.getTimelineMetricsServiceWatcherDelay();
- // Start the watchdog
- executorService.scheduleWithFixedDelay(
- new TimelineMetricStoreWatcher(this, configuration), initDelay, delay,
- TimeUnit.SECONDS);
- LOG.info("Started watchdog for timeline metrics store with initial " +
- "delay = " + initDelay + ", delay = " + delay);
+ if (!configuration.isTimelineMetricsServiceWatcherDisabled()) {
+ int initDelay = configuration.getTimelineMetricsServiceWatcherInitDelay();
+ int delay = configuration.getTimelineMetricsServiceWatcherDelay();
+ // Start the watchdog
+ executorService.scheduleWithFixedDelay(
+ new TimelineMetricStoreWatcher(this, configuration), initDelay, delay,
+ TimeUnit.SECONDS);
+ LOG.info("Started watchdog for timeline metrics store with initial " +
+ "delay = " + initDelay + ", delay = " + delay);
+ }
isInitialized = true;
}
diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java
index 7fa1d2dc16..1c86ebb53b 100644
--- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java
+++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/PhoenixHBaseAccessor.java
@@ -221,14 +221,14 @@ public class PhoenixHBaseAccessor {
String encoding = metricsConf.get(HBASE_ENCODING_SCHEME, DEFAULT_ENCODING);
String compression = metricsConf.get(HBASE_COMPRESSION_SCHEME, DEFAULT_TABLE_COMPRESSION);
- String precisionTtl = metricsConf.get(PRECISION_TABLE_TTL, "86400"); //1 day
- String hostMinTtl = metricsConf.get(HOST_MINUTE_TABLE_TTL, "604800"); //7 days
- String hostHourTtl = metricsConf.get(HOST_HOUR_TABLE_TTL, "2592000"); //30 days
- String hostDailyTtl = metricsConf.get(HOST_DAILY_TABLE_TTL, "31536000"); //1 year
- String clusterSecTtl = metricsConf.get(CLUSTER_SECOND_TABLE_TTL, "2592000"); //7 days
- String clusterMinTtl = metricsConf.get(CLUSTER_MINUTE_TABLE_TTL, "7776000"); //30 days
- String clusterHourTtl = metricsConf.get(CLUSTER_HOUR_TABLE_TTL, "31536000"); //1 year
- String clusterDailyTtl = metricsConf.get(CLUSTER_DAILY_TABLE_TTL, "63072000"); //2 years
+ String precisionTtl = getDaysInSeconds(metricsConf.get(PRECISION_TABLE_TTL, "1")); //1 day
+ String hostMinTtl = getDaysInSeconds(metricsConf.get(HOST_MINUTE_TABLE_TTL, "7")); //7 days
+ String hostHourTtl = getDaysInSeconds(metricsConf.get(HOST_HOUR_TABLE_TTL, "30")); //30 days
+ String hostDailyTtl = getDaysInSeconds(metricsConf.get(HOST_DAILY_TABLE_TTL, "365")); //1 year
+ String clusterSecTtl = getDaysInSeconds(metricsConf.get(CLUSTER_SECOND_TABLE_TTL, "7")); //7 days
+ String clusterMinTtl = getDaysInSeconds(metricsConf.get(CLUSTER_MINUTE_TABLE_TTL, "30")); //30 days
+ String clusterHourTtl = getDaysInSeconds(metricsConf.get(CLUSTER_HOUR_TABLE_TTL, "365")); //1 year
+ String clusterDailyTtl = getDaysInSeconds(metricsConf.get(CLUSTER_DAILY_TABLE_TTL, "730")); //2 years
try {
LOG.info("Initializing metrics schema...");
@@ -1255,4 +1255,9 @@ public class PhoenixHBaseAccessor {
return metadataMap;
}
+
+ private String getDaysInSeconds(String daysString) {
+ double days = Double.valueOf(daysString.trim());
+ return String.valueOf((int)(days*86400));
+ }
}
diff --git a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TimelineMetricConfiguration.java b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TimelineMetricConfiguration.java
index 46f61fbc74..cc9a2f368c 100644
--- a/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TimelineMetricConfiguration.java
+++ b/ambari-metrics/ambari-metrics-timelineservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/metrics/timeline/TimelineMetricConfiguration.java
@@ -181,6 +181,9 @@ public class TimelineMetricConfiguration {
public static final String HANDLER_THREAD_COUNT =
"timeline.metrics.service.handler.thread.count";
+ public static final String WATCHER_DISABLED =
+ "timeline.metrics.service.watcher.disabled";
+
public static final String WATCHER_INITIAL_DELAY =
"timeline.metrics.service.watcher.initial.delay";
@@ -273,6 +276,13 @@ public class TimelineMetricConfiguration {
return 20;
}
+ public boolean isTimelineMetricsServiceWatcherDisabled() {
+ if (metricsConf != null) {
+ return Boolean.parseBoolean(metricsConf.get(WATCHER_DISABLED, "false"));
+ }
+ return false;
+ }
+
public int getTimelineMetricsServiceWatcherInitDelay() {
if (metricsConf != null) {
return Integer.parseInt(metricsConf.get(WATCHER_INITIAL_DELAY, "600"));
diff --git a/ambari-metrics/pom.xml b/ambari-metrics/pom.xml
index 9a39122dfc..1f8768328c 100644
--- a/ambari-metrics/pom.xml
+++ b/ambari-metrics/pom.xml
@@ -52,7 +52,6 @@
<hadoop.winpkg.folder>hadoop-2.6.0.2.2.4.2-0002</hadoop.winpkg.folder>
<grafana.folder>grafana-2.6.0</grafana.folder>
<grafana.tar>https://grafanarel.s3.amazonaws.com/builds/grafana-2.6.0.linux-x64.tar.gz</grafana.tar>
- <ambari-grafana.tar>https://github.com/u39kun/ambari-grafana/raw/master/dist/ambari-grafana.tgz</ambari-grafana.tar>
<resmonitor.install.dir>
/usr/lib/python2.6/site-packages/resource_monitoring
</resmonitor.install.dir>
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index f19ca14db0..ed940044df 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -220,7 +220,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>14.0.1</version>
+ <version>16.0</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index b500fb2a80..51fd88b458 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1179,11 +1179,6 @@
<version>4.2.5</version>
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>14.0.1</version>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
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 210fe176c7..248ce4bb70 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
@@ -989,7 +989,44 @@ public class HeartBeatHandler {
if(response.getAgentConfig() != null) {
LOG.debug("Agent configuration map set to " + response.getAgentConfig());
}
- response.setRecoveryConfig(RecoveryConfig.getRecoveryConfig(config));
+
+ //
+ // Filter the enabled components by maintenance mode
+ //
+
+ // Build a map of component name => Service component host
+ // for easy look up of maintenance state by component name.
+ // As of now, a host can belong to only one cluster.
+ // Clusters::getClustersForHost(hostname) returns one item.
+ Map<String, ServiceComponentHost> schFromComponentName = new HashMap<>();
+
+ for (Cluster cl : clusterFsm.getClustersForHost(hostname)) {
+ List<ServiceComponentHost> scHosts = cl.getServiceComponentHosts(hostname);
+ for (ServiceComponentHost sch : scHosts) {
+ schFromComponentName.put(sch.getServiceComponentName(), sch);
+ }
+ }
+
+ // Keep only the components that have maintenance state set to OFF
+ List<String> enabledComponents = new ArrayList<>();
+ String[] confEnabledComponents = config.getEnabledComponents().split(",");
+
+ for (String componentName : confEnabledComponents) {
+ ServiceComponentHost sch = schFromComponentName.get(componentName);
+
+ // Append the component name only if it is
+ // in the host and not in maintenance mode.
+ if (sch != null && sch.getMaintenanceState() == MaintenanceState.OFF) {
+ enabledComponents.add(componentName);
+ }
+ }
+
+ // Overwrite the pre-constructed RecoveryConfig's list of
+ // enabled components with the filtered list
+ RecoveryConfig rc = RecoveryConfig.getRecoveryConfig(config);
+ rc.setEnabledComponents(StringUtils.join(enabledComponents, ','));
+ response.setRecoveryConfig(rc);
+
if(response.getRecoveryConfig() != null) {
LOG.info("Recovery configuration set to " + response.getRecoveryConfig().toString());
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
index 3f558ebb4a..3da86092ff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java
@@ -48,21 +48,9 @@ public class RecoveryConfig {
@SerializedName("maxLifetimeCount")
private String maxLifetimeCount;
- @SerializedName("enabledComponents")
+ @SerializedName("components")
private String enabledComponents;
- @SerializedName("disabledComponents")
- private String disabledComponents;
-
-
- public String getDisabledComponents() {
- return disabledComponents;
- }
-
- public void setDisabledComponents(String disabledComponents) {
- this.disabledComponents = disabledComponents;
- }
-
public String getEnabledComponents() {
return enabledComponents;
}
@@ -118,7 +106,6 @@ public class RecoveryConfig {
rc.setRetryGap(conf.getNodeRecoveryRetryGap());
rc.setType(conf.getNodeRecoveryType());
rc.setWindowInMinutes(conf.getNodeRecoveryWindowInMin());
- rc.setDisabledComponents(conf.getDisabledComponents());
rc.setEnabledComponents(conf.getEnabledComponents());
return rc;
}
@@ -131,8 +118,7 @@ public class RecoveryConfig {
buffer.append(", windowInMinutes=").append(windowInMinutes);
buffer.append(", retryGap=").append(retryGap);
buffer.append(", maxLifetimeCount=").append(maxLifetimeCount);
- buffer.append(", disabledComponents=").append(disabledComponents);
- buffer.append(", enabledComponents=").append(enabledComponents);
+ buffer.append(", components=").append(enabledComponents);
buffer.append('}');
return buffer.toString();
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcher.java
index 092aaf4ba4..907588dc47 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcher.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcher.java
@@ -40,6 +40,8 @@ import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.escape.Escaper;
+import com.google.common.escape.Escapers;
import com.google.inject.Inject;
/**
@@ -82,6 +84,18 @@ public class AlertScriptDispatcher implements NotificationDispatcher {
private static final long DEFAULT_SCRIPT_TIMEOUT = 5000L;
/**
+ * Used to escape text being passed into the shell command.
+ */
+ public static final Escaper SHELL_ESCAPE;
+
+ static {
+ final Escapers.Builder builder = Escapers.builder();
+ builder.addEscape('\"', "\\\"");
+ builder.addEscape('!', "\\!");
+ SHELL_ESCAPE = builder.build();
+ }
+
+ /**
* Configuration data from the ambari.properties file.
*/
@Inject
@@ -242,8 +256,8 @@ public class AlertScriptDispatcher implements NotificationDispatcher {
// these could have spaces in them, so quote them so they don't mess up the
// command line
- String alertLabel = "\"" + definition.getLabel() + "\"";
- String alertText = "\"" + alertInfo.getAlertText() + "\"";
+ String alertLabel = "\"" + SHELL_ESCAPE.escape(definition.getLabel()) + "\"";
+ String alertText = "\"" + SHELL_ESCAPE.escape(alertInfo.getAlertText()) + "\"";
Object[] params = new Object[] { script, definitionName, alertLabel, serviceName,
alertState.name(), alertText };
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
index 3a88f37ae4..a27bc1d33b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
@@ -712,7 +712,7 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
*
* @param history
*/
- protected AlertInfo(AlertHistoryEntity history) {
+ public AlertInfo(AlertHistoryEntity history) {
m_history = history;
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/CachedAlertFlushService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/CachedAlertFlushService.java
index 72bf68ab73..2e38c9bc16 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/CachedAlertFlushService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/CachedAlertFlushService.java
@@ -76,7 +76,7 @@ public class CachedAlertFlushService extends AbstractScheduledService {
protected void startUp() throws Exception {
boolean enabled = m_configuration.isAlertCacheEnabled();
if (!enabled) {
- stop();
+ stopAsync();
}
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/JsonOsFamilyRoot.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/JsonOsFamilyRoot.java
new file mode 100644
index 0000000000..3f9158f807
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/JsonOsFamilyRoot.java
@@ -0,0 +1,38 @@
+/**
+ * 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.state.stack;
+
+import java.util.Map;
+
+public class JsonOsFamilyRoot {
+ private Map<String, JsonOsFamilyEntry> mapping;
+ private Map<String, String> aliases;
+
+ public Map<String, JsonOsFamilyEntry> getMapping() {
+ return mapping;
+ }
+ public void setMapping(Map<String, JsonOsFamilyEntry> mapping) {
+ this.mapping = mapping;
+ }
+ public Map<String, String> getAliases() {
+ return aliases;
+ }
+ public void setAliases(Map<String, String> aliases) {
+ this.aliases = aliases;
+ }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
index 37a6db3c36..e494c4421b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
@@ -48,11 +48,14 @@ public class OsFamily {
private final String os_pattern = "([\\D]+|(?:[\\D]+[\\d]+[\\D]+))([\\d]*)";
private final String OS_DISTRO = "distro";
private final String OS_VERSION = "versions";
+ private final String OS_MAPPING = "mapping";
+ private final String OS_ALIASES = "aliases";
private final String LOAD_CONFIG_MSG = "Could not load OS family definition from %s file";
private final String FILE_NAME = "os_family.json";
private final Logger LOG = LoggerFactory.getLogger(OsFamily.class);
private Map<String, JsonOsFamilyEntry> osMap = null;
+ private JsonOsFamilyRoot jsonOsFamily = null;
/**
* Initialize object
@@ -77,9 +80,10 @@ public class OsFamily {
if (!f.exists()) throw new Exception();
inputStream = new FileInputStream(f);
- Type type = new TypeToken<Map<String, JsonOsFamilyEntry>>() {}.getType();
+ Type type = new TypeToken<JsonOsFamilyRoot>() {}.getType();
Gson gson = new Gson();
- osMap = gson.fromJson(new InputStreamReader(inputStream), type);
+ jsonOsFamily = gson.fromJson(new InputStreamReader(inputStream), type);
+ osMap = jsonOsFamily.getMapping();
} catch (Exception e) {
LOG.error(String.format(LOAD_CONFIG_MSG, new File(SharedResourcesPath, FILE_NAME).toString()));
throw new RuntimeException(e);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog222.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog222.java
index 7e2683d9ee..88b3151fbc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog222.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog222.java
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
/**
* Upgrade catalog for version 2.2.2.
@@ -52,8 +53,16 @@ public class UpgradeCatalog222 extends AbstractUpgradeCatalog {
"timeline.metrics.host.aggregator.daily.checkpointCutOffMultiplier";
private static final String CLUSTER_AGGREGATOR_DAILY_CHECKPOINTCUTOFFMULTIPIER =
"timeline.metrics.cluster.aggregator.daily.checkpointCutOffMultiplier";
-
-
+ private static final String TIMELINE_METRICS_SERVICE_WATCHER_DISBALED = "timeline.metrics.service.watcher.disabled";
+ private static final String AMS_MODE = "timeline.metrics.service.operation.mode";
+ public static final String PRECISION_TABLE_TTL = "timeline.metrics.host.aggregator.ttl";
+ public static final String HOST_MINUTE_TABLE_TTL = "timeline.metrics.host.aggregator.minute.ttl";
+ public static final String HOST_HOUR_TABLE_TTL = "timeline.metrics.host.aggregator.hourly.ttl";
+ public static final String HOST_DAILY_TABLE_TTL = "timeline.metrics.host.aggregator.daily.ttl";
+ public static final String CLUSTER_SECOND_TABLE_TTL = "timeline.metrics.cluster.aggregator.second.ttl";
+ public static final String CLUSTER_MINUTE_TABLE_TTL = "timeline.metrics.cluster.aggregator.minute.ttl";
+ public static final String CLUSTER_HOUR_TABLE_TTL = "timeline.metrics.cluster.aggregator.hourly.ttl";
+ public static final String CLUSTER_DAILY_TABLE_TTL = "timeline.metrics.cluster.aggregator.daily.ttl";
// ----- Constructors ------------------------------------------------------
@@ -175,6 +184,94 @@ public class UpgradeCatalog222 extends AbstractUpgradeCatalog {
}
+ if (!amsSiteProperties.containsKey(TIMELINE_METRICS_SERVICE_WATCHER_DISBALED)) {
+ LOG.info("Add config " + TIMELINE_METRICS_SERVICE_WATCHER_DISBALED + " = false");
+ newProperties.put(TIMELINE_METRICS_SERVICE_WATCHER_DISBALED, String.valueOf(false));
+ }
+
+ boolean isDistributed = false;
+ if ("distributed".equals(amsSite.getProperties().get(AMS_MODE))) {
+ isDistributed = true;
+ }
+
+ if (amsSiteProperties.containsKey(PRECISION_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(PRECISION_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ if (isDistributed) {
+ if ("86400".equals(oldTtl)) {
+ newTtl = "7.0"; // 7 days
+ }
+ }
+ newProperties.put(PRECISION_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + PRECISION_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(HOST_MINUTE_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(HOST_MINUTE_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(HOST_MINUTE_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + HOST_MINUTE_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(HOST_MINUTE_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(HOST_MINUTE_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(HOST_MINUTE_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + HOST_MINUTE_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(HOST_HOUR_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(HOST_HOUR_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(HOST_HOUR_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + HOST_HOUR_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(HOST_DAILY_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(HOST_DAILY_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(HOST_DAILY_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + HOST_DAILY_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(CLUSTER_SECOND_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(CLUSTER_SECOND_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+
+ if ("2592000".equals(oldTtl)) {
+ newTtl = "7.0"; // 7 days
+ }
+
+ newProperties.put(CLUSTER_SECOND_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + CLUSTER_SECOND_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(CLUSTER_MINUTE_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(CLUSTER_MINUTE_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+
+ if ("7776000".equals(oldTtl)) {
+ newTtl = "30.0"; // 30 days
+ }
+
+ newProperties.put(CLUSTER_MINUTE_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + CLUSTER_MINUTE_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(CLUSTER_HOUR_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(CLUSTER_HOUR_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(CLUSTER_HOUR_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + CLUSTER_HOUR_TABLE_TTL + " : " + newTtl);
+ }
+
+ if (amsSiteProperties.containsKey(CLUSTER_DAILY_TABLE_TTL)) {
+ String oldTtl = amsSiteProperties.get(CLUSTER_DAILY_TABLE_TTL);
+ String newTtl = convertToDaysIfInSeconds(oldTtl);
+ newProperties.put(CLUSTER_DAILY_TABLE_TTL, newTtl);
+ LOG.info("Setting value of " + CLUSTER_DAILY_TABLE_TTL + " : " + newTtl);
+ }
+
updateConfigurationPropertiesForCluster(cluster, AMS_SITE, newProperties, true, true);
}
@@ -183,4 +280,19 @@ public class UpgradeCatalog222 extends AbstractUpgradeCatalog {
}
}
+ private String convertToDaysIfInSeconds(String secondsString) {
+
+ int seconds = Integer.valueOf(secondsString);
+ double days = 0.0;
+
+ if (seconds >= 86400) {
+ days += TimeUnit.SECONDS.toDays(seconds);
+ }
+
+ days += ((float)seconds % 86400.0) / 86400.0;
+ days = Math.round(days * 100.0)/100.0;
+
+ return String.valueOf(days);
+ }
+
}
diff --git a/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/configuration/accumulo-site.xml b/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/configuration/accumulo-site.xml
index 2e7576823e..c2e0200924 100644
--- a/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/configuration/accumulo-site.xml
+++ b/ambari-server/src/main/resources/common-services/ACCUMULO/1.6.1.2.2.0/configuration/accumulo-site.xml
@@ -24,6 +24,7 @@
<property>
<name>instance.volumes</name>
<value>hdfs://localhost:8020/apps/accumulo/data</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Location of Accumulo data files in HDFS.</description>
<value-attributes>
<overridable>false</overridable>
@@ -33,6 +34,7 @@
<property>
<name>instance.zookeeper.host</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Comma-separated list of ZooKeeper server:port
pairs.</description>
<value-attributes>
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-site.xml b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-site.xml
index a3f0028000..180b43bb71 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-site.xml
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-site.xml
@@ -283,59 +283,65 @@
</property>
<property>
<name>timeline.metrics.host.aggregator.daily.ttl</name>
- <value>31536000</value>
+ <value>365</value>
<description>
Host based daily resolution data purge interval. Default is 1 year.
</description>
</property>
<property>
<name>timeline.metrics.host.aggregator.hourly.ttl</name>
- <value>2592000</value>
+ <value>30</value>
<description>
Host based hourly resolution data purge interval. Default is 30 days.
</description>
</property>
<property>
<name>timeline.metrics.host.aggregator.minute.ttl</name>
- <value>604800</value>
+ <value>7</value>
<description>
Host based minute resolution data purge interval. Default is 7 days.
</description>
</property>
<property>
<name>timeline.metrics.cluster.aggregator.second.ttl</name>
- <value>2592000</value>
+ <value>7</value>
<description>
Cluster wide second resolution data purge interval. Default is 7 days.
</description>
</property>
<property>
<name>timeline.metrics.cluster.aggregator.minute.ttl</name>
- <value>7776000</value>
+ <value>30</value>
<description>
Cluster wide minute resolution data purge interval. Default is 30 days.
</description>
</property>
<property>
<name>timeline.metrics.cluster.aggregator.hourly.ttl</name>
- <value>31536000</value>
+ <value>365</value>
<description>
Cluster wide hourly resolution data purge interval. Default is 1 year.
</description>
</property>
<property>
<name>timeline.metrics.cluster.aggregator.daily.ttl</name>
- <value>63072000</value>
+ <value>730</value>
<description>
Cluster wide daily resolution data purge interval. Default is 2 years.
</description>
</property>
<property>
<name>timeline.metrics.host.aggregator.ttl</name>
- <value>86400</value>
+ <value>1</value>
<description>
- 1 minute resolution data purge interval. Default is 1 day.
+ 1 minute resolution data purge interval. Default is 1 day for embedded mode and 7 days for Distributed mode.
</description>
+ <depends-on>
+ <property>
+ <type>ams-site</type>
+ <name>timeline.metrics.service.operation.mode</name>
+ </property>
+ </depends-on>
</property>
<property>
<name>timeline.metrics.hbase.data.block.encoding</name>
@@ -495,6 +501,19 @@
</description>
</property>
<property>
+ <name>timeline.metrics.service.watcher.disabled</name>
+ <value>false</value>
+ <description>
+ Disable Timeline Metric Store watcher thread. Disabled by default in AMS distributed mode.
+ </description>
+ <depends-on>
+ <property>
+ <type>ams-site</type>
+ <name>timeline.metrics.service.operation.mode</name>
+ </property>
+ </depends-on>
+ </property>
+ <property>
<name>timeline.metrics.service.watcher.initial.delay</name>
<value>600</value>
<description>
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 c3dbc6b00b..3a832eb99c 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
@@ -83,6 +83,7 @@
<package>
<name>ambari-metrics-collector</name>
<skipUpgrade>true</skipUpgrade>
+ <condition>should_install_ams_collector</condition>
</package>
<package>
<name>ambari-metrics-monitor</name>
@@ -95,6 +96,7 @@
<package>
<name>ambari-metrics-grafana</name>
<skipUpgrade>true</skipUpgrade>
+ <condition>should_install_ams_grafana</condition>
</package>
<package>
<name>gcc</name>
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_collector.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_collector.py
index ddefed7fad..533d3ec952 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_collector.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_collector.py
@@ -31,7 +31,9 @@ from ambari_commons.os_family_impl import OsFamilyImpl
class AmsCollector(Script):
def install(self, env):
- self.install_packages(env, exclude_packages = ['ambari-metrics-grafana'])
+ import params
+ env.set_params(params)
+ self.install_packages(env)
def configure(self, env, action = None):
import params
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana.py
index d96309c4dd..6dd60f56da 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana.py
@@ -26,7 +26,10 @@ from metrics_grafana_util import create_ams_datasource
class AmsGrafana(Script):
def install(self, env):
- self.install_packages(env, exclude_packages = ['ambari-metrics-collector'])
+ import params
+ env.set_params(params)
+ self.install_packages(env)
+ self.configure(env) # for security
def configure(self, env, action = None):
import params
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana_util.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana_util.py
index c4a91e121a..5ab40b02d2 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana_util.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_grafana_util.py
@@ -58,8 +58,9 @@ def create_ams_datasource():
Logger.info("Ambari Metrics Grafana datasource already present. Checking Metrics Collector URL")
datasource_url = datasources_json[i]["url"]
- if datasource_url == (params.metric_collector_host + ":" + params.metric_collector_port
- + "/ws/v1/timeline/metrics") :
+ if datasource_url == (params.ams_grafana_protocol + "://"
+ + params.metric_collector_host + ":"
+ + params.metric_collector_port):
Logger.info("Metrics Collector URL validation succeeded. Skipping datasource creation")
GRAFANA_CONNECT_TRIES = 0 # No need to create datasource again
@@ -84,6 +85,7 @@ def create_ams_datasource():
try:
ams_datasource_json = Template('metrics_grafana_datasource.json.j2',
ams_datasource_name=METRICS_GRAFANA_DATASOURCE_NAME,
+ ams_grafana_protocol=params.ams_grafana_protocol,
ams_collector_host=params.metric_collector_host,
ams_collector_port=params.metric_collector_port).get_content()
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_monitor.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_monitor.py
index 921bed7ac4..d98384ba1d 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_monitor.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/metrics_monitor.py
@@ -27,7 +27,7 @@ class AmsMonitor(Script):
def install(self, env):
import params
env.set_params(params)
- self.install_packages(env, exclude_packages = ['ambari-metrics-collector', 'ambari-metrics-grafana'])
+ self.install_packages(env)
self.configure(env) # for security
def configure(self, env):
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/templates/metrics_grafana_datasource.json.j2 b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/templates/metrics_grafana_datasource.json.j2
index 1b03a2d060..a803da5ba0 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/templates/metrics_grafana_datasource.json.j2
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/templates/metrics_grafana_datasource.json.j2
@@ -20,7 +20,7 @@
"name": "{{ams_datasource_name}}",
"type": "ambarimetrics",
"access": "proxy",
- "url": "{{ams_collector_host}}:{{ams_collector_port}}/ws/v1/timeline/metrics",
+ "url": "{{ams_grafana_protocol}}://{{ams_collector_host}}:{{ams_collector_port}}",
"password": "",
"user": "",
"database": "",
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/configuration/application-properties.xml b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/configuration/application-properties.xml
index 74b1537305..ed9f1bc7f9 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/configuration/application-properties.xml
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/configuration/application-properties.xml
@@ -102,6 +102,7 @@
<property>
<name>atlas.server.bind.address</name>
<value>localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
</property>
<property>
diff --git a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/configuration/falcon-startup.properties.xml b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/configuration/falcon-startup.properties.xml
index 66a297c8c5..431d9632e3 100644
--- a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/configuration/falcon-startup.properties.xml
+++ b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/configuration/falcon-startup.properties.xml
@@ -120,6 +120,7 @@
<property>
<name>*.broker.url</name>
<value>tcp://localhost:61616</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Default Active MQ url</description>
</property>
<property>
diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/metainfo.xml
index 21ab4459b8..ce625eb33d 100644
--- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/metainfo.xml
@@ -76,6 +76,16 @@
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
+ <customCommands>
+ <customCommand>
+ <name>ACTIVATE_STANDBY</name>
+ <commandScript>
+ <script>scripts/hawqstandby.py</script>
+ <scriptType>PYTHON</scriptType>
+ <timeout>1200</timeout>
+ </commandScript>
+ </customCommand>
+ </customCommands>
<dependencies>
<dependency>
<name>HDFS/HDFS_CLIENT</name>
diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawq_constants.py b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawq_constants.py
index 01de99a773..6a2d9ba43f 100644
--- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawq_constants.py
+++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawq_constants.py
@@ -27,6 +27,7 @@ YARN = "yarn"
CLUSTER = "cluster"
IMMEDIATE = "immediate"
FAST = "fast"
+ACTIVATE = "activate"
# Users
root_user = "root"
diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawqstandby.py b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawqstandby.py
index 7f5bab4e93..7da7f6df8a 100644
--- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawqstandby.py
+++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/package/scripts/hawqstandby.py
@@ -51,8 +51,10 @@ class HawqStandby(Script):
from hawqstatus import get_pid_file
check_process_status(get_pid_file())
- def activatestandby(self, env):
- pass
+ def activate_standby(self, env):
+ import utils
+ utils.exec_hawq_operation(hawq_constants.ACTIVATE, "{0} -a -M {1} -v".format(hawq_constants.STANDBY, hawq_constants.FAST))
+
if __name__ == "__main__":
HawqStandby().execute()
diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/configuration/hbase-site.xml b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/configuration/hbase-site.xml
index 4fefb1e511..3575bf2f8e 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/configuration/hbase-site.xml
+++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/configuration/hbase-site.xml
@@ -23,6 +23,7 @@
<property>
<name>hbase.rootdir</name>
<value>hdfs://localhost:8020/apps/hbase/data</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The directory shared by region servers and into
which HBase persists. The URL should be 'fully-qualified'
to include the filesystem scheme. For example, to specify the
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
index 4d73250e8a..d216605224 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/core-site.xml
@@ -59,6 +59,7 @@
<name>fs.defaultFS</name>
<!-- cluster variant -->
<value>hdfs://localhost:8020</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The name of the default file system. Either the
literal string "local" or a host:port for HDFS.</description>
<final>true</final>
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
index ea5514da55..260fe65130 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/configuration/hdfs-site.xml
@@ -255,6 +255,7 @@
<property>
<name>dfs.namenode.http-address</name>
<value>localhost:50070</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The name of the default file system. Either the
literal string "local" or a host:port for HDFS.</description>
<final>true</final>
@@ -366,6 +367,7 @@
<!-- cluster variant -->
<name>dfs.namenode.secondary.http-address</name>
<value>localhost:50090</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Address of secondary namenode web server</description>
</property>
@@ -373,6 +375,7 @@
<property>
<name>dfs.namenode.https-address</name>
<value>localhost:50470</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The https address where namenode binds</description>
</property>
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
index 80da3a1955..4087c72cbe 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
@@ -46,6 +46,7 @@ limitations under the License.
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive?createDatabaseIfNotExist=true</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<display-name>Database URL</display-name>
<description>JDBC connect string for a JDBC metastore</description>
<value-attributes>
@@ -124,6 +125,7 @@ limitations under the License.
<property>
<name>hive.metastore.uris</name>
<value>thrift://localhost:9083</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>URI for client to contact metastore server</description>
</property>
@@ -444,6 +446,7 @@ limitations under the License.
<property>
<name>atlas.rest.address</name>
<value>http://localhost:21000</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<depends-on>
<property>
<type>application-properties</type>
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/webhcat-site.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/webhcat-site.xml
index 72a57105b2..be2f22133b 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/webhcat-site.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/webhcat-site.xml
@@ -117,6 +117,7 @@ limitations under the License.
<property>
<name>templeton.zookeeper.hosts</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>ZooKeeper servers, as comma separated host:port pairs</description>
<value-attributes>
<type>multiLine</type>
diff --git a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/configuration/kafka-broker.xml b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/configuration/kafka-broker.xml
index b23075d39b..6d0c8c662a 100644
--- a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/configuration/kafka-broker.xml
+++ b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/configuration/kafka-broker.xml
@@ -45,6 +45,7 @@
<property>
<name>zookeeper.connect</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
Zookeeper also allows you to add a "chroot" path which will make all kafka data for this cluster appear under a particular path.
This is a way to setup multiple Kafka clusters or other applications on the same zookeeper cluster. To do this give a connection
@@ -295,6 +296,7 @@
<property>
<name>kafka.ganglia.metrics.host</name>
<value>localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description> Ganglia host </description>
</property>
<property>
diff --git a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/configuration/ranger-knox-plugin-properties.xml b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/configuration/ranger-knox-plugin-properties.xml
index 0ab649cd61..eef1daf9af 100644
--- a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/configuration/ranger-knox-plugin-properties.xml
+++ b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/configuration/ranger-knox-plugin-properties.xml
@@ -113,6 +113,7 @@
<property>
<name>XAAUDIT.HDFS.DESTINATION_DIRECTORY</name>
<value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
<depends-on>
<property>
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/configuration/oozie-site.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/configuration/oozie-site.xml
index 5a188758d5..4a8e60c673 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/configuration/oozie-site.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/configuration/oozie-site.xml
@@ -26,6 +26,7 @@
<property>
<name>oozie.base.url</name>
<value>http://localhost:11000/oozie</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Base Oozie URL.</description>
</property>
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/configuration/oozie-site.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/configuration/oozie-site.xml
index 2ecc0ca4c1..107816dc0e 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/configuration/oozie-site.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/configuration/oozie-site.xml
@@ -35,6 +35,7 @@
<property>
<name>oozie.base.url</name>
<value>http://localhost:11000/oozie</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Base Oozie URL.</description>
</property>
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
index 0cffae0365..d73272d3b3 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
@@ -268,6 +268,7 @@
<property>
<name>xasecure.audit.destination.hdfs.dir</name>
<value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<display-name>Destination HDFS Directory</display-name>
<description>HDFS folder to write audit to, make sure all service user has required permissions. This property is overridable at service level</description>
<depends-on>
diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/configuration/kms-site.xml b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/configuration/kms-site.xml
index 889e3107c2..e559d92900 100644
--- a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/configuration/kms-site.xml
+++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/configuration/kms-site.xml
@@ -23,6 +23,7 @@
<property>
<name>hadoop.kms.key.provider.uri</name>
<value>dbks://http@localhost:9292/kms</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>URI of the backing KeyProvider for the KMS.</description>
</property>
diff --git a/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/configuration/storm-site.xml b/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/configuration/storm-site.xml
index 4719dbb4af..aada3632fc 100644
--- a/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/configuration/storm-site.xml
+++ b/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/configuration/storm-site.xml
@@ -42,6 +42,7 @@
<property>
<name>storm.zookeeper.servers</name>
<value>['localhost']</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>A list of hosts of ZooKeeper servers used to manage the cluster.</description>
<value-attributes>
<type>multiLine</type>
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
index 5737c4d47d..f30b807a17 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
@@ -257,12 +257,14 @@
<property>
<name>mapreduce.jobhistory.address</name>
<value>localhost:10020</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Enter your JobHistoryServer hostname.</description>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>localhost:19888</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Enter your JobHistoryServer hostname.</description>
</property>
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
index 802a1f5d0b..59d4964615 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration/yarn-site.xml
@@ -26,24 +26,28 @@
<property>
<name>yarn.resourcemanager.hostname</name>
<value>localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The hostname of the RM.</description>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>localhost:8025</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description> The address of ResourceManager. </description>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>localhost:8030</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The address of the scheduler interface.</description>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>localhost:8050</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
The address of the applications manager interface in the
RM.
@@ -53,6 +57,7 @@
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>localhost:8141</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The address of the RM admin interface.</description>
</property>
@@ -372,6 +377,7 @@
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>localhost:8088</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
The address of the RM web application.
</description>
@@ -380,6 +386,7 @@
<property>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>localhost:8090</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
The https address of the RM web application.
</description>
@@ -396,6 +403,7 @@
<property>
<name>yarn.log.server.url</name>
<value>http://localhost:19888/jobhistory/logs</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
URI for the HistoryServer's log resource
</description>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
index a53dd8b80b..af21008794 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
@@ -507,8 +507,12 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
operatingMode = services["configurations"]["ams-site"]["properties"]["timeline.metrics.service.operation.mode"]
if operatingMode == "distributed":
+ putAmsSiteProperty("timeline.metrics.service.watcher.disabled", 'true')
+ putAmsSiteProperty("timeline.metrics.host.aggregator.ttl", 7)
putAmsHbaseSiteProperty("hbase.cluster.distributed", 'true')
else:
+ putAmsSiteProperty("timeline.metrics.service.watcher.disabled", 'false')
+ putAmsSiteProperty("timeline.metrics.host.aggregator.ttl", 1)
putAmsHbaseSiteProperty("hbase.cluster.distributed", 'false')
rootDir = "file:///var/lib/ambari-metrics-collector/hbase"
@@ -564,7 +568,6 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
putAmsHbaseSiteProperty("hbase.hregion.memstore.flush.size", 134217728)
putAmsHbaseSiteProperty("hbase.regionserver.global.memstore.upperLimit", 0.35)
putAmsHbaseSiteProperty("hbase.regionserver.global.memstore.lowerLimit", 0.3)
- putAmsSiteProperty("timeline.metrics.host.aggregator.ttl", 86400)
if len(amsCollectorHosts) > 1:
pass
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/configuration/hive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/configuration/hive-site.xml
index aad9ba5ccd..56dc017ff1 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/configuration/hive-site.xml
@@ -44,6 +44,7 @@ limitations under the License.
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive?createDatabaseIfNotExist=true</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<display-name>Database URL</display-name>
<description>JDBC connect string for a JDBC metastore</description>
<value-attributes>
@@ -120,6 +121,7 @@ limitations under the License.
<property>
<name>hive.metastore.uris</name>
<value>thrift://localhost:9083</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>URI for client to contact metastore server</description>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/OOZIE/configuration/oozie-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/services/OOZIE/configuration/oozie-site.xml
index af1a0a8373..b4d29658df 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/OOZIE/configuration/oozie-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/OOZIE/configuration/oozie-site.xml
@@ -26,6 +26,7 @@
<property>
<name>oozie.base.url</name>
<value>http://localhost:11000/oozie</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Base Oozie URL.</description>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/services/YARN/configuration/yarn-site.xml
index 667c37439c..732cef18a2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/YARN/configuration/yarn-site.xml
@@ -61,6 +61,7 @@
<property>
<name>yarn.timeline-service.webapp.address</name>
<value>localhost:8188</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
The http address of the timeline service web application.
</description>
@@ -69,6 +70,7 @@
<property>
<name>yarn.timeline-service.webapp.https.address</name>
<value>localhost:8190</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
The http address of the timeline service web application.
</description>
@@ -77,6 +79,7 @@
<property>
<name>yarn.timeline-service.address</name>
<value>localhost:10200</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
This is default address for the timeline server to start
the RPC server.
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml
index 9decf51e71..dbf8506bff 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml
@@ -29,18 +29,6 @@
<reponame>HDP-UTILS</reponame>
</repo>
</os>
- <os family="amazon2015">
- <repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.2.6.0</baseurl>
- <repoid>HDP-2.2</repoid>
- <reponame>HDP</reponame>
- </repo>
- <repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6</baseurl>
- <repoid>HDP-UTILS-1.1.0.20</repoid>
- <reponame>HDP-UTILS</reponame>
- </repo>
- </os>
<os family="suse11">
<repo>
<baseurl>http://public-repo-1.hortonworks.com/HDP/suse11sp3/2.x/updates/2.2.6.0</baseurl>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/configuration/ranger-hbase-plugin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/configuration/ranger-hbase-plugin-properties.xml
index 4e871517a6..fb6de71a58 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/configuration/ranger-hbase-plugin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/configuration/ranger-hbase-plugin-properties.xml
@@ -106,6 +106,7 @@
<property>
<name>XAAUDIT.HDFS.DESTINATION_DIRECTORY</name>
<value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
<depends-on>
<property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/ranger-hdfs-plugin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/ranger-hdfs-plugin-properties.xml
index 8bb6369cdd..d8ab47aff6 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/ranger-hdfs-plugin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/ranger-hdfs-plugin-properties.xml
@@ -110,8 +110,8 @@
<property>
<name>XAAUDIT.HDFS.DESTINATION_DIRECTORY</name>
- <value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%
- </value>
+ <value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
<depends-on>
<property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-env.xml
index 87adb4baa8..471af6e987 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-env.xml
@@ -130,26 +130,6 @@ export METASTORE_PORT={{hive_metastore_port}}
</property>
<property>
- <name>cost_based_optimizer</name>
- <display-name>Cost Based Optimizer</display-name>
- <value>Off</value>
- <value-attributes>
- <type>value-list</type>
- <entries>
- <entry>
- <value>On</value>
- <label>On</label>
- </entry>
- <entry>
- <value>Off</value>
- <label>Off</label>
- </entry>
- </entries>
- <selection-cardinality>1</selection-cardinality>
- </value-attributes>
- </property>
-
- <property>
<name>hive_security_authorization</name>
<display-name>Choose Authorization</display-name>
<value>None</value>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-site.xml
index 35db348b03..25bb468f1d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/hive-site.xml
@@ -43,6 +43,7 @@ limitations under the License.
<property>
<name>hive.zookeeper.quorum</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>List of ZooKeeper servers to talk to. This is needed for: 1.
Read/write locks - when hive.lock.manager is set to
org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager,
@@ -114,6 +115,7 @@ limitations under the License.
<property>
<name>hive.cluster.delegation.token.store.zookeeper.connectString</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>The ZooKeeper token store connect string.</description>
</property>
@@ -345,6 +347,7 @@ limitations under the License.
<property>
<name>hive.metastore.uris</name>
<value>thrift://localhost:9083</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description>
</property>
@@ -363,6 +366,7 @@ limitations under the License.
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive?createDatabaseIfNotExist=true</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<display-name>Database URL</display-name>
<description>JDBC connect string for a JDBC metastore</description>
<value-attributes>
@@ -467,12 +471,6 @@ limitations under the License.
<name>hive.cbo.enable</name>
<value>true</value>
<description>Flag to control enabling Cost Based Optimizations using Calcite framework.</description>
- <depends-on>
- <property>
- <type>hive-env</type>
- <name>cost_based_optimizer</name>
- </property>
- </depends-on>
</property>
<property>
@@ -816,10 +814,6 @@ limitations under the License.
</value-attributes>
<depends-on>
<property>
- <type>hive-env</type>
- <name>cost_based_optimizer</name>
- </property>
- <property>
<type>hive-site</type>
<name>hive.cbo.enable</name>
</property>
@@ -851,10 +845,6 @@ limitations under the License.
</value-attributes>
<depends-on>
<property>
- <type>hive-env</type>
- <name>cost_based_optimizer</name>
- </property>
- <property>
<type>hive-site</type>
<name>hive.cbo.enable</name>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/ranger-hive-plugin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/ranger-hive-plugin-properties.xml
index a9ceb29c86..756e95390b 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/ranger-hive-plugin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/configuration/ranger-hive-plugin-properties.xml
@@ -95,6 +95,7 @@
<property>
<name>XAAUDIT.HDFS.DESTINATION_DIRECTORY</name>
<value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
<depends-on>
<property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/ranger-storm-plugin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/ranger-storm-plugin-properties.xml
index ef07f4f301..13acbffb63 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/ranger-storm-plugin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/ranger-storm-plugin-properties.xml
@@ -106,6 +106,7 @@
<property>
<name>XAAUDIT.HDFS.DESTINATION_DIRECTORY</name>
<value>hdfs://localhost:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description></description>
<depends-on>
<property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
index e75442f907..ee12ba3029 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
@@ -39,6 +39,7 @@
<property>
<name>hadoop.registry.zk.quorum</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
List of hostname:port pairs defining the zookeeper quorum binding for the registry
</description>
@@ -98,6 +99,7 @@
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>
List Host:Port of the ZooKeeper servers to be used by the RM. comma separated host:port pairs, each corresponding to a zk server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002" If the optional chroot suffix is used the example would look like: "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a" where the client would be rooted at "/app/a" and all paths would be relative to this root - ie getting/setting/etc... "/foo/bar" would result in operations being run on "/app/a/foo/bar" (from the server perspective).
</description>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
index 9e43865eff..dc968cc5d2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/stack_advisor.py
@@ -353,14 +353,11 @@ class HDP22StackAdvisor(HDP21StackAdvisor):
putHiveSiteProperty("hive.exec.reducers.bytes.per.reducer", "67108864")
# CBO
- putHiveEnvProperty("cost_based_optimizer", "On")
- if str(configurations["hive-env"]["properties"]["cost_based_optimizer"]).lower() == "on":
- putHiveSiteProperty("hive.cbo.enable", "true")
- else:
- putHiveSiteProperty("hive.cbo.enable", "false")
- hive_cbo_enable = configurations["hive-site"]["properties"]["hive.cbo.enable"]
- putHiveSiteProperty("hive.stats.fetch.partition.stats", hive_cbo_enable)
- putHiveSiteProperty("hive.stats.fetch.column.stats", hive_cbo_enable)
+ if "hive-site" in services["configurations"] and "hive.cbo.enable" in services["configurations"]["hive-site"]["properties"]:
+ hive_cbo_enable = services["configurations"]["hive-site"]["properties"]["hive.cbo.enable"]
+ putHiveSiteProperty("hive.stats.fetch.partition.stats", hive_cbo_enable)
+ putHiveSiteProperty("hive.stats.fetch.column.stats", hive_cbo_enable)
+
putHiveSiteProperty("hive.compute.query.using.stats", "true")
# Interactive Query
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml
index 279134b988..142b87d858 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/repos/repoinfo.xml
@@ -41,18 +41,6 @@
<reponame>HDP-UTILS</reponame>
</repo>
</os>
- <os family="amazon2015">
- <repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.3.0.0</baseurl>
- <repoid>HDP-2.3</repoid>
- <reponame>HDP</reponame>
- </repo>
- <repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6</baseurl>
- <repoid>HDP-UTILS-1.1.0.20</repoid>
- <reponame>HDP-UTILS</reponame>
- </repo>
- </os>
<os family="suse11">
<repo>
<baseurl>http://public-repo-1.hortonworks.com/HDP/suse11sp3/2.x/updates/2.3.0.0</baseurl>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/kafka-broker.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/kafka-broker.xml
index 8c2f34a938..6e924e2e8f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/kafka-broker.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/kafka-broker.xml
@@ -22,6 +22,7 @@
<property>
<name>listeners</name>
<value>PLAINTEXT://localhost:6667</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>host and port where kafka broker will be accepting connnections. localhost will be subsituted with hostname.</description>
</property>
<property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/ranger-kafka-plugin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/ranger-kafka-plugin-properties.xml
index 490e0592d9..18429a18c0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/ranger-kafka-plugin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/KAFKA/configuration/ranger-kafka-plugin-properties.xml
@@ -48,6 +48,7 @@
<property>
<name>zookeeper.connect</name>
<value>localhost:2181</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Used for repository creation on ranger admin</description>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
index 1e86e7d00e..dce8a90796 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
@@ -58,6 +58,7 @@
<display-name>JDBC connect string for root user</display-name>
<description>JDBC connect string - auto populated based on other values. This is to be used by root user</description>
<value>jdbc:mysql://localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<value-attributes>
<overridable>false</overridable>
</value-attributes>
@@ -187,6 +188,7 @@
<property>
<name>xasecure.audit.destination.hdfs.dir</name>
<value>hdfs://localhost:8020</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<display-name>Destination HDFS Directory</display-name>
<description>HDFS folder to write audit to, make sure all service user has required permissions. This property is overridable at service level</description>
<depends-on>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/STORM/configuration/storm-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/STORM/configuration/storm-site.xml
index ca6d2b6d10..6a5e6db70f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/STORM/configuration/storm-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/STORM/configuration/storm-site.xml
@@ -22,6 +22,7 @@
<property>
<name>nimbus.seeds</name>
<value>localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Comma-delimited list of the hosts running nimbus server.</description>
<value-attributes>
<type>componentHosts</type>
@@ -52,6 +53,7 @@
<property>
<name>nimbus.host</name>
<value>localhost</value>
+ <property-type>DONT_ADD_ON_UPGRADE</property-type>
<description>Deprecated config in favor of nimbus.seeds used during non HA mode.</description>
<deleted>true</deleted>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/repos/repoinfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/repos/repoinfo.xml
index 6ac43f95dd..54bd3dad62 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/repos/repoinfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/repos/repoinfo.xml
@@ -41,18 +41,6 @@
<reponame>HDP-UTILS</reponame>
</repo>
</os>
- <os family="redhat2015">
- <repo>
- <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/updates/2.4.0.0</baseurl>
- <repoid>HDP-2.4</repoid>
- <reponame>HDP</reponame>
- </repo>
- <repo>
- <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.20/repos/centos6</baseurl>
- <repoid>HDP-UTILS-1.1.0.20</repoid>
- <reponame>HDP-UTILS</reponame>
- </repo>
- </os>
<os family="suse11">
<repo>
<baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11sp3/2.x/updates/2.4.0.0</baseurl>
diff --git a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-env.xml b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-env.xml
index 0efd749595..8dde3fd33f 100644
--- a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-env.xml
@@ -77,26 +77,6 @@
</property>
<property>
- <name>cost_based_optimizer</name>
- <display-name>Cost Based Optimizer</display-name>
- <value>Off</value>
- <value-attributes>
- <type>value-list</type>
- <entries>
- <entry>
- <value>On</value>
- <label>On</label>
- </entry>
- <entry>
- <value>Off</value>
- <label>Off</label>
- </entry>
- </entries>
- <selection-cardinality>1</selection-cardinality>
- </value-attributes>
- </property>
-
- <property>
<name>hive_security_authorization</name>
<display-name>Choose Authorization</display-name>
<value>None</value>
diff --git a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-site.xml b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-site.xml
index 6ef7f32981..be7c943fa5 100644
--- a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/HIVE/configuration/hive-site.xml
@@ -789,10 +789,6 @@ limitations under the License.
</value-attributes>
<depends-on>
<property>
- <type>hive-env</type>
- <name>cost_based_optimizer</name>
- </property>
- <property>
<type>hive-site</type>
<name>hive.cbo.enable</name>
</property>
@@ -824,10 +820,6 @@ limitations under the License.
</value-attributes>
<depends-on>
<property>
- <type>hive-env</type>
- <name>cost_based_optimizer</name>
- </property>
- <property>
<type>hive-site</type>
<name>hive.cbo.enable</name>
</property>
diff --git a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/stack_advisor.py
index afdb7cf744..1ed4ce06dc 100644
--- a/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDPWIN/2.2/services/stack_advisor.py
@@ -362,14 +362,11 @@ class HDPWIN22StackAdvisor(HDPWIN21StackAdvisor):
putHiveSiteProperty("hive.exec.reducers.bytes.per.reducer", "67108864")
# CBO
- putHiveEnvProperty("cost_based_optimizer", "On")
- if str(configurations["hive-env"]["properties"]["cost_based_optimizer"]).lower() == "on":
- putHiveSiteProperty("hive.cbo.enable", "true")
- else:
- putHiveSiteProperty("hive.cbo.enable", "false")
- hive_cbo_enable = configurations["hive-site"]["properties"]["hive.cbo.enable"]
- putHiveSiteProperty("hive.stats.fetch.partition.stats", hive_cbo_enable)
- putHiveSiteProperty("hive.stats.fetch.column.stats", hive_cbo_enable)
+ if "hive-site" in services["configurations"] and "hive.cbo.enable" in services["configurations"]["hive-site"]["properties"]:
+ hive_cbo_enable = services["configurations"]["hive-site"]["properties"]["hive.cbo.enable"]
+ putHiveSiteProperty("hive.stats.fetch.partition.stats", hive_cbo_enable)
+ putHiveSiteProperty("hive.stats.fetch.column.stats", hive_cbo_enable)
+
putHiveSiteProperty("hive.compute.query.using.stats", "true")
# Interactive Query
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 d3945dc242..2a4cec8a2d 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
@@ -183,9 +183,11 @@ public class TestHeartbeatHandler {
public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ private InMemoryDefaultTestModule module;
+
@Before
public void setup() throws Exception {
- InMemoryDefaultTestModule module = new InMemoryDefaultTestModule(){
+ module = new InMemoryDefaultTestModule(){
@Override
protected void configure() {
@@ -856,11 +858,23 @@ public class TestHeartbeatHandler {
Clusters fsm = clusters;
HeartBeatHandler handler = new HeartBeatHandler(fsm, new ActionQueue(), am,
injector);
- clusters.addHost(DummyHostname1);
+ Cluster cluster = getDummyCluster();
+ Service hdfs = cluster.addService(HDFS);
+ hdfs.persist();
+ hdfs.addServiceComponent(DATANODE).persist();
+ hdfs.getServiceComponent(DATANODE).addServiceComponentHost(DummyHostname1).persist();
+ hdfs.addServiceComponent(NAMENODE).persist();
+ hdfs.getServiceComponent(NAMENODE).addServiceComponentHost(DummyHostname1).persist();
+ hdfs.addServiceComponent(HDFS_CLIENT).persist();
+ hdfs.getServiceComponent(HDFS_CLIENT).addServiceComponentHost(DummyHostname1).persist();
+
Host hostObject = clusters.getHost(DummyHostname1);
hostObject.setIPv4("ipv4");
hostObject.setIPv6("ipv6");
+ // add recovery.enabled_components to ambari configuration
+ module.getProperties().put("recovery.enabled_components", "NAMENODE,DATANODE");
+
Register reg = new Register();
HostInfo hi = new HostInfo();
hi.setHostName(DummyHostname1);
@@ -877,6 +891,7 @@ public class TestHeartbeatHandler {
assertEquals(rc.getMaxLifetimeCount(), "10");
assertEquals(rc.getRetryGap(), "2");
assertEquals(rc.getWindowInMinutes(), "23");
+ assertEquals(rc.getEnabledComponents(), "NAMENODE,DATANODE");
rc = RecoveryConfig.getRecoveryConfig(new Configuration());
assertEquals(rc.getMaxCount(), "6");
@@ -884,6 +899,65 @@ public class TestHeartbeatHandler {
assertEquals(rc.getMaxLifetimeCount(), "12");
assertEquals(rc.getRetryGap(), "5");
assertEquals(rc.getWindowInMinutes(), "60");
+ assertEquals(rc.getEnabledComponents(), "");
+
+ // clean up
+ module.getProperties().remove("recovery.enabled_components");
+ }
+
+ //
+ // Same as testRegistrationRecoveryConfig but will test
+ // maintenance mode set to ON for a service component host
+ //
+ @Test
+ public void testRegistrationRecoveryConfigMaintenanceMode()
+ throws AmbariException, InvalidStateTransitionException {
+ ActionManager am = getMockActionManager();
+ replay(am);
+ Clusters fsm = clusters;
+ HeartBeatHandler handler = new HeartBeatHandler(fsm, new ActionQueue(), am,
+ injector);
+ Cluster cluster = getDummyCluster();
+ Service hdfs = cluster.addService(HDFS);
+ hdfs.persist();
+ hdfs.addServiceComponent(DATANODE).persist();
+ hdfs.getServiceComponent(DATANODE).addServiceComponentHost(DummyHostname1).persist();
+ hdfs.addServiceComponent(NAMENODE).persist();
+ hdfs.getServiceComponent(NAMENODE).addServiceComponentHost(DummyHostname1).persist();
+ hdfs.addServiceComponent(HDFS_CLIENT).persist();
+ hdfs.getServiceComponent(HDFS_CLIENT).addServiceComponentHost(DummyHostname1).persist();
+
+ Host hostObject = clusters.getHost(DummyHostname1);
+ hostObject.setIPv4("ipv4");
+ hostObject.setIPv6("ipv6");
+
+ // add recovery.enabled_components to ambari configuration
+ module.getProperties().put("recovery.enabled_components", "NAMENODE,DATANODE,HDFS_CLIENT");
+
+ // set maintenance mode on HDFS_CLIENT on host1 to true
+ ServiceComponentHost schHdfsClient = hdfs.getServiceComponent(HDFS_CLIENT).getServiceComponentHost(DummyHostname1);
+ schHdfsClient.setMaintenanceState(MaintenanceState.ON);
+
+ Register reg = new Register();
+ HostInfo hi = new HostInfo();
+ hi.setHostName(DummyHostname1);
+ hi.setOS(DummyOsType);
+ reg.setHostname(DummyHostname1);
+ reg.setCurrentPingPort(DummyCurrentPingPort);
+ reg.setHardwareProfile(hi);
+ reg.setAgentVersion(metaInfo.getServerVersion());
+ reg.setPrefix(Configuration.PREFIX_DIR);
+ RegistrationResponse rr = handler.handleRegistration(reg);
+ RecoveryConfig rc = rr.getRecoveryConfig();
+ assertEquals(rc.getMaxCount(), "4");
+ assertEquals(rc.getType(), "FULL");
+ assertEquals(rc.getMaxLifetimeCount(), "10");
+ assertEquals(rc.getRetryGap(), "2");
+ assertEquals(rc.getWindowInMinutes(), "23");
+ assertEquals(rc.getEnabledComponents(), "NAMENODE,DATANODE"); // HDFS_CLIENT is in maintenance mode
+
+ // clean up
+ module.getProperties().remove("recovery.enabled_components");
}
@Test
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcherTest.java
index 12141c9992..9e0e406925 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcherTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/notifications/dispatchers/AlertScriptDispatcherTest.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.notifications.dispatchers;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
@@ -28,8 +29,12 @@ import org.apache.ambari.server.notifications.DispatchCallback;
import org.apache.ambari.server.notifications.DispatchFactory;
import org.apache.ambari.server.notifications.Notification;
import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.alert.AlertNotification;
import org.apache.ambari.server.state.alert.TargetType;
+import org.apache.ambari.server.state.services.AlertNoticeDispatchService.AlertInfo;
import org.apache.ambari.server.state.stack.OsFamily;
import org.easymock.EasyMock;
import org.junit.Before;
@@ -44,6 +49,8 @@ import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import junit.framework.Assert;
+
/**
* Tests {@link AlertScriptDispatcher}.
*/
@@ -217,6 +224,60 @@ public class AlertScriptDispatcherTest {
}
/**
+ * Tests that arguments given to the {@link ProcessBuilder} are properly
+ * escaped.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testArgumentEscaping() throws Exception {
+ final String ALERT_DEFINITION_NAME = "mock_alert_with_quotes";
+ final String ALERT_DEFINITION_LABEL = "Mock alert with Quotes";
+ final String ALERT_LABEL = "Alert Label";
+ final String ALERT_SERVICE_NAME = "FOO_SERVICE";
+ final String ALERT_TEXT = "Did you know, \"Quotes are hard!!!\"";
+ final String ALERT_TEXT_ESCAPED = "Did you know, \\\"Quotes are hard\\!\\!\\!\\\"";
+
+ DispatchCallback callback = EasyMock.createNiceMock(DispatchCallback.class);
+ AlertNotification notification = new AlertNotification();
+ notification.Callback = callback;
+ notification.CallbackIds = Collections.singletonList(UUID.randomUUID().toString());
+
+ AlertDefinitionEntity definition = new AlertDefinitionEntity();
+ definition.setDefinitionName(ALERT_DEFINITION_NAME);
+ definition.setLabel(ALERT_DEFINITION_LABEL);
+
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertLabel(ALERT_LABEL);
+ history.setAlertText(ALERT_TEXT);
+ history.setAlertState(AlertState.OK);
+ history.setServiceName(ALERT_SERVICE_NAME);
+
+ AlertInfo alertInfo = new AlertInfo(history);
+ notification.setAlertInfo(alertInfo);
+
+ AlertScriptDispatcher dispatcher = new AlertScriptDispatcher();
+ m_injector.injectMembers(dispatcher);
+
+ ProcessBuilder processBuilder = dispatcher.getProcessBuilder(SCRIPT_CONFIG_VALUE, notification);
+ List<String> commands = processBuilder.command();
+ Assert.assertEquals(3, commands.size());
+ Assert.assertEquals("sh", commands.get(0));
+ Assert.assertEquals("-c", commands.get(1));
+
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(SCRIPT_CONFIG_VALUE).append(" ");
+ buffer.append(ALERT_DEFINITION_NAME).append(" ");
+ buffer.append("\"").append(ALERT_DEFINITION_LABEL).append("\"").append(" ");
+ buffer.append(ALERT_SERVICE_NAME).append(" ");
+ buffer.append(AlertState.OK).append(" ");
+ buffer.append("\"").append(ALERT_TEXT_ESCAPED).append("\"");
+
+ Assert.assertEquals(buffer.toString(), commands.get(2));
+ }
+
+ /**
*
*/
private class MockModule extends AbstractModule {
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog222Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog222Test.java
index 67b9da51e5..6061e067bc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog222Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog222Test.java
@@ -133,12 +133,31 @@ public class UpgradeCatalog222Test {
{
put("timeline.metrics.host.aggregator.daily.checkpointCutOffMultiplier", String.valueOf(1));
put("timeline.metrics.cluster.aggregator.daily.checkpointCutOffMultiplier", String.valueOf(1));
+ put("timeline.metrics.service.operation.mode", "distributed");
+ put("timeline.metrics.host.aggregator.ttl", String.valueOf(86400));
+ put("timeline.metrics.host.aggregator.minute.ttl", String.valueOf(604800));
+ put("timeline.metrics.host.aggregator.hourly.ttl", String.valueOf(2592000));
+ put("timeline.metrics.host.aggregator.daily.ttl", String.valueOf(31536000));
+ put("timeline.metrics.cluster.aggregator.second.ttl", String.valueOf(21600)); //Less than 1 day
+ put("timeline.metrics.cluster.aggregator.minute.ttl", String.valueOf(7776000));
+ put("timeline.metrics.cluster.aggregator.hourly.ttl", String.valueOf(31536000));
+ put("timeline.metrics.cluster.aggregator.daily.ttl", String.valueOf(63072000));
}
};
Map<String, String> newPropertiesAmsSite = new HashMap<String, String>() {
{
put("timeline.metrics.host.aggregator.daily.checkpointCutOffMultiplier", String.valueOf(2));
put("timeline.metrics.cluster.aggregator.daily.checkpointCutOffMultiplier", String.valueOf(2));
+ put("timeline.metrics.service.watcher.disabled", String.valueOf(false));
+ put("timeline.metrics.host.aggregator.ttl", String.valueOf(7.0));
+ put("timeline.metrics.host.aggregator.minute.ttl", String.valueOf(7.0));
+ put("timeline.metrics.host.aggregator.hourly.ttl", String.valueOf(30.0));
+ put("timeline.metrics.host.aggregator.daily.ttl", String.valueOf(365.0));
+ put("timeline.metrics.cluster.aggregator.second.ttl", String.valueOf(0.25));
+ put("timeline.metrics.cluster.aggregator.minute.ttl", String.valueOf(30.0));
+ put("timeline.metrics.cluster.aggregator.hourly.ttl", String.valueOf(365.0));
+ put("timeline.metrics.cluster.aggregator.daily.ttl", String.valueOf(730.0));
+ put("timeline.metrics.service.operation.mode", "distributed");
}
};
EasyMockSupport easyMockSupport = new EasyMockSupport();
@@ -151,7 +170,7 @@ public class UpgradeCatalog222Test {
put("normal", cluster);
}}).once();
expect(cluster.getDesiredConfigByType("ams-site")).andReturn(mockAmsSite).atLeastOnce();
- expect(mockAmsSite.getProperties()).andReturn(oldPropertiesAmsSite).times(2);
+ expect(mockAmsSite.getProperties()).andReturn(oldPropertiesAmsSite).anyTimes();
Injector injector = easyMockSupport.createNiceMock(Injector.class);
expect(injector.getInstance(Gson.class)).andReturn(null).anyTimes();
diff --git a/ambari-server/src/test/python/TestOSCheck.py b/ambari-server/src/test/python/TestOSCheck.py
index cf114a1a9a..d919fbc8be 100644
--- a/ambari-server/src/test/python/TestOSCheck.py
+++ b/ambari-server/src/test/python/TestOSCheck.py
@@ -30,7 +30,7 @@ from mock.mock import MagicMock
from only_for_platform import os_distro_value, os_distro_value_linux
-from ambari_commons import OSCheck
+from ambari_commons import OSCheck, OSConst
import os_check_type
utils = __import__('ambari_server.utils').utils
@@ -50,7 +50,7 @@ class TestOSCheck(TestCase):
# 1 - Any system
mock_is_oracle_linux.return_value = False
- mock_linux_distribution.return_value = ('my_os', '', '')
+ mock_linux_distribution.return_value = ('my_os', '2015.09', '')
result = OSCheck.get_os_type()
self.assertEquals(result, 'my_os')
@@ -66,13 +66,13 @@ class TestOSCheck(TestCase):
# 3 - path exist: '/etc/oracle-release'
mock_is_oracle_linux.return_value = True
- mock_linux_distribution.return_value = ('some_os', '', '')
+ mock_linux_distribution.return_value = ('some_os', '1234', '')
result = OSCheck.get_os_type()
self.assertEquals(result, 'oraclelinux')
# 4 - Common system
mock_is_oracle_linux.return_value = False
- mock_linux_distribution.return_value = ('CenToS', '', '')
+ mock_linux_distribution.return_value = ('CenToS', '4.56', '')
result = OSCheck.get_os_type()
self.assertEquals(result, 'centos')
@@ -99,31 +99,31 @@ class TestOSCheck(TestCase):
# 1 - Any system
mock_exists.return_value = False
- mock_linux_distribution.return_value = ('MY_os', '', '')
+ mock_linux_distribution.return_value = ('MY_os', '5.6.7', '')
result = OSCheck.get_os_family()
self.assertEquals(result, 'my_os')
# 2 - Redhat
mock_exists.return_value = False
- mock_linux_distribution.return_value = ('Centos Linux', '', '')
+ mock_linux_distribution.return_value = ('Centos Linux', '2.4', '')
result = OSCheck.get_os_family()
self.assertEquals(result, 'redhat')
# 3 - Ubuntu
mock_exists.return_value = False
- mock_linux_distribution.return_value = ('Ubuntu', '', '')
+ mock_linux_distribution.return_value = ('Ubuntu', '14.04', '')
result = OSCheck.get_os_family()
self.assertEquals(result, 'ubuntu')
# 4 - Suse
mock_exists.return_value = False
mock_linux_distribution.return_value = (
- 'suse linux enterprise server', '', '')
+ 'suse linux enterprise server', '11.3', '')
result = OSCheck.get_os_family()
self.assertEquals(result, 'suse')
mock_exists.return_value = False
- mock_linux_distribution.return_value = ('SLED', '', '')
+ mock_linux_distribution.return_value = ('SLED', '1.2.3.4.5', '')
result = OSCheck.get_os_family()
self.assertEquals(result, 'suse')
@@ -141,7 +141,7 @@ class TestOSCheck(TestCase):
def test_get_os_version(self, mock_linux_distribution):
# 1 - Any system
- mock_linux_distribution.return_value = ('', '123.45', '')
+ mock_linux_distribution.return_value = ('some_os', '123.45', '')
result = OSCheck.get_os_version()
self.assertEquals(result, '123.45')
@@ -159,7 +159,7 @@ class TestOSCheck(TestCase):
def test_get_os_major_version(self, mock_linux_distribution):
# 1
- mock_linux_distribution.return_value = ('', '123.45.67', '')
+ mock_linux_distribution.return_value = ('abcd_os', '123.45.67', '')
result = OSCheck.get_os_major_version()
self.assertEquals(result, '123')
@@ -167,6 +167,21 @@ class TestOSCheck(TestCase):
mock_linux_distribution.return_value = ('Suse', '11', '')
result = OSCheck.get_os_major_version()
self.assertEquals(result, '11')
+
+ @patch.object(OSCheck, "os_distribution")
+ def test_aliases(self, mock_linux_distribution):
+ OSConst.OS_TYPE_ALIASES['qwerty_os123'] = 'aliased_os5'
+ OSConst.OS_FAMILY_COLLECTION.append({
+ 'name': 'aliased_os_family',
+ 'os_list': ["aliased_os"]
+ })
+
+ mock_linux_distribution.return_value = ('qwerty_os', '123.45.67', '')
+
+ self.assertEquals(OSCheck.get_os_type(), 'aliased_os')
+ self.assertEquals(OSCheck.get_os_major_version(), '5')
+ self.assertEquals(OSCheck.get_os_version(), '5.45.67')
+ self.assertEquals(OSCheck.get_os_family(), 'aliased_os_family')
@patch.object(OSCheck, "os_distribution")
def test_get_os_release_name(self, mock_linux_distribution):
diff --git a/ambari-server/src/test/python/stacks/2.1/configs/hive-metastore-upgrade.json b/ambari-server/src/test/python/stacks/2.1/configs/hive-metastore-upgrade.json
index 7829f05804..0fbc282444 100644
--- a/ambari-server/src/test/python/stacks/2.1/configs/hive-metastore-upgrade.json
+++ b/ambari-server/src/test/python/stacks/2.1/configs/hive-metastore-upgrade.json
@@ -77,8 +77,7 @@
"hive_user": "hive",
"hive_database": "New MySQL Database",
"hive.heapsize": "703",
- "hcat_pid_dir": "/var/run/webhcat",
- "cost_based_optimizer": "On",
+ "hcat_pid_dir": "/var/run/webhcat",
"webhcat_user": "hcat",
"hive_security_authorization": "None",
"hive_exec_orc_storage_strategy": "SPEED",
diff --git a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
index 0a8f05b992..d2497fd4f2 100644
--- a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
@@ -1019,7 +1019,6 @@ class TestHDP22StackAdvisor(TestCase):
},
'hive-env': {
'properties': {
- 'cost_based_optimizer': 'On',
'hive_exec_orc_storage_strategy': 'SPEED',
'hive_security_authorization': 'None',
'hive_timeline_logging_enabled': 'true',
@@ -1033,7 +1032,6 @@ class TestHDP22StackAdvisor(TestCase):
'hive.server2.tez.initialize.default.sessions': 'false',
'hive.server2.tez.sessions.per.default.queue': '1',
'hive.auto.convert.join.noconditionaltask.size': '268435456',
- 'hive.cbo.enable': 'true',
'hive.compactor.initiator.on': 'false',
'hive.compactor.worker.threads': '0',
'hive.compute.query.using.stats': 'true',
@@ -1176,7 +1174,8 @@ class TestHDP22StackAdvisor(TestCase):
"hive.server2.authentication.kerberos.keytab": "",
"hive.server2.authentication.kerberos.principal": "",
"hive.server2.authentication.pam.services": "",
- "hive.server2.custom.authentication.class": ""
+ "hive.server2.custom.authentication.class": "",
+ "hive.cbo.enable": "true"
}
},
"hiveserver2-site": {
@@ -1251,7 +1250,8 @@ class TestHDP22StackAdvisor(TestCase):
"hive.server2.authentication.kerberos.keytab": "",
"hive.server2.authentication.kerberos.principal": "",
"hive.server2.authentication.pam.services": "",
- "hive.server2.custom.authentication.class": ""
+ "hive.server2.custom.authentication.class": "",
+ "hive.cbo.enable": "true"
}
},
"hiveserver2-site": {
@@ -1315,10 +1315,8 @@ class TestHDP22StackAdvisor(TestCase):
#test recommendations
services["configurations"]["hive-site"]["properties"]["hive.cbo.enable"] = "false"
services["configurations"]["hive-env"]["properties"]["hive_security_authorization"] = "sqlstdauth"
- services["changed-configurations"] = [{"type": "hive-site", "name": "hive.cbo.enable"},
- {"type": "hive-env", "name": "hive_security_authorization"}]
+ services["changed-configurations"] = [{"type": "hive-env", "name": "hive_security_authorization"}]
expected["hive-env"]["properties"]["hive_security_authorization"] = "sqlstdauth"
- expected["hive-site"]["properties"]["hive.cbo.enable"] = "false"
expected["hive-site"]["properties"]["hive.stats.fetch.partition.stats"]="false"
expected["hive-site"]["properties"]["hive.stats.fetch.column.stats"]="false"
expected["hive-site"]["properties"]["hive.security.authorization.enabled"]="true"
@@ -2052,7 +2050,8 @@ class TestHDP22StackAdvisor(TestCase):
"properties": {
"timeline.metrics.cluster.aggregate.splitpoints": " ",
"timeline.metrics.host.aggregate.splitpoints": " ",
- "timeline.metrics.host.aggregator.ttl": "86400"
+ "timeline.metrics.host.aggregator.ttl": "1",
+ 'timeline.metrics.service.watcher.disabled': 'false'
}
}
}
@@ -2230,6 +2229,8 @@ class TestHDP22StackAdvisor(TestCase):
expected['ams-hbase-env']['properties']['hbase_regionserver_heapsize'] = '512'
expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '102'
expected['ams-hbase-env']['properties']['regionserver_xmn_size'] = '384'
+ expected['ams-site']['properties']['timeline.metrics.host.aggregator.ttl'] = '7'
+ expected['ams-site']['properties']['timeline.metrics.service.watcher.disabled'] = 'true'
self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
self.assertEquals(configurations, expected)
diff --git a/ambari-server/src/test/python/stacks/2.3/common/services-sparkts-hive.json b/ambari-server/src/test/python/stacks/2.3/common/services-sparkts-hive.json
index 51ae36af7d..20a672e055 100644
--- a/ambari-server/src/test/python/stacks/2.3/common/services-sparkts-hive.json
+++ b/ambari-server/src/test/python/stacks/2.3/common/services-sparkts-hive.json
@@ -2402,47 +2402,6 @@
},
"dependencies" : [ ]
}, {
- "href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/cost_based_optimizer",
- "StackConfigurations" : {
- "property_depends_on" : [ ],
- "property_name" : "cost_based_optimizer",
- "service_name" : "HIVE",
- "stack_name" : "HDP",
- "stack_version" : "2.3",
- "type" : "hive-env.xml"
- },
- "dependencies" : [ {
- "href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/cost_based_optimizer/dependencies/hive.cbo.enable",
- "StackConfigurationDependency" : {
- "dependency_name" : "hive.cbo.enable",
- "dependency_type" : "hive-site",
- "property_name" : "cost_based_optimizer",
- "service_name" : "HIVE",
- "stack_name" : "HDP",
- "stack_version" : "2.3"
- }
- }, {
- "href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/cost_based_optimizer/dependencies/hive.stats.fetch.column.stats",
- "StackConfigurationDependency" : {
- "dependency_name" : "hive.stats.fetch.column.stats",
- "dependency_type" : "hive-site",
- "property_name" : "cost_based_optimizer",
- "service_name" : "HIVE",
- "stack_name" : "HDP",
- "stack_version" : "2.3"
- }
- }, {
- "href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/cost_based_optimizer/dependencies/hive.stats.fetch.partition.stats",
- "StackConfigurationDependency" : {
- "dependency_name" : "hive.stats.fetch.partition.stats",
- "dependency_type" : "hive-site",
- "property_name" : "cost_based_optimizer",
- "service_name" : "HIVE",
- "stack_name" : "HDP",
- "stack_version" : "2.3"
- }
- } ]
- }, {
"href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/datanucleus.autoCreateSchema",
"StackConfigurations" : {
"property_depends_on" : [ ],
@@ -4199,9 +4158,6 @@
"href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/hive.stats.fetch.column.stats",
"StackConfigurations" : {
"property_depends_on" : [ {
- "type" : "hive-env",
- "name" : "cost_based_optimizer"
- }, {
"type" : "hive-site",
"name" : "hive.cbo.enable"
} ],
@@ -4216,9 +4172,6 @@
"href" : "/api/v1/stacks/HDP/versions/2.3/services/HIVE/configurations/hive.stats.fetch.partition.stats",
"StackConfigurations" : {
"property_depends_on" : [ {
- "type" : "hive-env",
- "name" : "cost_based_optimizer"
- }, {
"type" : "hive-site",
"name" : "hive.cbo.enable"
} ],
diff --git a/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py
index 72e77184e3..545a2b5bcf 100644
--- a/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py
@@ -882,7 +882,6 @@ class TestHDP23StackAdvisor(TestCase):
},
'hive-env': {
'properties': {
- 'cost_based_optimizer': 'On',
'hive_exec_orc_storage_strategy': 'SPEED',
'hive_security_authorization': 'None',
'hive_timeline_logging_enabled': 'true',
@@ -896,7 +895,6 @@ class TestHDP23StackAdvisor(TestCase):
'hive.server2.tez.initialize.default.sessions': 'false',
'hive.server2.tez.sessions.per.default.queue': '1',
'hive.auto.convert.join.noconditionaltask.size': '268435456',
- 'hive.cbo.enable': 'true',
'hive.compactor.initiator.on': 'false',
'hive.compactor.worker.threads': '0',
'hive.compute.query.using.stats': 'true',
@@ -1040,7 +1038,8 @@ class TestHDP23StackAdvisor(TestCase):
"hive.server2.authentication.kerberos.keytab": "",
"hive.server2.authentication.kerberos.principal": "",
"hive.server2.authentication.pam.services": "",
- "hive.server2.custom.authentication.class": ""
+ "hive.server2.custom.authentication.class": "",
+ "hive.cbo.enable": "true"
}
},
"hiveserver2-site": {
diff --git a/ambari-web/app/controllers/main/admin/service_auto_start.js b/ambari-web/app/controllers/main/admin/service_auto_start.js
index fd288eda3b..40712922a1 100644
--- a/ambari-web/app/controllers/main/admin/service_auto_start.js
+++ b/ambari-web/app/controllers/main/admin/service_auto_start.js
@@ -21,6 +21,11 @@ var App = require('app');
App.MainAdminServiceAutoStartController = Em.Controller.extend({
name: 'mainAdminServiceAutoStartController',
+ clusterConfigs: null,
+ componentsConfigs: [],
+ isSaveDisabled: true,
+ valueChanged: false,
+
loadClusterConfig: function () {
return App.ajax.send({
name: 'config.tags.site',
@@ -31,6 +36,161 @@ App.MainAdminServiceAutoStartController = Em.Controller.extend({
});
},
+ loadComponentsConfigs: function () {
+ return App.ajax.send({
+ name: 'components.get_category',
+ sender: this,
+ success: 'loadComponentsConfigsSuccess'
+ });
+ },
+
+ loadComponentsConfigsSuccess: function (data) {
+ this.set('componentsConfigs', data.items);
+ },
+
+ tabs: function() {
+ var services = {};
+ var tabs = [];
+ this.get('componentsConfigs').forEach(function(component) {
+ var serviceComponentInfo = component.ServiceComponentInfo;
+ if (serviceComponentInfo.category === "MASTER" || serviceComponentInfo.category === "SLAVE") {
+ var componentRecovery = Ember.Object.create({
+ display_name: App.format.role(serviceComponentInfo.component_name),
+ component_name: serviceComponentInfo.component_name,
+ //recovery_enabled: serviceComponentInfo.recovery_enabled === 'true',
+ recovery_enabled: false,
+ valueChanged: false,
+ service_name: serviceComponentInfo.service_name
+ });
+ if (services[serviceComponentInfo.service_name]) {
+ services[serviceComponentInfo.service_name].get('componentRecovery').push(componentRecovery);
+ services[serviceComponentInfo.service_name].set('enabledComponents', services[serviceComponentInfo.service_name].get('enabledComponents') + (componentRecovery.get('recovery_enabled') ? 1 : 0));
+ services[serviceComponentInfo.service_name].set('totalComponents', services[serviceComponentInfo.service_name].get('totalComponents') + 1);
+ } else {
+ services[serviceComponentInfo.service_name] = Ember.Object.create({
+ service_name: serviceComponentInfo.service_name,
+ display_name: App.format.role(serviceComponentInfo.service_name),
+ headingClass: "." + serviceComponentInfo.service_name,
+ isActive: false,
+ componentRecovery: [componentRecovery],
+ enabledComponents: componentRecovery.recovery_enabled ? 1 : 0,
+ totalComponents: 1,
+ indicator: function() {
+ var percentage = this.get('enabledComponents') / this.get('totalComponents');
+ var indicator = "icon-adjust";
+ if (percentage === 1) {
+ indicator = "icon-circle";
+ } else if (percentage === 0) {
+ indicator = "icon-circle-blank";
+ }
+ return indicator;
+ }.property('enabledComponents', 'totalComponents')
+ });
+ }
+ }
+ });
+ for (var service in services ) {
+ tabs.push(services[service]);
+ }
+ if (tabs.length) {
+ tabs[0].set('isActive', true);
+ }
+ return tabs;
+ }.property('componentsConfigs'),
+
+ checkValuesChange: function () {
+ var valuesChanged = this.get('valueChanged');
+ this.get('tabs').forEach(function (service) {
+ service.get('componentRecovery').forEach(function (component) {
+ valuesChanged = valuesChanged || component.get('valueChanged');
+ });
+ });
+ this.set('isSaveDisabled', !valuesChanged);
+ }.observes('valueChanged'),
+
+ doReload: function () {
+ window.location.reload();
+ },
+
+ /**
+ * If some configs are changed and user navigates away or select another config-group, show this popup with propose to save changes
+ * @param {object} transitionCallback - callback with action to change configs view
+ * @return {App.ModalPopup}
+ * @method showSavePopup
+ */
+ showSavePopup: function (transitionCallback) {
+ var self = this;
+ return App.ModalPopup.show({
+ header: Em.I18n.t('dashboard.configHistory.info-bar.save.popup.title'),
+ footerClass: Em.View.extend({
+ templateName: require('templates/main/service/info/save_popup_footer'),
+ }),
+ primary: Em.I18n.t('common.save'),
+ secondary: Em.I18n.t('common.cancel'),
+ onSave: function () {
+ //save cluster setting
+ if (self.get('valueChanged')) {
+ self.saveClusterConfigs(self.get('clusterConfigs'));
+ }
+ //save component settings
+ var enabledComponents = [];
+ var disabledComponents = [];
+ self.get('tabs').forEach(function (service) {
+ service.get('componentRecovery').forEach(function (component) {
+ if (component.get('valueChanged')) {
+ if (component.get('recoveryEnabled')) {
+ enabledComponents.push(component.get('component_name'));
+ } else {
+ disabledComponents.push(component.get('component_name'));
+ }
+ }
+ });
+ });
+ if (enabledComponents.length){
+ App.ajax.send({
+ name: 'components.update',
+ sender: this,
+ data: {
+ ServiceComponentInfo: {
+ recovery_enabled: "true"
+ },
+ query: 'ServiceComponentInfo/component_name.in(' + enabledComponents.join(',') + ')'
+ }
+ });
+ }
+ if (disabledComponents.length){
+ App.ajax.send({
+ name: 'components.update',
+ sender: this,
+ data: {
+ ServiceComponentInfo: {
+ recovery_enabled: "false"
+ },
+ query: 'ServiceComponentInfo/component_name.in(' + disabledComponents.join(',') + ')'
+ }
+ });
+ }
+ if (typeof transitionCallback === 'function') {
+ transitionCallback();
+ } else {
+ self.doReload();
+ }
+ this.hide();
+ },
+ onDiscard: function () {
+ if (typeof transitionCallback === 'function') {
+ transitionCallback();
+ } else {
+ self.doReload();
+ }
+ this.hide();
+ },
+ onCancel: function () {
+ this.hide();
+ }
+ });
+ },
+
saveClusterConfigs: function (clusterConfigs) {
return App.ajax.send({
name: 'admin.save_configs',
@@ -41,5 +201,4 @@ App.MainAdminServiceAutoStartController = Em.Controller.extend({
}
});
}
-
});
diff --git a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
index 244b8f07c9..79e524e006 100644
--- a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
+++ b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
@@ -61,7 +61,9 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
value: '',
defaultValue: 'custom',
disabled: false,
- isAll: Em.computed.equal('value', 'all')
+ isAll: function () {
+ return this.get('value') == 'all';
+ }.property('value')
}),
method: {
label: Em.I18n.t('alerts.actions.manage_alert_notifications_popup.method'),
@@ -157,7 +159,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
* used in Type combobox
* @type {Array}
*/
- methods: ['EMAIL', 'SNMP', 'Custom SNMP'],
+ methods: ['EMAIL', 'SNMP'],
/**
* List of available value for Severity Filter
@@ -218,8 +220,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
'mail.smtp.from',
'mail.smtp.host',
'mail.smtp.port',
- 'mail.smtp.starttls.enable',
- 'ambari.dispatch-property.script'
+ 'mail.smtp.starttls.enable'
],
validationMap: {
@@ -241,16 +242,6 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
validator: 'retypePasswordValidation'
}
],
- 'Custom SNMP': [
- {
- errorKey: 'portError',
- validator: 'portValidation'
- },
- {
- errorKey: 'hostError',
- validator: 'hostsValidation'
- }
- ],
SNMP: [
{
errorKey: 'portError',
@@ -331,25 +322,24 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
fillEditCreateInputs: function (addCopyToName) {
var inputFields = this.get('inputFields');
var selectedAlertNotification = this.get('selectedAlertNotification');
- var props = selectedAlertNotification.get('properties');
inputFields.set('name.value', (addCopyToName ? 'Copy of ' : '') + selectedAlertNotification.get('name'));
inputFields.set('groups.value', selectedAlertNotification.get('groups').toArray());
- inputFields.set('email.value', props['ambari.dispatch.recipients'] ?
- props['ambari.dispatch.recipients'].join(', ') : '');
- inputFields.set('SMTPServer.value', props['mail.smtp.host']);
- inputFields.set('SMTPPort.value', props['mail.smtp.port']);
- inputFields.set('SMTPUseAuthentication.value', props['mail.smtp.auth'] !== "false");
- inputFields.set('SMTPUsername.value', props['ambari.dispatch.credential.username']);
- inputFields.set('SMTPPassword.value', props['ambari.dispatch.credential.password']);
- inputFields.set('retypeSMTPPassword.value', props['ambari.dispatch.credential.password']);
- inputFields.set('SMTPSTARTTLS.value', props['mail.smtp.starttls.enable'] !== "false");
- inputFields.set('emailFrom.value', props['mail.smtp.from']);
- inputFields.set('version.value', props['ambari.dispatch.snmp.version']);
- inputFields.set('OIDs.value', props['ambari.dispatch.snmp.oids.trap']);
- inputFields.set('community.value', props['ambari.dispatch.snmp.community']);
- inputFields.set('host.value', props['ambari.dispatch.recipients'] ?
- props['ambari.dispatch.recipients'].join(', ') : '');
- inputFields.set('port.value', props['ambari.dispatch.snmp.port']);
+ inputFields.set('email.value', selectedAlertNotification.get('properties')['ambari.dispatch.recipients'] ?
+ selectedAlertNotification.get('properties')['ambari.dispatch.recipients'].join(', ') : '');
+ inputFields.set('SMTPServer.value', selectedAlertNotification.get('properties')['mail.smtp.host']);
+ inputFields.set('SMTPPort.value', selectedAlertNotification.get('properties')['mail.smtp.port']);
+ inputFields.set('SMTPUseAuthentication.value', selectedAlertNotification.get('properties')['mail.smtp.auth'] !== "false");
+ inputFields.set('SMTPUsername.value', selectedAlertNotification.get('properties')['ambari.dispatch.credential.username']);
+ inputFields.set('SMTPPassword.value', selectedAlertNotification.get('properties')['ambari.dispatch.credential.password']);
+ inputFields.set('retypeSMTPPassword.value', selectedAlertNotification.get('properties')['ambari.dispatch.credential.password']);
+ inputFields.set('SMTPSTARTTLS.value', selectedAlertNotification.get('properties')['mail.smtp.starttls.enable'] !== "false");
+ inputFields.set('emailFrom.value', selectedAlertNotification.get('properties')['mail.smtp.from']);
+ inputFields.set('version.value', selectedAlertNotification.get('properties')['ambari.dispatch.snmp.version']);
+ inputFields.set('OIDs.value', selectedAlertNotification.get('properties')['ambari.dispatch.snmp.oids.trap']);
+ inputFields.set('community.value', selectedAlertNotification.get('properties')['ambari.dispatch.snmp.community']);
+ inputFields.set('host.value', selectedAlertNotification.get('properties')['ambari.dispatch.recipients'] ?
+ selectedAlertNotification.get('properties')['ambari.dispatch.recipients'].join(', ') : '');
+ inputFields.set('port.value', selectedAlertNotification.get('properties')['ambari.dispatch.snmp.port']);
inputFields.set('severityFilter.value', selectedAlertNotification.get('alertStates'));
inputFields.set('global.value', selectedAlertNotification.get('global'));
inputFields.set('allGroups.value', selectedAlertNotification.get('global') ? 'all' : 'custom');
@@ -358,13 +348,14 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
inputFields.set('description.value', selectedAlertNotification.get('description'));
inputFields.set('method.value', selectedAlertNotification.get('type'));
inputFields.get('customProperties').clear();
+ var properties = selectedAlertNotification.get('properties');
var ignoredCustomProperties = this.get('ignoredCustomProperties');
- Em.keys(props).forEach(function (k) {
+ Em.keys(properties).forEach(function (k) {
if (ignoredCustomProperties.contains(k)) return;
inputFields.get('customProperties').pushObject({
name: k,
- value: props[k],
- defaultValue: props[k]
+ value: properties[k],
+ defaultValue: properties[k]
});
});
},
@@ -403,7 +394,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
validationMap = self.get('validationMap');
self.get('methods').forEach(function (method) {
var validations = validationMap[method];
- if (method === currentMethod) {
+ if (method == currentMethod) {
validations.mapProperty('validator').forEach(function (key) {
this.get(key).call(this);
}, this);
@@ -427,7 +418,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
if (!newName) {
this.set('nameError', true);
errorMessage = Em.I18n.t('alerts.actions.manage_alert_notifications_popup.error.name.empty');
- } else if (newName && newName !== this.get('currentName') && self.get('alertNotifications').mapProperty('name').contains(newName)) {
+ } else if (newName && newName != this.get('currentName') && self.get('alertNotifications').mapProperty('name').contains(newName)) {
this.set('nameError', true);
errorMessage = Em.I18n.t('alerts.actions.manage_alert_notifications_popup.error.name.existed');
} else {
@@ -484,7 +475,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
hostsValidation: function() {
var inputValue = this.get('controller.inputFields.host.value').trim(),
- hostError = false;
+ hostError = false;;
if (!this.get('isEmailMethodSelected')) {
var array = inputValue.split(',');
hostError = array.some(function(hostname) {
@@ -540,7 +531,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
* @method selectAllGroups
*/
selectAllGroups: function () {
- if (this.get('controller.inputFields.allGroups.value') === 'custom') {
+ if (this.get('controller.inputFields.allGroups.value') == 'custom') {
this.set('groupSelect.selection', this.get('groupSelect.content').slice());
}
},
@@ -550,7 +541,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
* @method clearAllGroups
*/
clearAllGroups: function () {
- if (this.get('controller.inputFields.allGroups.value') === 'custom') {
+ if (this.get('controller.inputFields.allGroups.value') == 'custom') {
this.set('groupSelect.selection', []);
}
},
@@ -654,9 +645,6 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
properties['ambari.dispatch.snmp.community'] = inputFields.get('community.value');
properties['ambari.dispatch.recipients'] = inputFields.get('host.value').replace(/\s/g, '').split(',');
properties['ambari.dispatch.snmp.port'] = inputFields.get('port.value');
- if (inputFields.get('method.value') === 'SNMP') {
- properties['ambari.dispatch-property.script'] = "org.apache.ambari.contrib.snmp.script";
- }
}
inputFields.get('customProperties').forEach(function (customProperty) {
properties[customProperty.name] = customProperty.value;
@@ -671,7 +659,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({
properties: properties
}
};
- if (inputFields.get('allGroups.value') === 'custom') {
+ if (inputFields.get('allGroups.value') == 'custom') {
apiObject.AlertTarget.groups = inputFields.get('groups.value').mapProperty('id');
}
return apiObject;
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 00fb4b9897..59877a5efa 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -2307,6 +2307,7 @@ Em.I18n.translations = {
'hosts.host.summary.hostname':'Hostname',
'hosts.host.summary.agentHeartbeat':'Heartbeat',
'hosts.host.summary.hostMetrics':'Host Metrics',
+ 'hosts.host.summary.hostLogMetrics':'Host Log Metrics',
'hosts.host.summary.addComponent':'Add Component',
'hosts.host.summary.currentVersion':'Current Version',
diff --git a/ambari-web/app/mixins/common/widgets/widget_mixin.js b/ambari-web/app/mixins/common/widgets/widget_mixin.js
index df7ff7622b..b6fe353003 100644
--- a/ambari-web/app/mixins/common/widgets/widget_mixin.js
+++ b/ambari-web/app/mixins/common/widgets/widget_mixin.js
@@ -119,6 +119,7 @@ App.WidgetMixin = Ember.Mixin.create({
context: this,
startCallName: 'getHostComponentMetrics',
successCallback: this.getHostComponentMetricsSuccessCallback,
+ errorCallback: this.getMetricsErrorCallback,
completeCallback: function () {
requestCounter--;
if (requestCounter === 0) this.onMetricsLoaded();
@@ -130,6 +131,7 @@ App.WidgetMixin = Ember.Mixin.create({
context: this,
startCallName: 'getServiceComponentMetrics',
successCallback: this.getMetricsSuccessCallback,
+ errorCallback: this.getMetricsErrorCallback,
completeCallback: function () {
requestCounter--;
if (requestCounter === 0) this.onMetricsLoaded();
@@ -271,12 +273,41 @@ App.WidgetMixin = Ember.Mixin.create({
if (!Em.isNone(metric_data)) {
_metric.data = metric_data;
this.get('metrics').pushObject(_metric);
+ } else if (this.get('graphView')) {
+ var graph = this.get('childViews') && this.get('childViews').findProperty('_showMessage');
+ if (graph) {
+ graph.set('hasData', false);
+ this.set('isExportButtonHidden', true);
+ graph._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noDataAtTime.message'));
+ this.get('metrics').clear();
+ }
}
}, this);
}
},
/**
+ * error callback on getting aggregated metrics and host component metrics
+ * @param {object} xhr
+ * @param {string} textStatus
+ * @param {string} errorThrown
+ */
+ getMetricsErrorCallback: function (xhr, textStatus, errorThrown) {
+ if (this.get('graphView')) {
+ var graph = this.get('childViews') && this.get('childViews').findProperty('_showMessage');
+ if (graph) {
+ if (xhr.readyState == 4 && xhr.status) {
+ textStatus = xhr.status + " " + textStatus;
+ }
+ graph.set('hasData', false);
+ this.set('isExportButtonHidden', true);
+ graph._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
+ this.get('metrics').clear();
+ }
+ }
+ },
+
+ /**
* make GET call to get metrics value for all host components
* @param {object} request
* @return {$.ajax}
@@ -704,6 +735,7 @@ App.WidgetLoadAggregator = Em.Object.create({
bulks[id].subRequests = [{
context: request.context,
successCallback: request.successCallback,
+ errorCallback: request.errorCallback,
completeCallback: request.completeCallback
}];
} else {
@@ -711,6 +743,7 @@ App.WidgetLoadAggregator = Em.Object.create({
bulks[id].subRequests.push({
context: request.context,
successCallback: request.successCallback,
+ errorCallback: request.errorCallback,
completeCallback: request.completeCallback
});
}
@@ -732,11 +765,17 @@ App.WidgetLoadAggregator = Em.Object.create({
_request.subRequests.forEach(function (subRequest) {
subRequest.successCallback.call(subRequest.context, response);
}, this);
- }).complete(function () {
- _request.subRequests.forEach(function (subRequest) {
- subRequest.completeCallback.call(subRequest.context);
- }, this);
- });
+ }).fail(function (xhr, textStatus, errorThrown) {
+ _request.subRequests.forEach(function (subRequest) {
+ if (subRequest.errorCallback) {
+ subRequest.errorCallback.call(subRequest.context, xhr, textStatus, errorThrown);
+ }
+ }, this);
+ }).complete(function () {
+ _request.subRequests.forEach(function (subRequest) {
+ subRequest.completeCallback.call(subRequest.context);
+ }, this);
+ });
})(bulks[id]);
}
}
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index cbaf34d4e6..419f8457c0 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -265,13 +265,16 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
}),
logs: Em.Route.extend({
- route: '/logs',
+ route: '/logs:query',
connectOutlets: function (router, context) {
if (App.get('supports.logSearch')) {
router.get('mainHostDetailsController').connectOutlet('mainHostLogs')
} else {
router.transitionTo('summary');
}
+ },
+ serialize: function(router, params) {
+ return this.serializeQueryParams(router, params, 'mainHostDetailsController');
}
}),
@@ -525,6 +528,14 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
connectOutlets: function (router) {
router.set('mainAdminController.category', "serviceAutoStart");
router.get('mainAdminController').connectOutlet('mainAdminServiceAutoStart');
+ },
+ exitRoute: function (router, context, callback) {
+ var controller = router.get('mainAdminServiceAutoStartController');
+ if (!controller.get('isSaveDisabled')) {
+ controller.showSavePopup(callback);
+ } else {
+ callback();
+ }
}
}),
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index a1969db332..57b7e76b6c 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2245,6 +2245,7 @@ a:focus {
left: 60px;
overflow: visible;
position: relative;
+ text-align: center;
}
.chart-y-axis {
position: absolute;
@@ -2260,6 +2261,10 @@ a:focus {
margin-top: 35px !important;
}
}
+ .alert {
+ display: inline-block;
+ padding-right: 14px;
+ }
}
position: relative;
margin: 20px 15px 0 15px;
@@ -3807,6 +3812,11 @@ table.graphs {
.bootstrap-switch {
margin-left: 20px;
}
+
+ .nav i {
+ margin-top: 0;
+ color: @green;
+ }
}
.admin-user-settings {
diff --git a/ambari-web/app/templates/main/admin/service_auto_start.hbs b/ambari-web/app/templates/main/admin/service_auto_start.hbs
index b5c10328ce..5d9b67c68f 100644
--- a/ambari-web/app/templates/main/admin/service_auto_start.hbs
+++ b/ambari-web/app/templates/main/admin/service_auto_start.hbs
@@ -24,14 +24,48 @@
{{t admin.serviceAutoStart.header.text}}
</div>
<br/>
- <div class="cluster-switcher">
- <p>{{t admin.serviceAutoStart.body.text}}
- {{view Ember.Checkbox checkedBinding="view.switcherValue"}}
- </p>
+ <div class="cluster-switcher row-fluid">
+ <div class="span4">
+ {{t admin.serviceAutoStart.body.text}}
+ </div>
+ <div class="span4">
+ {{view Ember.Checkbox checkedBinding="view.switcherValue"}}
+ </div>
+ <div class="pull-right operations-button pull-right">
+ <button class="btn" {{action doReload target="controller"}} {{bindAttr disabled="controller.isSaveDisabled"}}>{{t common.discard}}</button>
+ <button class="btn btn-success" {{action showSavePopup target="controller"}} {{bindAttr disabled="controller.isSaveDisabled"}}>{{t common.save}}</button>
+ </div>
</div>
{{#if view.switcherValue}}
- <div>
+ <div class="tabs-left">
<hr>
+ <ul class="nav nav-tabs">
+ {{#each tab in controller.tabs}}
+ <li {{bindAttr class="tab.isActive:active"}}>
+ <a href="#" data-toggle="tab" {{bindAttr data-target="tab.headingClass"}}>
+ {{tab.display_name}}
+ <i {{bindAttr class=":pull-right tab.indicator"}}>
+ </i>
+ </a>
+ </li>
+ {{/each}}
+ </ul>
+ <div class="tab-content">
+ {{#each tab in controller.tabs}}
+ <div {{bindAttr class=":tab-pane tab.isActive:active tab.service_name :row-fluid"}}>
+ {{#each component in tab.componentRecovery}}
+ <div class="row-fluid">
+ <div class="span4">
+ {{component.display_name}}
+ </div>
+ <div class="span8">
+ {{view App.MainAdminServiceAutoStartComponentView recoveryEnabledBinding="component.recovery_enabled" componentBinding="component" tabBinding="tab"}}
+ </div>
+ </div>
+ {{/each}}
+ </div>
+ {{/each}}
+ </div>
</div>
{{/if}}
-</div>
+</div> \ No newline at end of file
diff --git a/ambari-web/app/templates/main/admin/service_auto_start/component_auto_start.hbs b/ambari-web/app/templates/main/admin/service_auto_start/component_auto_start.hbs
new file mode 100644
index 0000000000..56af5adba2
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/service_auto_start/component_auto_start.hbs
@@ -0,0 +1,19 @@
+{{!
+* 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.
+}}
+
+{{view Ember.Checkbox checkedBinding="view.recoveryEnabled"}} \ No newline at end of file
diff --git a/ambari-web/app/templates/main/host/log_metrics.hbs b/ambari-web/app/templates/main/host/log_metrics.hbs
new file mode 100644
index 0000000000..22a39bee16
--- /dev/null
+++ b/ambari-web/app/templates/main/host/log_metrics.hbs
@@ -0,0 +1,26 @@
+{{!
+* 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.
+}}
+
+<div class="row-fluid log-metrics-charts mtl">
+ {{#each item in view.logsData}}
+ <div class="span6 text-center mtl">
+ {{view view.chartView contentBinding="item"}}
+ <a href="#" {{action transitionByService item target="view"}}>{{item.service.displayName}}</a>
+ </div>
+ {{/each}}
+</div>
diff --git a/ambari-web/app/templates/main/host/summary.hbs b/ambari-web/app/templates/main/host/summary.hbs
index 6b4c7a571c..17a0b69837 100644
--- a/ambari-web/app/templates/main/host/summary.hbs
+++ b/ambari-web/app/templates/main/host/summary.hbs
@@ -168,19 +168,31 @@
</div>
</div>
</div>
- {{!metrics}}
- {{#unless view.isNoHostMetricsService}}
- <div class="span6">
+ <div class="span6">
+ {{!metrics}}
+ {{#unless view.isNoHostMetricsService}}
<div class="box">
<div class="box-header">
<h4>{{t hosts.host.summary.hostMetrics}}</h4>
{{view view.timeRangeListView}}
</div>
<div>
- {{view App.MainHostMetricsView contentBinding="view.content"}}
+ {{view App.MainHostMetricsView contentBinding="view.content"}}
</div>
</div>
- </div>
+ {{/unless}}
+
+ {{!logs metrics}}
+ {{#if App.supports.logSearch}}
+ <div class="box">
+ <div class="box-header">
+ <h4>{{t hosts.host.summary.hostLogMetrics}}</h4>
+ </div>
+ <div>
+ {{view App.MainHostLogMetrics contentBinding="view.content"}}
+ </div>
+ </div>
+ {{/if}}
</div>
- {{/unless}}
+ </div>
</div>
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 8b89365d16..ce6a196ff9 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -2340,6 +2340,27 @@ var urls = {
'real': '/clusters/{clusterName}/components?fields=host_components/HostRoles/host_name,ServiceComponentInfo/component_name,ServiceComponentInfo/started_count{urlParams}&minimal_response=true',
'mock': ''
},
+ 'components.get_category': {
+ 'real': '/clusters/{clusterName}/components?fields=ServiceComponentInfo/component_name,ServiceComponentInfo/service_name,ServiceComponentInfo/category,ServiceComponentInfo/recovery_enabled&minimal_response=true',
+ 'mock': ''
+ },
+ 'components.update': {
+ 'real': '/clusters/{clusterName}/components?{urlParams}',
+ 'mock': '',
+ 'type': 'PUT',
+ 'format': function (data) {
+ return {
+ data: JSON.stringify({
+ RequestInfo: {
+ query: data.query
+ },
+ Body: {
+ ServiceComponentInfo: data.ServiceComponentInfo
+ }
+ })
+ }
+ }
+ },
'hosts.all.install': {
'real': '/hosts?minimal_response=true',
'mock': ''
diff --git a/ambari-web/app/utils/ember_reopen.js b/ambari-web/app/utils/ember_reopen.js
index 512b3da7de..bf091da934 100644
--- a/ambari-web/app/utils/ember_reopen.js
+++ b/ambari-web/app/utils/ember_reopen.js
@@ -242,6 +242,23 @@ Ember.TextArea.reopen({
attributeBindings: ['readonly']
});
+/**
+ * Simply converts query string to object.
+ *
+ * @param {string} queryString query string e.g. '?param1=value1&param2=value2'
+ * @return {object} converted object
+ */
+function parseQueryParams(queryString) {
+ if (!queryString) {
+ return {};
+ }
+ return queryString.replace(/^\?/, '').split('&').map(decodeURIComponent)
+ .reduce(function(p, c) {
+ var keyVal = c.split('=');
+ p[keyVal[0]] = keyVal[1];
+ return p;
+ }, {});
+};
Ember.Route.reopen({
/**
@@ -257,6 +274,35 @@ Ember.Route.reopen({
*/
exitRoute: function (router, context, callback) {
callback();
+ },
+
+ /**
+ * Query Params serializer. This method should be used inside <code>serialize</code> method.
+ * You need to specify `:query` dynamic sygment in your route's <code>route</code> attribute
+ * e.g. Em.Route.extend({ route: '/login:query'}) and return result of this method.
+ * This method will set <code>serializedQuery</code> property to specified controller by name.
+ * For concrete example see `app/routes/main.js`.
+ *
+ * @example
+ * queryParams: Em.Route.extend({
+ * route: '/queryDemo:query',
+ * serialize: function(route, params) {
+ * return this.serializeQueryParams(route, params, 'controllerNameToSetQueryObject');
+ * }
+ * });
+ * // now when navigated to http://example.com/#/queryDemo?param1=value1&param2=value2
+ * // App.router.get('controllerNameToSetQueryObject').get('serializedQuery')
+ * // will return { param1: 'value1', param2: 'value2' }
+ *
+ * @param {Em.Router} router router instance passed to <code>serialize</code> method
+ * @param {object} params dynamic segment passed to <code>seriazlie</code>
+ * @param {string} controllerName name of the controller to set `serializedQuery` as result
+ * @return {object}
+ */
+ serializeQueryParams: function(router, params, controllerName) {
+ var controller = router.get(controllerName);
+ controller.set('serializedQuery', parseQueryParams(params ? params.query : ''));
+ return params || { query: ''};
}
});
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 570f6cd078..2440086773 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -128,6 +128,7 @@ require('views/main/host/summary');
require('views/main/host/configs');
require('views/main/host/configs_service');
require('views/main/host/configs_service_menu');
+require('views/main/host/log_metrics');
require('views/main/host/metrics');
require('views/main/host/stack_versions_view');
require('views/main/host/add_view');
@@ -141,6 +142,7 @@ require('views/main/host/metrics/processes');
require('views/main/host/addHost/step4_view');
require('views/main/admin');
require('views/main/admin/service_auto_start');
+require('views/main/admin/service_auto_start/component_auto_start');
require('views/main/admin/highAvailability/nameNode/wizard_view');
require('views/main/admin/highAvailability/progress_view');
require('views/main/admin/highAvailability/nameNode/rollback_view');
diff --git a/ambari-web/app/views/common/chart/pie.js b/ambari-web/app/views/common/chart/pie.js
index 0280f87452..ce9bda4b48 100644
--- a/ambari-web/app/views/common/chart/pie.js
+++ b/ambari-web/app/views/common/chart/pie.js
@@ -82,16 +82,15 @@ App.ChartPieView = Em.View.extend({
.append("svg:g")
.attr("transform", "translate(" + thisChart.get('w') / 2 + "," + thisChart.get('h') / 2 + ")"));
- this.set('arcs', thisChart.get('svg').selectAll("path")
+ this.set('arcs', thisChart.get('svg').selectAll(".arc")
.data(thisChart.donut(thisChart.get('data')))
- .enter().append("svg:path")
+ .enter()
+ .append("svg:g").attr('class', 'arc')
+ .append('svg:path')
.attr("fill", function (d, i) {
return thisChart.palette.color(i);
})
.attr("d", thisChart.get('arc'))
-
);
-
}
-
-}); \ No newline at end of file
+});
diff --git a/ambari-web/app/views/common/widget/graph_widget_view.js b/ambari-web/app/views/common/widget/graph_widget_view.js
index da30dca302..6feaa28d5d 100644
--- a/ambari-web/app/views/common/widget/graph_widget_view.js
+++ b/ambari-web/app/views/common/widget/graph_widget_view.js
@@ -311,7 +311,9 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, {
self.set('parentView.isExportMenuHidden', true);
});
this.setYAxisFormatter();
- this.loadData();
+ if (!arguments.length || this.get('parentView.data.length')) {
+ this.loadData();
+ }
var self = this;
Em.run.next(function () {
if (self.get('isPreview')) {
diff --git a/ambari-web/app/views/main/admin/service_auto_start.js b/ambari-web/app/views/main/admin/service_auto_start.js
index 2d3ae16e6c..dcbbfc93e2 100644
--- a/ambari-web/app/views/main/admin/service_auto_start.js
+++ b/ambari-web/app/views/main/admin/service_auto_start.js
@@ -28,7 +28,7 @@ App.MainAdminServiceAutoStartView = Em.View.extend({
*/
switcherValue: false,
- clusterConfigs: null,
+ savedRecoveryEnabled: false,
didInsertElement: function () {
var self = this;
@@ -41,12 +41,14 @@ App.MainAdminServiceAutoStartView = Em.View.extend({
}
];
App.router.get('configurationController').getConfigsByTags(tag).done(function (data) {
- self.set('clusterConfigs', data[0].properties);
- self.set('switcherValue', self.get('clusterConfigs.recovery_enabled') === 'true');
+ self.set('controller.clusterConfigs', data[0].properties);
+ self.set('switcherValue', data[0].properties.recovery_enabled === 'true');
+ self.set('savedRecoveryEnabled', self.get('switcherValue'));
// plugin should be initiated after applying binding for switcherValue
Em.run.later('sync', function() {
self.initSwitcher();
}.bind(self), 10);
+ self.get('controller').loadComponentsConfigs();
});
});
},
@@ -58,8 +60,8 @@ App.MainAdminServiceAutoStartView = Em.View.extend({
*/
updateClusterConfigs: function (state){
this.set('switcherValue', state);
- this.set('clusterConfigs.recovery_enabled', '' + state);
- this.get('controller').saveClusterConfigs(this.get('clusterConfigs'));
+ this.set('controller.clusterConfigs.recovery_enabled', '' + state);
+ this.set('controller.valueChanged', this.get('savedRecoveryEnabled') !== state);
},
/**
@@ -70,7 +72,7 @@ App.MainAdminServiceAutoStartView = Em.View.extend({
initSwitcher: function () {
var self = this;
if (this.$()) {
- var switcher = this.$("input:eq(0)").bootstrapSwitch({
+ this.$("input:eq(0)").bootstrapSwitch({
onText: Em.I18n.t('common.enabled'),
offText: Em.I18n.t('common.disabled'),
offColor: 'default',
diff --git a/ambari-web/app/views/main/admin/service_auto_start/component_auto_start.js b/ambari-web/app/views/main/admin/service_auto_start/component_auto_start.js
new file mode 100644
index 0000000000..cc910b8f57
--- /dev/null
+++ b/ambari-web/app/views/main/admin/service_auto_start/component_auto_start.js
@@ -0,0 +1,57 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.MainAdminServiceAutoStartComponentView = Em.View.extend({
+ templateName: require('templates/main/admin/service_auto_start/component_auto_start'),
+
+ recoveryEnabled: false,
+ savedRecoveryEnabled: false,
+ tab: null,
+ component: null,
+
+ didInsertElement: function () {
+ this.set('savedRecoveryEnabled', this.get('recoveryEnabled'));
+ this.initSwitcher();
+ },
+
+ /**
+ * Init switcher plugin.
+ *
+ * @method initSwitcher
+ */
+ initSwitcher: function () {
+ var self = this;
+ if (this.$()) {
+ this.$("input:eq(0)").bootstrapSwitch({
+ onText: Em.I18n.t('common.enabled'),
+ offText: Em.I18n.t('common.disabled'),
+ offColor: 'default',
+ onColor: 'success',
+ handleWidth: Math.max(Em.I18n.t('common.enabled').length, Em.I18n.t('common.disabled').length) * 8,
+ onSwitchChange: function (event, state) {
+ self.set('tab.enabledComponents', self.get('tab.enabledComponents') + (state ? 1 : -1));
+ self.set('recoveryEnabled', state);
+ self.set('component.valueChanged', self.get('savedRecoveryEnabled') !== state);
+ self.get('parentView.controller').checkValuesChange();
+ }
+ });
+ }
+ }
+}); \ No newline at end of file
diff --git a/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js b/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js
index 407487d0bd..eea3040cb0 100644
--- a/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js
+++ b/ambari-web/app/views/main/dashboard/cluster_metrics/cpu.js
@@ -43,21 +43,21 @@ App.ChartClusterMetricsCPU = App.ChartLinearTimeView.extend({
idle = null,
data = Em.get(jsonData, this.get('seriesTemplate.path'));
if (data) {
- for (var name in data) {
+ Object.keys(data).forEach(function (name) {
var seriesData = data[name];
if (seriesData) {
var s = {
name: name,
data: seriesData
};
- if (name.indexOf('Idle') > -1) {
+ if (name.contains('Idle')) {
//CPU idle metric should be the last in series array
idle = s;
- continue;
+ return;
}
dataArray.push(s);
}
- }
+ });
if (idle) {
dataArray.push(idle);
}
@@ -66,7 +66,7 @@ App.ChartClusterMetricsCPU = App.ChartLinearTimeView.extend({
},
colorForSeries: function (series) {
- if (Em.I18n.t('dashboard.clusterMetrics.cpu.displayNames.idle') == series.name){
+ if (series.name && series.name.contains(Em.I18n.t('dashboard.clusterMetrics.cpu.displayNames.idle'))) {
return '#CFECEC';
}
return null;
diff --git a/ambari-web/app/views/main/host/log_metrics.js b/ambari-web/app/views/main/host/log_metrics.js
new file mode 100644
index 0000000000..20f5ec6d53
--- /dev/null
+++ b/ambari-web/app/views/main/host/log_metrics.js
@@ -0,0 +1,141 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @typedef {Ember.Object} LogLevelItemObject
+ * @property {string} level level name
+ * @property {number} counter
+ */
+/**
+ * @typedef {Object} ServiceLogMetricsObject
+ * @property {App.Service} service model instance
+ * @property {LogLevelItemObject[]} logs
+ */
+App.MainHostLogMetrics = Em.View.extend({
+ templateName: require('templates/main/host/log_metrics'),
+ classNames: ['host-log-metrics'],
+
+ /**
+ * @type {ServiceLogMetricsObject[]}
+ */
+ logsData: function() {
+ var services = this.get('content').get('hostComponents').mapProperty('service').uniq();
+ var logLevels = ['fatal', 'critical', 'error', 'warning', 'info', 'debug'];
+ return services.map(function(service) {
+ var levels = logLevels.map(function(level) {
+ return Em.Object.create({
+ level: level,
+ counter: Math.ceil(Math.random()*10)
+ });
+ });
+ return Em.Object.create({
+ service: service,
+ logs: levels
+ });
+ });
+ }.property('content'),
+
+ /**
+ * @type {Ember.View} Pie Chart view
+ * @extends App.PieChartView
+ */
+ chartView: App.ChartPieView.extend({
+ classNames: ['log-metrics-chart'],
+ w: 150,
+ h: 150,
+ stroke: '#fff',
+ strokeWidth: 1,
+ levelColors: {
+ FATAL: '#B10202',
+ CRITICAL: '#E00505',
+ ERROR: App.healthStatusRed,
+ INFO: App.healthStatusGreen,
+ WARNING: App.healthStatusOrange,
+ DEBUG: '#1e61f7'
+ },
+ innerR: 36,
+ donut: d3.layout.pie().sort(null).value(function(d) { return d.get('counter'); }),
+
+ prepareChartData: function(content) {
+ this.set('data', content.get('logs'));
+ },
+
+ didInsertElement: function() {
+ this.prepareChartData(this.get('content'));
+ this._super();
+ this.appendLabels();
+ this.formatCenterText();
+ this.attachArcEvents();
+ this.colorizeArcs();
+ },
+
+ attachArcEvents: function() {
+ var self = this;
+ this.get('svg').selectAll('.arc')
+ .on('mouseover', function(d) {
+ self.get('svg').select('g.center-text').select('text')
+ .text(d.data.get('level').capitalize() + ": " + d.data.get('counter'));
+ })
+ .on('mouseout', function() {
+ self.get('svg').select('g.center-text').select('text').text('');
+ });
+ },
+
+ formatCenterText: function() {
+ this.get('svg')
+ .append('svg:g')
+ .attr('class', 'center-text')
+ .attr('render-order', 1)
+ .append('svg:text')
+ .attr('transform', "translate(0,0)")
+ .attr('text-anchor', 'middle')
+ .attr('stroke', '#000')
+ .attr('stroke-width', 0)
+ },
+
+ appendLabels: function() {
+ var labelArc = d3.svg.arc()
+ .outerRadius(this.get('outerR') - 15)
+ .innerRadius(this.get('outerR') - 15);
+ this.get('svg').selectAll('.arc')
+ .append('text')
+ .attr('transform', function(d) { return "translate(" + labelArc.centroid(d) + ")"; })
+ .attr('stroke', '#000')
+ .attr('stroke-width', 0)
+ .attr('font-size', '12px')
+ .attr('dy', '.50em')
+ .text(function(d) { return d.data.get('counter'); });
+ },
+
+ colorizeArcs: function() {
+ var self = this;
+ this.get('svg').selectAll('.arc path')
+ .attr('fill', function(d) {
+ return self.get('levelColors')[d.data.get('level').toUpperCase()];
+ });
+ }
+ }),
+
+
+ transitionByService: function(e) {
+ var service = e.context;
+ App.router.transitionTo('logs', {query: '?service_name=' + service.get('service.serviceName')});
+ }
+});
diff --git a/ambari-web/app/views/main/host/logs_view.js b/ambari-web/app/views/main/host/logs_view.js
index dfe00e410b..b51f9556ab 100644
--- a/ambari-web/app/views/main/host/logs_view.js
+++ b/ambari-web/app/views/main/host/logs_view.js
@@ -67,6 +67,10 @@ App.MainHostLogsView = App.TableView.extend({
serviceNameFilterView: filters.createSelectView({
column: 1,
fieldType: 'filter-input-width',
+ didInsertElement: function() {
+ this.setValue(Em.getWithDefault(this, 'controller.serializedQuery.service_name', ''));
+ this._super();
+ },
content: function() {
return [{
value: '',
@@ -86,6 +90,10 @@ App.MainHostLogsView = App.TableView.extend({
componentNameFilterView: filters.createSelectView({
column: 2,
fieldType: 'filter-input-width',
+ didInsertElement: function() {
+ this.setValue(Em.getWithDefault(this, 'controller.serializedQuery.component_name', ''));
+ this._super();
+ },
content: function() {
var hostName = this.get('parentView').get('host.hostName'),
hostComponents = App.HostComponent.find().filterProperty('hostName', hostName),
@@ -108,6 +116,10 @@ App.MainHostLogsView = App.TableView.extend({
fileExtensionsFilter: filters.createSelectView({
column: 3,
fieldType: 'filter-input-width',
+ didInsertElement: function() {
+ this.setValue(Em.getWithDefault(this, 'controller.serializedQuery.file_extension', ''));
+ this._super();
+ },
content: function() {
return [{
value: '',
diff --git a/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js b/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js
index 283c0af0f7..19d0c1bf57 100644
--- a/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js
@@ -699,77 +699,56 @@ describe('App.ManageAlertNotificationsController', function () {
describe("#formatNotificationAPIObject()", function () {
- var inputFields;
-
- beforeEach(function () {
- inputFields = Em.Object.create({
- name: {
- value: 'test_name'
- },
- groups: {
- value: [{id: 1}, {id: 2}, {id: 3}]
- },
- allGroups: {
- value: 'custom'
- },
- global: {
- value: false
- },
- method: {
- value: 'EMAIL'
- },
- email: {
- value: 'test1@test.test, test2@test.test,test3@test.test , test4@test.test'
- },
- severityFilter: {
- value: ['OK', 'CRITICAL']
- },
- SMTPServer: {
- value: 's1'
- },
- SMTPPort: {
- value: '25'
- },
- SMTPUseAuthentication: {
- value: "true"
- },
- SMTPUsername: {
- value: 'user'
- },
- SMTPPassword: {
- value: 'pass'
- },
- SMTPSTARTTLS: {
- value: "true"
- },
- emailFrom: {
- value: 'from'
- },
- description: {
- value: 'test_description'
- },
- host: {
- value: ''
- },
- customProperties: [
- {name: 'n1', value: 'v1'},
- {name: 'n2', value: 'v2'}
- ]
- });
- });
-
- it('should set property `ambari.dispatch-property.script` for SNMP type', function () {
- Em.set(inputFields, 'method.value', 'SNMP');
- controller.set('inputFields', inputFields);
- var result = controller.formatNotificationAPIObject();
- expect(result.AlertTarget.properties['ambari.dispatch-property.script']).to.be.equal('org.apache.ambari.contrib.snmp.script');
- });
-
- it('should not set property `ambari.dispatch-property.script` for EMAIL type', function () {
- Em.set(inputFields, 'method.value', 'EMAIL');
- controller.set('inputFields', inputFields);
- var result = controller.formatNotificationAPIObject();
- expect(result.AlertTarget.properties).to.not.have.property('ambari.dispatch-property.script');
+ var inputFields = Em.Object.create({
+ name: {
+ value: 'test_name'
+ },
+ groups: {
+ value: [{id: 1}, {id: 2}, {id: 3}]
+ },
+ allGroups: {
+ value: 'custom'
+ },
+ global: {
+ value: false
+ },
+ method: {
+ value: 'EMAIL'
+ },
+ email: {
+ value: 'test1@test.test, test2@test.test,test3@test.test , test4@test.test'
+ },
+ severityFilter: {
+ value: ['OK', 'CRITICAL']
+ },
+ SMTPServer: {
+ value: 's1'
+ },
+ SMTPPort: {
+ value: '25'
+ },
+ SMTPUseAuthentication: {
+ value: "true"
+ },
+ SMTPUsername: {
+ value: 'user'
+ },
+ SMTPPassword: {
+ value: 'pass'
+ },
+ SMTPSTARTTLS: {
+ value: "true"
+ },
+ emailFrom: {
+ value: 'from'
+ },
+ description: {
+ value: 'test_description'
+ },
+ customProperties: [
+ {name: 'n1', value: 'v1'},
+ {name: 'n2', value: 'v2'}
+ ]
});
it("should create object with properties from inputFields values", function () {
diff --git a/ambari-web/test/mixins/common/widget_mixin_test.js b/ambari-web/test/mixins/common/widget_mixin_test.js
index 00606f4512..91f628f626 100644
--- a/ambari-web/test/mixins/common/widget_mixin_test.js
+++ b/ambari-web/test/mixins/common/widget_mixin_test.js
@@ -384,6 +384,129 @@ describe('App.WidgetMixin', function () {
});
});
});
+
+ describe('#getMetricsErrorCallback()', function () {
+
+ var obj,
+ view = Em.Object.create({
+ _showMessage: Em.K
+ }),
+ cases = [
+ {
+ graphView: null,
+ metricsLength: 1,
+ showMessageCallCount: 0,
+ isExportButtonHidden: false,
+ title: 'no graph view'
+ },
+ {
+ graphView: {},
+ metricsLength: 1,
+ showMessageCallCount: 0,
+ isExportButtonHidden: false,
+ title: 'no childViews property'
+ },
+ {
+ graphView: {},
+ childViews: [],
+ metricsLength: 1,
+ showMessageCallCount: 0,
+ isExportButtonHidden: false,
+ title: 'no child views'
+ },
+ {
+ graphView: {},
+ childViews: [Em.Object.create({})],
+ metricsLength: 1,
+ showMessageCallCount: 0,
+ isExportButtonHidden: false,
+ title: 'no view with _showMessage method'
+ },
+ {
+ graphView: {},
+ childViews: [Em.Object.create({}), view],
+ metricsLength: 0,
+ showMessageCallCount: 1,
+ isExportButtonHidden: true,
+ title: 'graph view is available'
+ }
+ ],
+ messageCases = [
+ {
+ readyState: 2,
+ status: 0,
+ textStatus: 'error',
+ title: 'incomplete request'
+ },
+ {
+ readyState: 4,
+ status: 0,
+ textStatus: 'error',
+ title: 'no status code'
+ },
+ {
+ readyState: 4,
+ status: 404,
+ textStatus: '404 error',
+ title: 'status code available'
+ }
+ ];
+
+ beforeEach(function () {
+ sinon.spy(view, '_showMessage');
+ });
+
+ afterEach(function () {
+ view._showMessage.restore();
+ });
+
+ cases.forEach(function (item) {
+
+ describe(item.title, function () {
+
+ beforeEach(function () {
+ obj = Em.Object.create(App.WidgetMixin, {
+ metrics: [{}],
+ isExportButtonHidden: false,
+ graphView: item.graphView,
+ childViews: item.childViews
+ });
+ obj.getMetricsErrorCallback({});
+ });
+
+ it('metrics array', function () {
+ expect(obj.get('metrics')).to.have.length(item.metricsLength);
+ });
+
+ it('error message', function () {
+ expect(view._showMessage.callCount).to.equal(item.showMessageCallCount);
+ });
+
+ it('export button display', function () {
+ expect(obj.get('isExportButtonHidden')).to.equal(item.isExportButtonHidden);
+ });
+
+ });
+
+ });
+
+ messageCases.forEach(function (item) {
+
+ it(item.title, function () {
+ obj = Em.Object.create(App.WidgetMixin, {
+ graphView: Em.Object.create({}),
+ childViews: [view]
+ });
+ obj.getMetricsErrorCallback({
+ readyState: item.readyState,
+ status: item.status
+ }, 'error', 'Not Found');
+ expect(view._showMessage.firstCall.args).to.eql(['warn', Em.I18n.t('graphs.error.title'), Em.I18n.t('graphs.error.message').format(item.textStatus, 'Not Found')]);
+ });
+
+ });
+
+ });
});
@@ -502,6 +625,7 @@ describe('App.WidgetLoadAggregator', function () {
f1: function () {
return {
done: Em.K,
+ fail: Em.K,
complete: Em.K
}
},
diff --git a/ambari-web/test/utils/ember_reopen_test.js b/ambari-web/test/utils/ember_reopen_test.js
index eda5e81c06..aa50a50b03 100644
--- a/ambari-web/test/utils/ember_reopen_test.js
+++ b/ambari-web/test/utils/ember_reopen_test.js
@@ -78,4 +78,61 @@ describe('Ember functionality extension', function () {
});
+ describe('#Em.Route', function() {
+ describe('#serializeQueryParams', function() {
+ var route,
+ cases = [
+ {
+ m: 'No query params',
+ params: undefined,
+ e: {
+ result: {query: ''},
+ serializedQuery: {}
+ }
+ },
+ {
+ m: 'Query params ?param1=value1&param2=value2',
+ params: { query: '?param1=value1&param2=value2'},
+ e: {
+ result: {query: '?param1=value1&param2=value2'},
+ serializedQuery: {param1: 'value1', param2: 'value2'}
+ }
+ },
+ {
+ m: 'Query params with encodedComponent ?param1=value1%30&param2=value2',
+ params: { query: '?param1=value1%30&param2=value2'},
+ e: {
+ result: {query: '?param1=value1%30&param2=value2'},
+ serializedQuery: {param1: 'value10', param2: 'value2'}
+ }
+ }
+ ];
+
+ beforeEach(function() {
+ route = Ember.Route.create({
+ route: 'demo:query',
+ serialize: function(router, params) {
+ return this.serializeQueryParams(router, params, 'testController');
+ }
+ });
+ });
+
+ afterEach(function() {
+ route.destroy();
+ route = null;
+ });
+
+ cases.forEach(function(test) {
+ it(test.m, function() {
+ var ctrl = Em.Object.create({});
+ var router = Em.Object.create({
+ testController: ctrl
+ });
+ var ret = route.serialize(router, test.params);
+ expect(ret).to.be.eql(test.e.result);
+ expect(ctrl.get('serializedQuery')).to.be.eql(test.e.serializedQuery);
+ });
+ });
+ });
+ });
});
diff --git a/ambari-web/test/views/common/log_file_search_view_test.js b/ambari-web/test/views/common/log_file_search_view_test.js
index a5f940e368..ca208b30c4 100644
--- a/ambari-web/test/views/common/log_file_search_view_test.js
+++ b/ambari-web/test/views/common/log_file_search_view_test.js
@@ -32,8 +32,7 @@ describe('App.LogFileSearchView', function() {
isIncluded: !!isIncluded
});
};
-
- [
+ var cases = [
{
viewContent: {
keywordsFilterValue: 'some_keyword'