AMBARI-7159. FE: Validation errors should be more human readable
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3cec18a1 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3cec18a1 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3cec18a1 Branch: refs/heads/branch-alerts-dev Commit: 3cec18a1fc04f181665c80bc7c6e71d26ef65b05 Parents: 1c09523 Author: Srimanth Gunturi <sgunt...@hortonworks.com> Authored: Thu Sep 4 11:57:49 2014 -0700 Committer: Srimanth Gunturi <sgunt...@hortonworks.com> Committed: Thu Sep 4 16:14:30 2014 -0700 ---------------------------------------------------------------------- .../stacks/HDP/2.0.6/services/stack_advisor.py | 19 ++++--- .../stacks/2.0.6/common/test_stack_advisor.py | 54 +++++++++++++++++--- .../app/controllers/wizard/step6_controller.js | 5 +- 3 files changed, 61 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/3cec18a1/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py ---------------------------------------------------------------------- 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 d5be339..452ccbd 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 @@ -41,27 +41,32 @@ class HDP206StackAdvisor(DefaultStackAdvisor): for component in componentsList: if component["StackServiceComponents"]["cardinality"] is not None: componentName = component["StackServiceComponents"]["component_name"] + componentDisplayName = component["StackServiceComponents"]["display_name"] componentHostsCount = 0 if component["StackServiceComponents"]["hostnames"] is not None: componentHostsCount = len(component["StackServiceComponents"]["hostnames"]) cardinality = str(component["StackServiceComponents"]["cardinality"]) # cardinality types: null, 1+, 1-2, 1, ALL + message = None if "+" in cardinality: hostsMin = int(cardinality[:-1]) - hostsMax = sys.maxint + if componentHostsCount < hostsMin: + message = "At least {0} {1} components should be installed in cluster.".format(hostsMin, componentDisplayName) elif "-" in cardinality: nums = cardinality.split("-") hostsMin = int(nums[0]) hostsMax = int(nums[1]) + if componentHostsCount > hostsMax or componentHostsCount < hostsMin: + message = "Between {0} and {1} {2} components should be installed in cluster.".format(hostsMin, hostsMax, componentDisplayName) elif "ALL" == cardinality: - hostsMin = hostsCount - hostsMax = hostsCount + if componentHostsCount != hostsCount: + message = "{0} component should be installed on all hosts in cluster.".format(componentDisplayName) else: - hostsMin = int(cardinality) - hostsMax = int(cardinality) + if componentHostsCount != int(cardinality): + message = "Exactly {0} {1} components should be installed in cluster.".format(int(cardinality), componentDisplayName) - if componentHostsCount > hostsMax or componentHostsCount < hostsMin: - items.append( { "type": 'host-component', "level": 'ERROR', "message": 'Cardinality violation, cardinality={0}, hosts count={1}'.format(cardinality, str(componentHostsCount)), "component-name": str(componentName) } ) + if message is not None: + items.append({"type": 'host-component', "level": 'ERROR', "message": message, "component-name": componentName}) # Validating host-usage usedHostsListList = [component["StackServiceComponents"]["hostnames"] for component in componentsList if not self.isNotValuable(component)] http://git-wip-us.apache.org/repos/asf/ambari/blob/3cec18a1/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py index 510b439..1577730 100644 --- a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py +++ b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py @@ -108,8 +108,8 @@ class TestHDP206StackAdvisor(TestCase): { "name": "GANGLIA", "components": [ - {"name": "GANGLIA_MONITOR", "cardinality": "ALL", "category": "SLAVE", "is_master": False, "hostnames": ["host1"]}, - {"name": "GANGLIA_SERVER", "cardinality": "1-2", "category": "MASTER", "is_master": True, "hostnames": ["host2", "host1"]} + {"name": "GANGLIA_MONITOR", "display_name": "Ganglia Monitor", "cardinality": "ALL", "category": "SLAVE", "is_master": False, "hostnames": ["host1"]}, + {"name": "GANGLIA_SERVER", "display_name": "Ganglia Server", "cardinality": "1-2", "category": "MASTER", "is_master": True, "hostnames": ["host2", "host1"]} ] } ] @@ -118,7 +118,45 @@ class TestHDP206StackAdvisor(TestCase): result = self.stackAdvisor.validateComponentLayout(services, hosts) expectedItems = [ - {"message": "Cardinality violation, cardinality=ALL, hosts count=1", "level": "ERROR"} + {"message": "Ganglia Monitor component should be installed on all hosts in cluster.", "level": "ERROR"} + ] + self.assertValidationResult(expectedItems, result) + + def test_validationCardinalityExactAmount(self): + servicesInfo = [ + { + "name": "GANGLIA", + "components": [ + {"name": "GANGLIA_MONITOR", "display_name": "Ganglia Monitor", "cardinality": "2", "category": "SLAVE", "is_master": False, "hostnames": ["host1"]}, + {"name": "GANGLIA_SERVER", "display_name": "Ganglia Server", "cardinality": "2", "category": "MASTER", "is_master": True, "hostnames": ["host2", "host1"]} + ] + } + ] + services = self.prepareServices(servicesInfo) + hosts = self.prepareHosts(["host1", "host2"]) + result = self.stackAdvisor.validateComponentLayout(services, hosts) + + expectedItems = [ + {"message": "Exactly 2 Ganglia Monitor components should be installed in cluster.", "level": "ERROR"} + ] + self.assertValidationResult(expectedItems, result) + + def test_validationCardinalityAtLeast(self): + servicesInfo = [ + { + "name": "GANGLIA", + "components": [ + {"name": "GANGLIA_MONITOR", "display_name": "Ganglia Monitor", "cardinality": "1+", "category": "SLAVE", "is_master": False, "hostnames": ["host1"]}, + {"name": "GANGLIA_SERVER", "display_name": "Ganglia Server", "cardinality": "3+", "category": "MASTER", "is_master": True, "hostnames": ["host2", "host1"]} + ] + } + ] + services = self.prepareServices(servicesInfo) + hosts = self.prepareHosts(["host1", "host2"]) + result = self.stackAdvisor.validateComponentLayout(services, hosts) + + expectedItems = [ + {"message": "At least 3 Ganglia Server components should be installed in cluster.", "level": "ERROR"} ] self.assertValidationResult(expectedItems, result) @@ -166,7 +204,7 @@ class TestHDP206StackAdvisor(TestCase): { "name": "GANGLIA", "components": [ - {"name": "GANGLIA_SERVER", "cardinality": "0-1", "category": "MASTER", "is_master": True, "hostnames": ["host1", "host2"]} + {"name": "GANGLIA_SERVER", "display_name": "Ganglia Server", "cardinality": "0-1", "category": "MASTER", "is_master": True, "hostnames": ["host1", "host2"]} ] } ] @@ -175,7 +213,7 @@ class TestHDP206StackAdvisor(TestCase): result = self.stackAdvisor.validateComponentLayout(services, hosts) expectedItems = [ - {"message": "Cardinality violation, cardinality=0-1, hosts count=2", "level": "ERROR"} + {"message": "Between 0 and 1 Ganglia Server components should be installed in cluster.", "level": "ERROR"} ] self.assertValidationResult(expectedItems, result) @@ -223,8 +261,12 @@ class TestHDP206StackAdvisor(TestCase): } try: nextComponent["StackServiceComponents"]["hostnames"] = component["hostnames"] - except KeyError, err: + except KeyError: nextComponent["StackServiceComponents"]["hostnames"] = [] + try: + nextComponent["StackServiceComponents"]["display_name"] = component["display_name"] + except KeyError: + nextComponent["StackServiceComponents"]["display_name"] = component["name"] nextService["components"].append(nextComponent) services["services"].append(nextService) http://git-wip-us.apache.org/repos/asf/ambari/blob/3cec18a1/ambari-web/app/controllers/wizard/step6_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js index 5abdec6..7c7423c 100644 --- a/ambari-web/app/controllers/wizard/step6_controller.js +++ b/ambari-web/app/controllers/wizard/step6_controller.js @@ -674,11 +674,8 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, { if (component || !item['component-name']) { var details = ""; - if (component) { - details += " for " + component + " component"; - } if (item.host) { - details += " " + item.host; + details += " (" + item.host + ")"; } if (item.level === 'ERROR') {