ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jonathanhur...@apache.org
Subject ambari git commit: AMBARI-9894 - Alerts: YARN YM HA Alerts Are UNKNOWN Due to HA Redirects (jonathanhurley)
Date Wed, 04 Mar 2015 14:16:14 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 666fe656a -> fdab48d6b


AMBARI-9894 - Alerts: YARN YM HA Alerts Are UNKNOWN Due to HA Redirects (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: fdab48d6ba2efe23fd5729448b00752a61ae0059
Parents: 666fe65
Author: Jonathan Hurley <jhurley@hortonworks.com>
Authored: Tue Mar 3 12:31:29 2015 -0500
Committer: Jonathan Hurley <jhurley@hortonworks.com>
Committed: Wed Mar 4 09:16:05 2015 -0500

----------------------------------------------------------------------
 .../python/ambari_agent/alerts/base_alert.py    |  20 +-
 .../python/ambari_agent/alerts/metric_alert.py  |  30 +-
 .../src/test/python/ambari_agent/TestAlerts.py  | 675 ++++++++++---------
 .../python/ambari_commons/urllib_handlers.py    | 117 ++++
 .../common-services/YARN/2.1.0.2.0/alerts.json  |  21 +-
 .../alerts/alert_nodemanagers_summary.py        |  10 +-
 .../stacks/BIGTOP/0.8/services/YARN/alerts.json |  46 +-
 7 files changed, 572 insertions(+), 347 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 3ae3c6d..ec30570 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -129,8 +129,9 @@ class BaseAlert(object):
       if res_base_text is None:
         res_base_text = self._get_reporting_text(result_state)
 
-    except Exception as e:
-      message = "[Alert][{0}] Unable to run the alert".format(self.get_name())
+    except Exception as exception:
+      message = "[Alert][{0}] Unable to execute alert. {1}".format(
+        self.get_name(), str(exception))
       
       # print the exception if in DEBUG, otherwise just log the warning
       if logger.isEnabledFor(logging.DEBUG):
@@ -138,7 +139,7 @@ class BaseAlert(object):
       else:
         logger.warning(message)
 
-      res = (BaseAlert.RESULT_UNKNOWN, [str(e)])
+      res = (BaseAlert.RESULT_UNKNOWN, [str(exception)])
       res_base_text = "{0}"
     
     
@@ -292,7 +293,7 @@ class BaseAlert(object):
     # first thing is first; if there are HA keys then try to dynamically build
     # the property which is used to get the actual value of the uri
     # (ie dfs.namenode.http-address.c1ha.nn2)
-    if alert_uri_lookup_keys.ha_nameservice is not None:
+    if alert_uri_lookup_keys.ha_nameservice is not None or alert_uri_lookup_keys.ha_alias_key is not None:
       alert_uri = self._get_uri_from_ha_structure(alert_uri_lookup_keys)
       if alert_uri is not None:
         return alert_uri
@@ -338,7 +339,7 @@ class BaseAlert(object):
     :param alert_uri_lookup_keys:
     :return: the AlertUri named tuple if there is a valid HA URL, otherwise None
     """
-    if alert_uri_lookup_keys is None or alert_uri_lookup_keys.ha_nameservice is None:
+    if alert_uri_lookup_keys is None:
       return None
 
     logger.debug("[Alert][{0}] HA URI structure detected in definition, attempting to lookup dynamic HA properties".format(self.get_name()))
@@ -378,9 +379,16 @@ class BaseAlert(object):
 
       return None
 
+    if self.HA_NAMESERVICE_PARAM in ha_pattern and ha_nameservice is None:
+      logger.warning("[Alert][{0}] An HA URI pattern of {1} was detected, but there is no nameservice key".format(
+        self.get_name(), ha_pattern))
+
+      return None
+
     # convert dfs.namenode.http-address.{{ha-nameservice}}.{{alias}} into
     # dfs.namenode.http-address.c1ha.{{alias}}
-    ha_pattern = ha_pattern.replace(self.HA_NAMESERVICE_PARAM, ha_nameservice)
+    if ha_nameservice is not None:
+      ha_pattern = ha_pattern.replace(self.HA_NAMESERVICE_PARAM, ha_nameservice)
 
     # for each alias, grab it and check to see if this host matches
     for alias in ha_nameservice_alias.split(','):

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
index d378254..83dc54d 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
@@ -24,7 +24,9 @@ import logging
 import re
 import urllib2
 import uuid
+
 from alerts.base_alert import BaseAlert
+from ambari_commons.urllib_handlers import RefreshHeaderProcessor
 from resource_management.libraries.functions.get_port_from_url import get_port_from_url
 
 logger = logging.getLogger()
@@ -69,7 +71,6 @@ class MetricAlert(BaseAlert):
       pass
 
     collect_result = None
-    check_value = None
     value_list = []
 
     if isinstance(self.metric_info, JmxMetric):
@@ -142,20 +143,29 @@ class MetricAlert(BaseAlert):
     
   def _load_jmx(self, ssl, host, port, jmx_metric):
     """ creates a JmxMetric object that holds info about jmx-based metrics """
-    
-    logger.debug(str(jmx_metric.property_map))
-    
     value_list = []
 
-    for k, v in jmx_metric.property_map.iteritems():
+    if logger.isEnabledFor(logging.DEBUG):
+      logger.debug(str(jmx_metric.property_map))
+
+    for jmx_property_key, jmx_property_value in jmx_metric.property_map.iteritems():
       url = "{0}://{1}:{2}/jmx?qry={3}".format(
-        "https" if ssl else "http", host, str(port), k)
-        
-      response = urllib2.urlopen(url)
-      json_response = json.loads(response.read())
+        "https" if ssl else "http", host, str(port), jmx_property_key)
+
+      # use a customer header processor that will look for the non-standard
+      # "Refresh" header and attempt to follow the redirect
+      url_opener = urllib2.build_opener(RefreshHeaderProcessor())
+      response = url_opener.open(url)
+
+      content = response.read()
+
+      json_response = json.loads(content)
       json_data = json_response['beans'][0]
       
-      for attr in v:
+      for attr in jmx_property_value:
+        if attr not in json_data:
+          raise Exception("Unable to find {0} in JSON from {1} ".format(attr, url))
+
         value_list.append(json_data[attr])
         
     return value_list

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
index e9e106d..3133c57 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
@@ -21,6 +21,7 @@ limitations under the License.
 import os
 import socket
 import sys
+import urllib2
 
 from ambari_agent.AlertSchedulerHandler import AlertSchedulerHandler
 from ambari_agent.alerts.collector import AlertCollector
@@ -31,6 +32,7 @@ from ambari_agent.alerts.script_alert import ScriptAlert
 from ambari_agent.alerts.web_alert import WebAlert
 from ambari_agent.apscheduler.scheduler import Scheduler
 from ambari_agent.ClusterConfiguration import ClusterConfiguration
+from ambari_commons.urllib_handlers import RefreshHeaderProcessor
 
 from collections import namedtuple
 from mock.mock import MagicMock, patch
@@ -68,33 +70,7 @@ class TestAlerts(TestCase):
   @patch('time.time')
   @patch.object(socket.socket,"connect")
   def test_port_alert(self, socket_connect_mock, time_mock):
-    definition_json = { "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "PORT",
-        "uri": "{{hdfs-site/my-key}}",
-        "default_port": 50070,
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
-          },
-          "warning": {
-            "text": "(Unit Tests) TCP WARN - {0:.4f} response time on port {1}",
-            "value": 1.5
-          },
-          "critical": {
-            "text": "(Unit Tests) Could not load process info: {0}",
-            "value": 5.0
-          }
-        }
-      }
-    }
+    definition_json = self._get_port_alert_definition()
 
     configuration = { 'hdfs-site' : { 'my-key': 'value1' } }
 
@@ -136,28 +112,7 @@ class TestAlerts(TestCase):
 
   @patch.object(socket.socket,"connect")
   def test_port_alert_complex_uri(self, socket_connect_mock):
-    definition_json = { "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "PORT",
-        "uri": "{{hdfs-site/my-key}}",
-        "default_port": 50070,
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
-          },
-          "critical": {
-            "text": "(Unit Tests) Could not load process info: {0}"
-          }
-        }
-      }
-    }
+    definition_json = self._get_port_alert_definition()
 
     configuration = {'hdfs-site' :
       { 'my-key': 'c6401.ambari.apache.org:2181,c6402.ambari.apache.org:2181,c6403.ambari.apache.org:2181'}
@@ -222,20 +177,7 @@ class TestAlerts(TestCase):
 
 
   def test_script_alert(self):
-    definition_json = {
-      "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "SCRIPT",
-        "path": "test_script.py",
-      }
-    }
+    definition_json = self._get_script_alert_definition()
 
     # normally set by AlertSchedulerHandler
     definition_json['source']['stacks_directory'] = os.path.join('ambari_agent', 'dummy_files')
@@ -270,47 +212,9 @@ class TestAlerts(TestCase):
 
   @patch.object(MetricAlert, "_load_jmx")
   def test_metric_alert(self, ma_load_jmx_mock):
-    definition_json = {
-      "name": "cpu_check",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "METRIC",
-        "uri": {
-          "http": "{{hdfs-site/dfs.datanode.http.address}}"
-        },
-        "jmx": {
-          "property_list": [
-            "someJmxObject/value",
-            "someOtherJmxObject/value"
-          ],
-          "value": "{0} * 100 + 123"
-        },
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) ok_arr: {0} {1} {2}",
-          },
-          "warning": {
-            "text": "",
-            "value": 13
-          },
-          "critical": {
-            "text": "(Unit Tests) crit_arr: {0} {1} {2}",
-            "value": 72
-          }
-        }
-      }
-    }
-
-    ma_load_jmx_mock.return_value = [1, 3]
-
+    definition_json = self._get_metric_alert_definition()
     configuration = {'hdfs-site' :
-      { 'dfs.datanode.http.address': '1.2.3.4:80'}
+      { 'dfs.datanode.http.address': 'c6401.ambari.apache.org:80'}
     }
 
     collector = AlertCollector()
@@ -321,13 +225,32 @@ class TestAlerts(TestCase):
     alert.set_helpers(collector, cluster_configuration)
     alert.set_cluster("c1", "c6401.ambari.apache.org")
 
+    # trip an OK
+    ma_load_jmx_mock.return_value = [1, 25]
+
+    alert.collect()
+    alerts = collector.alerts()
+    self.assertEquals(0, len(collector.alerts()))
+    self.assertEquals('OK', alerts[0]['state'])
+    self.assertEquals('(Unit Tests) OK: 1 25 125', alerts[0]['text'])
+
+    # trip a warning
+    ma_load_jmx_mock.return_value = [1, 75]
+
+    alert.collect()
+    alerts = collector.alerts()
+    self.assertEquals(0, len(collector.alerts()))
+    self.assertEquals('WARNING', alerts[0]['state'])
+    self.assertEquals('(Unit Tests) Warning: 1 75 175', alerts[0]['text'])
+
+    # trip a critical now
+    ma_load_jmx_mock.return_value = [1, 150]
+
     alert.collect()
-    
     alerts = collector.alerts()
     self.assertEquals(0, len(collector.alerts()))
-    
     self.assertEquals('CRITICAL', alerts[0]['state'])
-    self.assertEquals('(Unit Tests) crit_arr: 1 3 223', alerts[0]['text'])
+    self.assertEquals('(Unit Tests) Critical: 1 150 250', alerts[0]['text'])
 
     del definition_json['source']['jmx']['value']
     collector = AlertCollector()
@@ -336,58 +259,21 @@ class TestAlerts(TestCase):
     alert.set_helpers(collector, cluster_configuration)
     alert.set_cluster("c1", "c6401.ambari.apache.org")
 
-    alert.collect()
+    # now try without any jmx value to compare to
+    ma_load_jmx_mock.return_value = [1, 25]
 
+    alert.collect()
     alerts = collector.alerts()
     self.assertEquals(0, len(collector.alerts()))
-
     self.assertEquals('OK', alerts[0]['state'])
-    self.assertEquals('(Unit Tests) ok_arr: 1 3 None', alerts[0]['text'])
+    self.assertEquals('(Unit Tests) OK: 1 25 None', alerts[0]['text'])
 
 
   @patch.object(MetricAlert, "_load_jmx")
   def test_alert_uri_structure(self, ma_load_jmx_mock):
-    definition_json = {
-      "name": "cpu_check",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "METRIC",
-        "uri": {
-          "http": "{{hdfs-site/dfs.datanode.http.address}}",
-          "https": "{{hdfs-site/dfs.datanode.https.address}}",
-          "https_property": "{{hdfs-site/dfs.http.policy}}",
-          "https_property_value": "HTTPS_ONLY"
-        },
-        "jmx": {
-          "property_list": [
-            "someJmxObject/value",
-            "someOtherJmxObject/value"
-          ],
-          "value": "{0}"
-        },
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) ok_arr: {0} {1} {2}",
-          },
-          "warning": {
-            "text": "",
-            "value": 10
-          },
-          "critical": {
-            "text": "(Unit Tests) crit_arr: {0} {1} {2}",
-            "value": 20
-          }
-        }
-      }
-    }
+    definition_json = self._get_metric_alert_definition()
 
-    ma_load_jmx_mock.return_value = [1,1]
+    ma_load_jmx_mock.return_value = [0,0]
     
     # run the alert without specifying any keys; an exception should be thrown
     # indicating that there was no URI and the result is UNKNOWN
@@ -418,7 +304,8 @@ class TestAlerts(TestCase):
     
     # set an actual property key (http)
     configuration = {'hdfs-site' :
-      { 'dfs.http.policy' : 'HTTP_ONLY', 'dfs.datanode.http.address' : '1.2.3.4:80' }
+      { 'dfs.http.policy' : 'HTTP_ONLY',
+        'dfs.datanode.http.address' : 'c6401.ambari.apache.org:80' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -433,7 +320,8 @@ class TestAlerts(TestCase):
     
     # set an actual property key (https)
     configuration = {'hdfs-site' :
-      { 'dfs.http.policy' : 'HTTP_ONLY', 'dfs.datanode.https.address' : '1.2.3.4:443' }
+      { 'dfs.http.policy' : 'HTTP_ONLY',
+        'dfs.datanode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -444,13 +332,13 @@ class TestAlerts(TestCase):
     alert.set_cluster("c1", "c6401.ambari.apache.org")
     alert.collect()
     
-    self.assertEquals('OK', collector.alerts()[0]['state'])    
+    self.assertEquals('OK', collector.alerts()[0]['state'])
 
     # set both (http and https)
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTP_ONLY',
-        'dfs.datanode.http.address' : '1.2.3.4:80',
-        'dfs.datanode.https.address' : '1.2.3.4:443' }
+        'dfs.datanode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.datanode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -466,43 +354,14 @@ class TestAlerts(TestCase):
 
   @patch.object(WebAlert, "_make_web_request")
   def test_web_alert(self, wa_make_web_request_mock):
-    definition_json = {
-      "name": "webalert_test",
-      "service": "HDFS",
-      "component": "DATANODE",
-      "label": "WebAlert Test",
-      "interval": 1,
-      "scope": "HOST",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "WEB",
-        "uri": {
-          "http": "{{hdfs-site/dfs.datanode.http.address}}",
-          "https": "{{hdfs-site/dfs.datanode.https.address}}",
-          "https_property": "{{hdfs-site/dfs.http.policy}}",
-          "https_property_value": "HTTPS_ONLY"
-        },
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) ok: {0}",
-          },
-          "warning": {
-            "text": "(Unit Tests) warning: {0}",
-          },
-          "critical": {
-            "text": "(Unit Tests) critical: {1}. {3}",
-          }
-        }
-      }
-    }
+    definition_json = self._get_web_alert_definition()
 
     WebResponse = namedtuple('WebResponse', 'status_code time_millis error_msg')
     wa_make_web_request_mock.return_value = WebResponse(200,1.234,None)
 
     # run the alert and check HTTP 200    
     configuration = {'hdfs-site' :
-      { 'dfs.datanode.http.address' : '1.2.3.4:80' }
+      { 'dfs.datanode.http.address' : 'c6401.ambari.apache.org:80' }
     }
 
     collector = AlertCollector()
@@ -550,12 +409,12 @@ class TestAlerts(TestCase):
     
     # http assertion indicating that we properly determined non-SSL
     self.assertEquals('CRITICAL', alerts[0]['state'])
-    self.assertEquals('(Unit Tests) critical: http://1.2.3.4:80. error message', alerts[0]['text'])
+    self.assertEquals('(Unit Tests) critical: http://c6401.ambari.apache.org:80. error message', alerts[0]['text'])
 
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTPS_ONLY',
-        'dfs.datanode.http.address' : '1.2.3.4:80',
-        'dfs.datanode.https.address' : '1.2.3.4:443' }
+        'dfs.datanode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.datanode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -572,7 +431,7 @@ class TestAlerts(TestCase):
     
     # SSL assertion
     self.assertEquals('CRITICAL', alerts[0]['state'])
-    self.assertEquals('(Unit Tests) critical: https://1.2.3.4:443. error message', alerts[0]['text'])
+    self.assertEquals('(Unit Tests) critical: https://c6401.ambari.apache.org:443. error message', alerts[0]['text'])
 
   def test_reschedule(self):
     test_file_path = os.path.join('ambari_agent', 'dummy_files')
@@ -594,28 +453,7 @@ class TestAlerts(TestCase):
 
 
   def test_alert_collector_purge(self):
-    definition_json = { "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "PORT",
-        "uri": "{{hdfs-site/my-key}}",
-        "default_port": 50070,
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
-          },
-          "critical": {
-            "text": "(Unit Tests) Could not load process info: {0}"
-          }
-        }
-      }
-    }
+    definition_json = self._get_port_alert_definition()
 
     configuration = {'hdfs-site' :
       { 'my-key': 'value1' }
@@ -658,28 +496,7 @@ class TestAlerts(TestCase):
 
     self.assertEquals(1, ash.get_job_count())
 
-    definition_json = { "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "PORT",
-        "uri": "{{hdfs-site/my-key}}",
-        "default_port": 50070,
-        "reporting": {
-          "ok": {
-            "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
-          },
-          "critical": {
-            "text": "(Unit Tests) Could not load process info: {0}"
-          }
-        }
-      }
-    }
+    definition_json = self._get_port_alert_definition()
 
     alert = PortAlert(definition_json, definition_json['source'])
     ash.schedule_definition(alert)
@@ -713,37 +530,14 @@ class TestAlerts(TestCase):
 
     ash.start()
 
-
     self.assertEquals(1, ash.get_job_count())
     self.assertEquals(0, len(ash._collector.alerts()))
 
     execution_commands = [ {
-        "clusterName": "c1",
-        "hostName": "c6401.ambari.apache.org",
-        "alertDefinition": {
-          "name": "namenode_process",
-          "service": "HDFS",
-          "component": "NAMENODE",
-          "label": "NameNode process",
-          "interval": 6,
-          "scope": "host",
-          "enabled": True,
-          "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-          "source": {
-            "type": "PORT",
-            "uri": "{{hdfs-site/my-key}}",
-            "default_port": 50070,
-            "reporting": {
-              "ok": {
-                "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
-              },
-              "critical": {
-                "text": "(Unit Tests) Could not load process info: {0}"
-              }
-            }
-          }
-        }
-      } ]
+      "clusterName": "c1",
+      "hostName": "c6401.ambari.apache.org",
+      "alertDefinition": self._get_port_alert_definition()
+    } ]
 
     # execute the alert immediately and verify that the collector has the result
     ash.execute_alert(execution_commands)
@@ -751,20 +545,7 @@ class TestAlerts(TestCase):
 
 
   def test_skipped_alert(self):
-    definition_json = {
-      "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "SCRIPT",
-        "path": "test_script.py",
-      }
-    }
+    definition_json = self._get_script_alert_definition()
 
     # normally set by AlertSchedulerHandler
     definition_json['source']['stacks_directory'] = os.path.join('ambari_agent', 'dummy_files')
@@ -795,20 +576,7 @@ class TestAlerts(TestCase):
 
 
   def test_default_reporting_text(self):
-    definition_json = {
-      "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "SCRIPT",
-        "path": "test_script.py",
-      }
-    }
+    definition_json = self._get_script_alert_definition()
 
     alert = ScriptAlert(definition_json, definition_json['source'], None)
     self.assertEquals(alert._get_reporting_text(alert.RESULT_OK), '{0}')
@@ -835,20 +603,7 @@ class TestAlerts(TestCase):
 
 
   def test_configuration_updates(self):
-    definition_json = {
-      "name": "namenode_process",
-      "service": "HDFS",
-      "component": "NAMENODE",
-      "label": "NameNode process",
-      "interval": 6,
-      "scope": "host",
-      "enabled": True,
-      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
-      "source": {
-        "type": "SCRIPT",
-        "path": "test_script.py",
-      }
-    }
+    definition_json = self._get_script_alert_definition()
 
     # normally set by AlertSchedulerHandler
     definition_json['source']['stacks_directory'] = os.path.join('ambari_agent', 'dummy_files')
@@ -909,8 +664,8 @@ class TestAlerts(TestCase):
     }
 
     configuration = {'hdfs-site' :
-      { 'dfs.namenode.http.address' : '1.2.3.4:80',
-        'dfs.namenode.https.address' : '1.2.3.4:443' }
+      { 'dfs.namenode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.namenode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     collector = AlertCollector()
@@ -924,13 +679,13 @@ class TestAlerts(TestCase):
     self.assertFalse(alert._check_uri_ssl_property(uri_keys))
 
     uri = alert._get_uri_from_structure(uri_keys)
-    self.assertEqual( '1.2.3.4:80', uri.uri )
+    self.assertEqual( 'c6401.ambari.apache.org:80', uri.uri )
     self.assertEqual( False, uri.is_ssl_enabled )
 
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTP_ONLY',
-        'dfs.namenode.http.address' : '1.2.3.4:80',
-        'dfs.namenode.https.address' : '1.2.3.4:443' }
+        'dfs.namenode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.namenode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -938,14 +693,14 @@ class TestAlerts(TestCase):
     self.assertFalse(alert._check_uri_ssl_property(uri_keys))
 
     uri = alert._get_uri_from_structure(uri_keys)
-    self.assertEqual( '1.2.3.4:80', uri.uri )
+    self.assertEqual( 'c6401.ambari.apache.org:80', uri.uri )
     self.assertEqual( False, uri.is_ssl_enabled )
 
     # switch to SSL
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTPS_ONLY',
-        'dfs.namenode.http.address' : '1.2.3.4:80',
-        'dfs.namenode.https.address' : '1.2.3.4:443' }
+        'dfs.namenode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.namenode.https.address' : 'c6401.ambari.apache.org:443' }
     }
 
     self.__update_cluster_configuration(cluster_configuration, configuration)
@@ -953,14 +708,14 @@ class TestAlerts(TestCase):
     self.assertTrue(alert._check_uri_ssl_property(uri_keys))
 
     uri = alert._get_uri_from_structure(uri_keys)
-    self.assertEqual( '1.2.3.4:443', uri.uri )
+    self.assertEqual( 'c6401.ambari.apache.org:443', uri.uri )
     self.assertEqual( True, uri.is_ssl_enabled )
 
     # test HA
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTP_ONLY',
-        'dfs.namenode.http.address' : '1.2.3.4:80',
-        'dfs.namenode.https.address' : '1.2.3.4:443',
+        'dfs.namenode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.namenode.https.address' : 'c6401.ambari.apache.org:443',
         'dfs.nameservices' : 'c1ha',
         'dfs.ha.namenodes.c1ha' : 'nn1, nn2',
         'dfs.namenode.http-address.c1ha.nn1' : 'c6401.ambari.apache.org:8080',
@@ -979,8 +734,8 @@ class TestAlerts(TestCase):
     # test HA SSL
     configuration = {'hdfs-site' :
       { 'dfs.http.policy' : 'HTTPS_ONLY',
-        'dfs.namenode.http.address' : '1.2.3.4:80',
-        'dfs.namenode.https.address' : '1.2.3.4:443',
+        'dfs.namenode.http.address' : 'c6401.ambari.apache.org:80',
+        'dfs.namenode.https.address' : 'c6401.ambari.apache.org:443',
         'dfs.nameservices' : 'c1ha',
         'dfs.ha.namenodes.c1ha' : 'nn1, nn2',
         'dfs.namenode.http-address.c1ha.nn1' : 'c6401.ambari.apache.org:8080',
@@ -999,6 +754,175 @@ class TestAlerts(TestCase):
     self.assertEqual( True, uri.is_ssl_enabled )
 
 
+  def test_uri_structure_parsing_without_namespace(self):
+    """
+    Tests that we can parse an HA URI that only includes an alias and
+    not a namespace
+    :return:
+    """
+    uri_structure = {
+      "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
+      "https": "{{yarn-site/yarn.resourcemanager.webapp.http.address}}",
+      "https_property": "{{yarn-site/yarn.http.policy}}",
+      "https_property_value": "HTTPS_ONLY",
+      "high_availability": {
+        "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+        "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+        "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+      }
+    }
+
+    configuration = { 'yarn-site' :
+      { 'yarn.http.policy' : 'HTTPS_ONLY',
+        'yarn.resourcemanager.webapp.address' : 'c6401.ambari.apache.org:80',
+        'yarn.resourcemanager.webapp.http.address' : 'c6401.ambari.apache.org:443',
+        'yarn.resourcemanager.webapp.address.rm1' : 'c6401.ambari.apache.org:8080',
+        'yarn.resourcemanager.webapp.https.address.rm1' : 'c6401.ambari.apache.org:8443',
+        'yarn.resourcemanager.webapp.address.rm2' : 'c6402.ambari.apache.org:8080',
+        'yarn.resourcemanager.webapp.https.address.rm2' : 'c6402.ambari.apache.org:8443',
+        'yarn.resourcemanager.ha.rm-ids' : 'rm1, rm2'
+      }
+    }
+
+    collector = AlertCollector()
+    cluster_configuration = self.__get_cluster_configuration()
+    self.__update_cluster_configuration(cluster_configuration, configuration)
+
+    alert = MockAlert()
+    alert.set_helpers(collector, cluster_configuration)
+    alert.set_cluster("c1", "c6402.ambari.apache.org")
+    uri_keys = alert._lookup_uri_property_keys(uri_structure)
+    self.assertTrue(alert._check_uri_ssl_property(uri_keys))
+
+    uri = alert._get_uri_from_structure(uri_keys)
+    self.assertEqual( 'c6402.ambari.apache.org:8443', uri.uri )
+    self.assertEqual( True, uri.is_ssl_enabled )
+
+
+  @patch('httplib.HTTPConnection')
+  @patch.object(RefreshHeaderProcessor, 'http_response')
+  def test_metric_alert_uses_refresh_processor(self, http_response_mock, http_connection_mock):
+    """
+    Tests that the RefreshHeaderProcessor is correctly chained and called
+    :param http_response_mock:
+    :param http_connection_mock:
+    :return:
+    """
+    http_conn = http_connection_mock.return_value
+    http_conn.getresponse.return_value = MagicMock(status=200)
+    http_response_mock.return_value = MagicMock(code=200)
+
+    url_opener = urllib2.build_opener(RefreshHeaderProcessor())
+    response = url_opener.open("http://foo.bar.baz/jmx")
+
+    self.assertFalse(response is None)
+    self.assertTrue(http_conn.request.called)
+    self.assertTrue(http_conn.getresponse.called)
+    self.assertTrue(http_response_mock.called)
+
+    # now we know that the refresh header is intercepting, reset the mocks
+    # and try with a METRIC alert
+    MagicMock.reset_mock(http_response_mock)
+    MagicMock.reset_mock(http_connection_mock)
+
+    definition_json = self._get_metric_alert_definition()
+
+    configuration = {'hdfs-site' :
+      { 'dfs.datanode.http.address': 'c6401.ambari.apache.org:80'}
+    }
+
+    collector = AlertCollector()
+    cluster_configuration = self.__get_cluster_configuration()
+    self.__update_cluster_configuration(cluster_configuration, configuration)
+
+    alert = MetricAlert(definition_json, definition_json['source'])
+    alert.set_helpers(collector, cluster_configuration)
+    alert.set_cluster("c1", "c6401.ambari.apache.org")
+
+    alert.collect()
+
+    self.assertFalse(response is None)
+    self.assertTrue(http_conn.request.called)
+    self.assertTrue(http_conn.getresponse.called)
+    self.assertTrue(http_response_mock.called)
+
+
+  def test_urllib2_refresh_header_processor(self):
+    from urllib2 import Request
+
+    # setup the original request
+    original_url = "http://foo.bar.baz/jmx?qry=someQuery"
+    request = Request(original_url)
+
+    # ensure that we get back a 200 with a refresh header to redirect us
+    response = MagicMock(code=200)
+    info_response = MagicMock()
+    info_response.keys.return_value = ["Refresh"]
+    info_response.getheader.return_value = "3; url=http://foobar.baz.qux:8080"
+
+    response.info.return_value = info_response
+
+    # add a mock parent to the refresh processor
+    parent_mock = MagicMock()
+    refresh_processor = RefreshHeaderProcessor()
+    refresh_processor.parent = parent_mock
+
+    # execute
+    refresh_processor.http_response(request, response)
+
+    # ensure that the parent was called with the modified URL
+    parent_mock.open.assert_called_with("http://foobar.baz.qux:8080/jmx?qry=someQuery")
+
+    # reset mocks
+    MagicMock.reset_mock(parent_mock)
+
+    # alter the refresh header to remove the time value
+    info_response.getheader.return_value = "url=http://foobar.baz.qux:8443"
+
+    # execute
+    refresh_processor.http_response(request, response)
+
+    # ensure that the parent was called with the modified URL
+    parent_mock.open.assert_called_with("http://foobar.baz.qux:8443/jmx?qry=someQuery")
+
+    # reset mocks
+    MagicMock.reset_mock(parent_mock)
+
+    # use an invalid refresh header
+    info_response.getheader.return_value = "http://foobar.baz.qux:8443"
+
+    # execute
+    refresh_processor.http_response(request, response)
+
+    # ensure that the parent was not called
+    self.assertFalse(parent_mock.open.called)
+
+    # reset mocks
+    MagicMock.reset_mock(parent_mock)
+
+    # remove the refresh header
+    info_response.keys.return_value = ["SomeOtherHeaders"]
+
+    # execute
+    refresh_processor.http_response(request, response)
+
+    # ensure that the parent was not called
+    self.assertFalse(parent_mock.open.called)
+
+    # reset mocks
+    MagicMock.reset_mock(parent_mock)
+
+    # use and invalid http code but include a refresh header
+    response.code = 401
+    info_response.keys.return_value = ["Refresh"]
+    info_response.getheader.return_value = "3; url=http://foobar.baz.qux:8080"
+
+    # execute
+    refresh_processor.http_response(request, response)
+
+    # ensure that the parent was not called
+    self.assertFalse(parent_mock.open.called)
+
 
   def __get_cluster_configuration(self):
     """
@@ -1031,6 +955,127 @@ class TestAlerts(TestCase):
       return self.original_open(file, mode)
 
 
+  def _get_script_alert_definition(self):
+    return {
+      "name": "namenode_process",
+      "service": "HDFS",
+      "component": "NAMENODE",
+      "label": "NameNode process",
+      "interval": 6,
+      "scope": "host",
+      "enabled": True,
+      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+      "source": {
+        "type": "SCRIPT",
+        "path": "test_script.py",
+      }
+    }
+
+
+  def _get_port_alert_definition(self):
+    return { "name": "namenode_process",
+      "service": "HDFS",
+      "component": "NAMENODE",
+      "label": "NameNode process",
+      "interval": 6,
+      "scope": "host",
+      "enabled": True,
+      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+      "source": {
+        "type": "PORT",
+        "uri": "{{hdfs-site/my-key}}",
+        "default_port": 50070,
+        "reporting": {
+          "ok": {
+            "text": "(Unit Tests) TCP OK - {0:.4f} response time on port {1}"
+          },
+          "warning": {
+            "text": "(Unit Tests) TCP WARN - {0:.4f} response time on port {1}",
+            "value": 1.5
+          },
+          "critical": {
+            "text": "(Unit Tests) Could not load process info: {0}",
+            "value": 5.0
+          }
+        }
+      }
+    }
+
+
+  def _get_metric_alert_definition(self):
+    return {
+      "name": "DataNode CPU Check",
+      "service": "HDFS",
+      "component": "DATANODE",
+      "label": "DataNode Process",
+      "interval": 6,
+      "scope": "host",
+      "enabled": True,
+      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+      "source": {
+        "type": "METRIC",
+        "uri": {
+          "http": "{{hdfs-site/dfs.datanode.http.address}}",
+          "https": "{{hdfs-site/dfs.datanode.https.address}}",
+          "https_property": "{{hdfs-site/dfs.http.policy}}",
+          "https_property_value": "HTTPS_ONLY"
+        },
+        "jmx": {
+          "property_list": [
+            "someJmxObject/value",
+            "someOtherJmxObject/value"
+          ],
+          "value": "({0} * 100) + {1}"
+        },
+        "reporting": {
+          "ok": {
+            "text": "(Unit Tests) OK: {0} {1} {2}",
+          },
+          "warning": {
+            "text": "(Unit Tests) Warning: {0} {1} {2}",
+            "value": 150
+          },
+          "critical": {
+            "text": "(Unit Tests) Critical: {0} {1} {2}",
+            "value": 200
+          }
+        }
+      }
+    }
+
+
+  def _get_web_alert_definition(self):
+    return {
+      "name": "webalert_test",
+      "service": "HDFS",
+      "component": "DATANODE",
+      "label": "WebAlert Test",
+      "interval": 1,
+      "scope": "HOST",
+      "enabled": True,
+      "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+      "source": {
+        "type": "WEB",
+        "uri": {
+          "http": "{{hdfs-site/dfs.datanode.http.address}}",
+          "https": "{{hdfs-site/dfs.datanode.https.address}}",
+          "https_property": "{{hdfs-site/dfs.http.policy}}",
+          "https_property_value": "HTTPS_ONLY"
+        },
+        "reporting": {
+          "ok": {
+            "text": "(Unit Tests) ok: {0}",
+          },
+          "warning": {
+            "text": "(Unit Tests) warning: {0}",
+          },
+          "critical": {
+            "text": "(Unit Tests) critical: {1}. {3}",
+          }
+        }
+      }
+    }
+
 class MockAlert(BaseAlert):
   """
   Mock class for testing

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-common/src/main/python/ambari_commons/urllib_handlers.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/ambari_commons/urllib_handlers.py b/ambari-common/src/main/python/ambari_commons/urllib_handlers.py
new file mode 100644
index 0000000..aa2e3f6
--- /dev/null
+++ b/ambari-common/src/main/python/ambari_commons/urllib_handlers.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import logging
+import string
+
+from urllib2 import BaseHandler
+from urlparse import urlparse
+from urlparse import urlunparse
+from urlparse import ParseResult
+
+logger = logging.getLogger()
+
+REFRESH_HEADER = "refresh"
+REFRESH_HEADER_URL_KEY = "url"
+
+class RefreshHeaderProcessor(BaseHandler):
+  """
+  Examines responses from urllib2 and determines if there is a refresh header
+  that points to a different location. If there is, then build a new URL
+  swapping out the original requests's host for the redirected host and
+  re-execute the query. If at any point, the parsing fails, then return the
+  original response.
+  """
+  def __init__(self):
+    """
+    Initialization
+    :return:
+    """
+    pass
+
+  def http_response(self, request, response):
+    """
+    Inspect the http response from urllib2 and see if thers is a refresh
+    response header. If there is, then attempt to follow it and re-execute
+    the query using the new host.
+    :param request:
+    :param response:
+    :return:
+    """
+    # extract the original response code and headers
+    response_code = response.code
+
+    # unless we got back a 200 don't do any further processing
+    if response_code != 200:
+      return response
+
+    # attempt to parse and follow the refresh header if it exists
+    try:
+      response_headers = response.info()
+      refresh_header = None
+
+      for response_header_key in response_headers.keys():
+        if response_header_key.lower() == REFRESH_HEADER.lower():
+          refresh_header = response_headers.getheader(response_header_key)
+          break
+
+      if refresh_header is None:
+        return response
+
+      # at this point the header should resemble
+      # Refresh: 3; url=http://c6403.ambari.apache.org:8088/
+      semicolon_index = string.find(refresh_header, ';')
+
+      # slice the redirect URL out of
+      # 3; url=http://c6403.ambari.apache.org:8088/jmx"
+      if semicolon_index >= 0:
+        redirect_url_key_value_pair = refresh_header[semicolon_index+1:]
+      else:
+        redirect_url_key_value_pair = refresh_header
+
+      equals_index = string.find(redirect_url_key_value_pair, '=')
+      key = redirect_url_key_value_pair[:equals_index]
+      redirect_url = redirect_url_key_value_pair[equals_index+1:]
+
+      if key.strip().lower() != REFRESH_HEADER_URL_KEY:
+        logger.warning("Unable to parse refresh header {0}".format(refresh_header))
+        return response
+
+      # extract out just host:port
+      # c6403.ambari.apache.org:8088
+      redirect_netloc = urlparse(redirect_url).netloc
+
+      # deconstruct the original request URL into parts
+      original_url_parts = urlparse(request.get_full_url())
+
+      # build a brand new URL by swapping out the original request URL's
+      # netloc with the redirect's netloc
+      redirect_url = urlunparse(ParseResult(original_url_parts.scheme,
+        redirect_netloc, original_url_parts.path, original_url_parts.params,
+        original_url_parts.query, original_url_parts.fragment))
+
+      # follow the new new and return the response
+      return self.parent.open(redirect_url)
+    except Exception,exception:
+      logger.error("Unable to follow refresh header {0}. {1}".format(
+        refresh_header, str(exception)))
+
+    # return the original response
+    return response
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/alerts.json b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/alerts.json
index efef2d0..0555d76 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/alerts.json
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/alerts.json
@@ -222,7 +222,12 @@
             "https_property": "{{yarn-site/yarn.http.policy}}",
             "https_property_value": "HTTPS_ONLY",
             "kerberos_keytab": "{{yarn-site/yarn.resourcemanager.webapp.spnego-keytab-file}}",
-            "kerberos_principal": "{{yarn-site/yarn.resourcemanager.webapp.spnego-principal}}"
+            "kerberos_principal": "{{yarn-site/yarn.resourcemanager.webapp.spnego-principal}}",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }
           },
           "reporting": {
             "ok": {
@@ -250,7 +255,12 @@
             "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
             "https": "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }
           },
           "reporting": {
             "ok": {
@@ -288,7 +298,12 @@
             "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
             "https": "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }
           },
           "reporting": {
             "ok": {

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/alerts/alert_nodemanagers_summary.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/alerts/alert_nodemanagers_summary.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/alerts/alert_nodemanagers_summary.py
index 6895889..5f7abbd 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/alerts/alert_nodemanagers_summary.py
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/alerts/alert_nodemanagers_summary.py
@@ -21,6 +21,8 @@ limitations under the License.
 import urllib2
 import json
 
+from ambari_commons.urllib_handlers import RefreshHeaderProcessor
+
 ERROR_LABEL = '{0} NodeManager{1} {2} unhealthy.'
 OK_LABEL = 'All NodeManagers are healthy'
 
@@ -100,8 +102,12 @@ def execute(parameters=None, host_name=None):
   return ((result_code, [label]))
 
 
-def get_value_from_jmx(qry, property):
-  response = urllib2.urlopen(qry)
+def get_value_from_jmx(url, property):
+  # use a customer header process that will look for the non-standard
+  # "Refresh" header and attempt to follow the redirect
+  url_opener = urllib2.build_opener(RefreshHeaderProcessor())
+  response = url_opener.open(url)
+
   data=response.read()
   data_dict = json.loads(data)
   return data_dict["beans"][0][property]

http://git-wip-us.apache.org/repos/asf/ambari/blob/fdab48d6/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/YARN/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/YARN/alerts.json b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/YARN/alerts.json
index 935fd1c..886b46d 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/YARN/alerts.json
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/YARN/alerts.json
@@ -14,7 +14,9 @@
             "http": "{{mapred-site/mapreduce.jobhistory.webapp.address}}",
             "https": "{{mapred-site/mapreduce.jobhistory.webapp.https.address}}",
             "https_property": "{{mapred-site/mapreduce.jobhistory.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "kerberos_keytab": "{{mapred-site/mapreduce.jobhistory.webapp.spnego-keytab-file}}",
+            "kerberos_principal": "{{mapred-site/mapreduce.jobhistory.webapp.spnego-principal}}"
           },
           "reporting": {
             "ok": {
@@ -24,7 +26,7 @@
               "text": "HTTP {0} response in {2:.3f} seconds"
             },
             "critical": {
-              "text": "Connection failed to {1}"
+              "text": "Connection failed to {1}: {3}"
             }
           }
         }
@@ -175,7 +177,9 @@
             "https": "{{yarn-site/yarn.nodemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
             "https_property_value": "HTTPS_ONLY",
-            "default_port": 8042
+            "default_port": 8042,
+            "kerberos_keytab": "{{yarn-site/yarn.nodemanager.webapp.spnego-keytab-file}}",
+            "kerberos_principal": "{{yarn-site/yarn.nodemanager.webapp.spnego-principal}}"
           },
           "reporting": {
             "ok": {
@@ -185,7 +189,7 @@
               "text": "HTTP {0} response in {2:.3f} seconds"
             },
             "critical": {
-              "text": "Connection failed to {1}"
+              "text": "Connection failed to {1}: {3}"
             }
           }
         }
@@ -199,7 +203,7 @@
         "enabled": true,
         "source": {
           "type": "SCRIPT",
-          "path": "BIGTOP/0.8/services/YARN/package/files/alert_nodemanager_health.py"
+          "path": "YARN/2.1.0.2.0/package/alerts/alert_nodemanager_health.py"
         }
       }
     ],
@@ -216,7 +220,14 @@
             "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
             "https": "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "kerberos_keytab": "{{yarn-site/yarn.resourcemanager.webapp.spnego-keytab-file}}",
+            "kerberos_principal": "{{yarn-site/yarn.resourcemanager.webapp.spnego-principal}}",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }            
           },
           "reporting": {
             "ok": {
@@ -226,7 +237,7 @@
               "text": "HTTP {0} response in {2:.3f} seconds"
             },
             "critical": {
-              "text": "Connection failed to {1}"
+              "text": "Connection failed to {1}: {3}"
             }
           }
         }
@@ -244,7 +255,12 @@
             "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
             "https": "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }            
           },
           "reporting": {
             "ok": {
@@ -282,7 +298,12 @@
             "http": "{{yarn-site/yarn.resourcemanager.webapp.address}}",
             "https": "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "high_availability": {
+              "alias_key" : "{{yarn-site/yarn.resourcemanager.ha.rm-ids}}",
+              "http_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.address.{{alias}}}}",
+              "https_pattern" : "{{yarn-site/yarn.resourcemanager.webapp.https.address.{{alias}}}}"
+            }            
           },
           "reporting": {
             "ok": {
@@ -312,6 +333,7 @@
       {
         "name": "yarn_app_timeline_server_webui",
         "label": "App Timeline Web UI",
+        "description": "This host-level alert is triggered if the App Timeline Server Web UI is unreachable.",
         "interval": 1,
         "scope": "ANY",
         "source": {
@@ -320,7 +342,9 @@
             "http": "{{yarn-site/yarn.timeline-service.webapp.address}}",
             "https": "{{yarn-site/yarn.timeline-service.webapp.https.address}}",
             "https_property": "{{yarn-site/yarn.http.policy}}",
-            "https_property_value": "HTTPS_ONLY"
+            "https_property_value": "HTTPS_ONLY",
+            "kerberos_keytab": "{{yarn-site/yarn.timeline-service.http-authentication.kerberos.keytab}}",
+            "kerberos_principal": "{{yarn-site/yarn.timeline-service.http-authentication.kerberos.principal}}"
           },
           "reporting": {
             "ok": {
@@ -330,7 +354,7 @@
               "text": "HTTP {0} response in {2:.3f} seconds"
             },
             "critical": {
-              "text": "Connection failed to {1}"
+              "text": "Connection failed to {1}: {3}"
             }
           }
         }


Mime
View raw message