AMBARI-17939. Validations are missing for HDFS properties recommended by HAWQ. (adenissov)
diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
index 9f85518..0777dc6 100644
--- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py
@@ -139,22 +139,8 @@
     if "hdfs-site" in services["configurations"]:
       hdfs_site = services["configurations"]["hdfs-site"]["properties"]
       putHdfsSiteProperty = self.putProperty(configurations, "hdfs-site", services)
-      putHdfsSitePropertyAttribute = self.putPropertyAttribute(configurations, "hdfs-site")
 
-      hdfs_site_desired_values = {
-        "dfs.allow.truncate" : "true",
-        "dfs.block.access.token.enable" : is_secured,
-        "dfs.block.local-path-access.user" : "gpadmin",
-        "dfs.client.read.shortcircuit" : "true",
-        "dfs.client.use.legacy.blockreader.local" : "false",
-        "dfs.datanode.data.dir.perm" : "750",
-        "dfs.datanode.handler.count" : "60",
-        "dfs.datanode.max.transfer.threads" : "40960",
-        "dfs.namenode.accesstime.precision" : "0",
-        "dfs.namenode.handler.count" : "200",
-        "dfs.support.append" : "true"
-      }
-      for property, desired_value in hdfs_site_desired_values.iteritems():
+      for property, desired_value in self.getHDFSSiteDesiredValues(self.isSecurityEnabled(services)).iteritems():
         if property not in hdfs_site or hdfs_site[property] != desired_value:
           putHdfsSiteProperty(property, desired_value)
 
@@ -163,11 +149,7 @@
       core_site = services["configurations"]["core-site"]["properties"]
       putCoreSiteProperty = self.putProperty(configurations, "core-site", services)
 
-      core_site_desired_values = {
-        "ipc.client.connection.maxidletime" : "3600000",
-        "ipc.server.listen.queue.size" : "3300"
-      }
-      for property, desired_value in core_site_desired_values.iteritems():
+      for property, desired_value in self.getCORESiteDesiredValues().iteritems():
         if property not in core_site or core_site[property] != desired_value:
           putCoreSiteProperty(property, desired_value)
 
@@ -303,6 +285,19 @@
     method = self.validateHAWQHdfsClientConfigurations
     resultItems = self.validateConfigurationsForSite(configurations, recommendedDefaults, services, hosts, siteName, method)
     items.extend(resultItems)
+
+    # validate recommended properties in hdfs-site
+    siteName = "hdfs-site"
+    method = self.validateHDFSSiteConfigurations
+    resultItems = self.validateConfigurationsForSite(configurations, recommendedDefaults, services, hosts, siteName, method)
+    items.extend(resultItems)
+
+    # validate recommended properties in core-site
+    siteName = "core-site"
+    method = self.validateCORESiteConfigurations
+    resultItems = self.validateConfigurationsForSite(configurations, recommendedDefaults, services, hosts, siteName, method)
+    items.extend(resultItems)
+
     return items
 
   def isHawqMasterPortConflict(self, configurations):
@@ -416,3 +411,43 @@
         validationItems.append({"config-name": PROP_NAME, "item": self.getWarnItem(message.format(PROP_NAME, str(MIN_NUM_SEGMENT_THRESHOLD)))})
 
     return self.toConfigurationValidationProblems(validationItems, "hdfs-client")
+
+  def validateHDFSSiteConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):
+    hdfs_site = properties
+    validationItems = []
+    for property, desired_value in self.getHDFSSiteDesiredValues(self.isSecurityEnabled(services)).iteritems():
+      if property not in hdfs_site or hdfs_site[property] != desired_value:
+        message = "HAWQ requires this property to be set to the recommended value of " + desired_value
+        item = self.getErrorItem(message) if property == "dfs.allow.truncate" else self.getWarnItem(message)
+        validationItems.append({"config-name": property, "item": item})
+    return self.toConfigurationValidationProblems(validationItems, "hdfs-site")
+
+  def validateCORESiteConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):
+    core_site = properties
+    validationItems = []
+    for property, desired_value in self.getCORESiteDesiredValues().iteritems():
+      if property not in core_site or core_site[property] != desired_value:
+        message = "HAWQ requires this property to be set to the recommended value of " + desired_value
+        validationItems.append({"config-name": property, "item": self.getWarnItem(message)})
+    return self.toConfigurationValidationProblems(validationItems, "core-site")
+
+  def getHDFSSiteDesiredValues(self, is_secure):
+    hdfs_site_desired_values = {
+      "dfs.allow.truncate" : "true",
+      "dfs.block.access.token.enable" : str(is_secure).lower(),
+      "dfs.block.local-path-access.user" : "gpadmin",
+      "dfs.client.read.shortcircuit" : "true",
+      "dfs.client.use.legacy.blockreader.local" : "false",
+      "dfs.datanode.data.dir.perm" : "750",
+      "dfs.datanode.handler.count" : "60",
+      "dfs.datanode.max.transfer.threads" : "40960",
+      "dfs.namenode.accesstime.precision" : "0",
+      "dfs.support.append" : "true"
+    }
+    return hdfs_site_desired_values
+
+  def getCORESiteDesiredValues(self):
+    core_site_desired_values = {
+      "ipc.server.listen.queue.size" : "3300"
+    }
+    return core_site_desired_values
\ No newline at end of file
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
index c2c2ff6..94c3117 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py
@@ -299,11 +299,6 @@
     putHdfsSiteProperty = self.putProperty(configurations, "hdfs-site", services)
     putHdfsSitePropertyAttribute = self.putPropertyAttribute(configurations, "hdfs-site")
 
-    servicesList = [service["StackServices"]["service_name"] for service in services["services"]]
-    if "HAWQ" in servicesList:
-      # Set dfs.allow.truncate to true
-      putHdfsSiteProperty('dfs.allow.truncate', 'true')
-
     if ('ranger-hdfs-plugin-properties' in services['configurations']) and ('ranger-hdfs-plugin-enabled' in services['configurations']['ranger-hdfs-plugin-properties']['properties']):
       rangerPluginEnabled = ''
       if 'ranger-hdfs-plugin-properties' in configurations and 'ranger-hdfs-plugin-enabled' in  configurations['ranger-hdfs-plugin-properties']['properties']:
@@ -812,13 +807,6 @@
                                     "item": self.getWarnItem(
                                       "dfs.namenode.inode.attributes.provider.class needs to be set to 'org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer' if Ranger HDFS Plugin is enabled.")})
 
-    # Check if dfs.allow.truncate is true
-    if "HAWQ" in servicesList and \
-        not ("dfs.allow.truncate" in services["configurations"]["hdfs-site"]["properties"] and \
-        services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"].lower() == 'true'):
-        validationItems.append({"config-name": "dfs.allow.truncate",
-                                "item": self.getWarnItem("HAWQ requires dfs.allow.truncate in hdfs-site.xml set to True.")})
-
     validationProblems = self.toConfigurationValidationProblems(validationItems, "hdfs-site")
     validationProblems.extend(parentValidationProblems)
     return validationProblems
diff --git a/ambari-server/src/test/python/common-services/HAWQ/test_service_advisor.py b/ambari-server/src/test/python/common-services/HAWQ/test_service_advisor.py
index b3edae4..7ececa0 100644
--- a/ambari-server/src/test/python/common-services/HAWQ/test_service_advisor.py
+++ b/ambari-server/src/test/python/common-services/HAWQ/test_service_advisor.py
@@ -79,6 +79,21 @@
         service["StackServices"]["advisor_name"] = "HAWQ200ServiceAdvisor"
         service["StackServices"]["advisor_path"] = self.hawq200ServiceAdvisorPath
 
+  def getDesiredHDFSSiteValues(self, is_secure):
+    hdfs_site_desired_values = {
+      "dfs.allow.truncate" : "true",
+      "dfs.block.access.token.enable" : str(is_secure).lower(),
+      "dfs.block.local-path-access.user" : "gpadmin",
+      "dfs.client.read.shortcircuit" : "true",
+      "dfs.client.use.legacy.blockreader.local" : "false",
+      "dfs.datanode.data.dir.perm" : "750",
+      "dfs.datanode.handler.count" : "60",
+      "dfs.datanode.max.transfer.threads" : "40960",
+      "dfs.namenode.accesstime.precision" : "0",
+      "dfs.support.append" : "true"
+    }
+    return hdfs_site_desired_values
+
   @patch("socket.getfqdn")
   def test_getHostsForMasterComponent(self, getfqdn_mock):
     getfqdn_mock.return_value = "c6401.ambari.apache.org"
@@ -265,27 +280,14 @@
     }
 
     ## Test that HDFS parameters required by HAWQ are recommended
-    self.serviceAdvisor.getServiceConfigurationRecommendations(configurations, None, services, hosts)
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.allow.truncate"], "true")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.block.access.token.enable"], "false")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.block.local-path-access.user"], "gpadmin")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.client.read.shortcircuit"], "true")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.client.use.legacy.blockreader.local"], "false")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.datanode.data.dir.perm"], "750")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.datanode.handler.count"], "60")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.datanode.max.transfer.threads"], "40960")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.namenode.accesstime.precision"], "0")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.namenode.handler.count"], "200")
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.support.append"], "true")
-
-    self.assertEquals(configurations["core-site"]["properties"]["ipc.client.connection.maxidletime"], "3600000")
-    self.assertEquals(configurations["core-site"]["properties"]["ipc.server.listen.queue.size"], "3300")
-
-
     configurations["cluster-env"]["properties"]["security_enabled"]="false"
     self.serviceAdvisor.getServiceConfigurationRecommendations(configurations, None, services, hosts)
-    self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.block.access.token.enable"], "false")
+    hdfs_site_desired_values = self.getDesiredHDFSSiteValues(False)
+    for property, value in hdfs_site_desired_values.iteritems():
+      self.assertEquals(configurations["hdfs-site"]["properties"][property], value)
+    self.assertEquals(configurations["core-site"]["properties"]["ipc.server.listen.queue.size"], "3300")
 
+    # Kerberos causes 1 property to be recommended differently
     configurations["cluster-env"]["properties"]["security_enabled"]="true"
     self.serviceAdvisor.getServiceConfigurationRecommendations(configurations, None, services, hosts)
     self.assertEquals(configurations["hdfs-site"]["properties"]["dfs.block.access.token.enable"], "true")
@@ -1166,3 +1168,85 @@
     problems = self.serviceAdvisor.validateHAWQHdfsClientConfigurations(properties, defaults, configurations, services, hosts)
     self.assertEqual(len(problems), 1)
     self.assertEqual(problems[0], expected)
+
+  def test_validateHDFSSiteConfigurations(self):
+    services = {
+      "services":  [
+        { "StackServices": {"service_name": "HAWQ"},
+          "components": [{
+            "StackServiceComponents": {
+              "component_name": "HAWQSEGMENT",
+              "hostnames": []
+            }}]
+          }],
+      "configurations": {"hdfs-site": {}, "core-site": {}}
+    }
+
+    # setup default configuration values for non-kerberos case
+    configurations = services["configurations"]
+    configurations["cluster-env"] = {"properties": {"security_enabled": "false"}}
+    defaults = {}
+    hosts = {}
+    desired_values = self.getDesiredHDFSSiteValues(False)
+
+    # check all properties setup correctly in hdfs-site
+    configurations["hdfs-site"]["properties"] = desired_values.copy()
+    problems = self.serviceAdvisor.validateHDFSSiteConfigurations(configurations["hdfs-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 0)
+
+    # check overall number of validations for hdfs-site
+    configurations["hdfs-site"]["properties"] = {}
+    problems = self.serviceAdvisor.validateHDFSSiteConfigurations(configurations["hdfs-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 10)
+
+    # check individual properties
+    for property in desired_values.keys():
+      # populate all properties as to desired configuration
+      configurations["hdfs-site"]["properties"] = desired_values.copy()
+      # test when the given property is missing
+      configurations["hdfs-site"]["properties"].pop(property)
+      expected = {
+        'config-type': 'hdfs-site',
+        'message': 'HAWQ requires this property to be set to the recommended value of ' + desired_values[property],
+        'type': 'configuration',
+        'config-name': property,
+        'level': 'ERROR' if property == 'dfs.allow.truncate' else 'WARN'
+      }
+      problems = self.serviceAdvisor.validateHDFSSiteConfigurations(configurations["hdfs-site"]["properties"], defaults, configurations, services, hosts)
+      self.assertEqual(len(problems), 1)
+      self.assertEqual(problems[0], expected)
+
+      # test when the given property has a non-desired value
+      configurations["hdfs-site"]["properties"][property] = "foo"
+      problems = self.serviceAdvisor.validateHDFSSiteConfigurations(configurations["hdfs-site"]["properties"], defaults, configurations, services, hosts)
+      self.assertEqual(len(problems), 1)
+      self.assertEqual(problems[0], expected)
+
+    # check all properties setup correctly in core-site
+    configurations["core-site"]["properties"] = {"ipc.server.listen.queue.size" : "3300"}
+    problems = self.serviceAdvisor.validateCORESiteConfigurations(configurations["core-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 0)
+
+    # check overall number of validations for core-site
+    configurations["core-site"]["properties"] = {}
+    problems = self.serviceAdvisor.validateCORESiteConfigurations(configurations["core-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 1)
+
+    # check incorrect core-site property
+    expected = {
+      'config-type': 'core-site',
+      'message': 'HAWQ requires this property to be set to the recommended value of 3300',
+      'type': 'configuration',
+      'config-name': 'ipc.server.listen.queue.size',
+      'level': 'WARN'
+    }
+    configurations["core-site"]["properties"] = {"ipc.server.listen.queue.size" : "0"}
+    problems = self.serviceAdvisor.validateCORESiteConfigurations(configurations["core-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 1)
+    self.assertEqual(problems[0], expected)
+
+    # check missing core-site property
+    configurations["core-site"]["properties"].pop("ipc.server.listen.queue.size")
+    problems = self.serviceAdvisor.validateCORESiteConfigurations(configurations["core-site"]["properties"], defaults, configurations, services, hosts)
+    self.assertEqual(len(problems), 1)
+    self.assertEqual(problems[0], expected)
\ No newline at end of file
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 ff87adb..15c19d1 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
@@ -186,26 +186,6 @@
     self.stackAdvisor.recommendHDFSConfigurations(configurations, clusterData, services, hosts)
     self.assertEquals(configurations['hdfs-site']['properties']['dfs.namenode.inode.attributes.provider.class'], 'org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer', "Test with Ranger HDFS plugin is enabled")
 
-    # Test 1 for dfs.allow.truncate with no HAWQ and dfs.allow.truncate not set
-    self.stackAdvisor.recommendHDFSConfigurations(configurations, clusterData, services, hosts)
-    self.assertTrue('dfs.allow.truncate' not in configurations['hdfs-site']['properties'])
-
-    # Test 2 for dfs.allow.truncate with HAWQ and dfs.allow.truncate not set
-    services["services"].append({"StackServices" : {"service_name" : "HAWQ"}, "components":[]})
-    self.stackAdvisor.recommendHDFSConfigurations(configurations, clusterData, services, hosts)
-    self.assertEquals(configurations['hdfs-site']['properties']['dfs.allow.truncate'], 'true')
-
-    # Test 3 for dfs.allow.truncate with no HAWQ and dfs.allow.truncate set to false
-    services["services"].remove({"StackServices" : {"service_name" : "HAWQ"}, "components":[]})
-    configurations['hdfs-site']['properties']['dfs.allow.truncate'] = 'false'
-    self.stackAdvisor.recommendHDFSConfigurations(configurations, clusterData, services, hosts)
-    self.assertEquals(configurations['hdfs-site']['properties']['dfs.allow.truncate'], 'false')
-
-    # Test 4 for dfs.allow.truncate with HAWQ and dfs.allow.truncate set to false
-    services["services"].append({"StackServices" : {"service_name" : "HAWQ"}, "components":[]})
-    self.stackAdvisor.recommendHDFSConfigurations(configurations, clusterData, services, hosts)
-    self.assertEquals(configurations['hdfs-site']['properties']['dfs.allow.truncate'], 'true')
-
   def test_recommendYARNConfigurations(self):
     configurations = {}
     servicesList = ["YARN"]
@@ -1561,97 +1541,6 @@
     self.stackAdvisor.recommendRangerConfigurations(recommendedConfigurations, clusterData, services, None)
     self.assertEquals(recommendedConfigurations['ranger-admin-site']['properties']['ranger.audit.solr.zookeepers'], 'NONE')
 
-  def test_validateHDFSConfigurations(self):
-    properties = {'dfs.datanode.data.dir': '/hadoop/hdfs/data'}
-    recommendedDefaults = {}
-    configurations = {
-      "core-site": {"properties": {}},
-    }
-    services = {
-      "services": [
-        {
-          "StackServices": {
-            "service_name": "HDFS"
-          },
-          "components": [
-            {
-              "StackServiceComponents": {
-                "component_name": "NAMENODE",
-                "hostnames": ["c6401.ambari.apache.org"]
-              }
-            }
-          ]
-        },
-        {
-          "StackServices": {
-            "service_name": "HAWQ"
-          },
-          "components": [
-            {
-              "StackServiceComponents": {
-                "component_name": "HAWQMASTER",
-                "hostnames": ["c6401.ambari.apache.org"]
-              }
-            }
-          ]
-        }
-      ],
-      "configurations": configurations
-    }
-    services["configurations"]["hdfs-site"] = {}
-    services["configurations"]["hdfs-site"]["properties"] = {}
-    hosts = {}
-
-    expected_warning = {
-        'config-type':'hdfs-site',
-        'message':'HAWQ requires dfs.allow.truncate in hdfs-site.xml set to True.',
-        'type':'configuration',
-        'config-name':'dfs.allow.truncate',
-        'level':'WARN'
-    }
-
-    # Test following cases:
-    # when HAWQ is being installed and dfs.allow.truncate is not set at all, warning
-    # when HAWQ is being installed and dfs.allow.truncate is set to True, no warning
-    # when HAWQ is being installed and dfs.allow.truncate is not set to True, warning
-    # when HAWQ is not installed and dfs.allow.truncate is not set at all, no warning
-    # when HAWQ is not installed and dfs.allow.truncate is set to True, no warning
-    # when HAWQ is not installed and dfs.allow.truncate is not set to True, no warning
-    # 1
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 1)
-    self.assertEqual(problems[0], expected_warning)
-
-    # 2
-    services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"] = "True"
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 0)
-
-    # 3
-    services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"] = "false"
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 1)
-    self.assertEqual(problems[0], expected_warning)
-
-    del services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"]
-    servicesElementWithoutHAWQ = [service for service in services["services"] if service["StackServices"]["service_name"] != "HAWQ"]
-    services["services"] = servicesElementWithoutHAWQ
-
-    # 4
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 0)
-
-    # 5
-    services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"] = "True"
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 0)
-
-    # 6
-    services["configurations"]["hdfs-site"]["properties"]["dfs.allow.truncate"] = "false"
-    problems = self.stackAdvisor.validateHDFSConfigurations(properties, recommendedDefaults, configurations, services, hosts)
-    self.assertEqual(len(problems), 0)
-
-
   def test_recommendRangerKMSConfigurations(self):
     clusterData = {}
     services = {