Repository: ambari Updated Branches: refs/heads/branch-2.5 f425159e3 -> f4e65c276
AMBARI-19909. Export Blueprints does not contain the settings object and hence the credential store values (Madhuvanthi Radhakrishnan via smohanty) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f4e65c27 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f4e65c27 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f4e65c27 Branch: refs/heads/branch-2.5 Commit: f4e65c2769751e290e58951cb144b67b33678892 Parents: f425159 Author: Sumit Mohanty <smoha...@hortonworks.com> Authored: Thu Feb 9 18:39:22 2017 -0800 Committer: Sumit Mohanty <smoha...@hortonworks.com> Committed: Thu Feb 9 18:39:22 2017 -0800 ---------------------------------------------------------------------- .../query/render/ClusterBlueprintRenderer.java | 124 ++++++++++++++++ .../render/ClusterBlueprintRendererTest.java | 143 +++++++++++++++++++ 2 files changed, 267 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f4e65c27/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java index 1a9ea91..77ccc24 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRenderer.java @@ -109,6 +109,20 @@ public class ClusterBlueprintRenderer extends BaseRenderer implements Renderer { if (resultTree.getChild(serviceType) == null) { resultTree.addChild(new HashSet<String>(), serviceType); } + TreeNode<Set<String>> serviceNode = resultTree.getChild(serviceType); + if (serviceNode == null) { + serviceNode = resultTree.addChild(new HashSet<String>(), serviceType); + } + String serviceComponentType = Resource.Type.Component.name(); + TreeNode<Set<String>> serviceComponentNode = resultTree.getChild( + serviceType + "/" + serviceComponentType); + if (serviceComponentNode == null) { + serviceComponentNode = serviceNode.addChild(new HashSet<String>(), serviceComponentType); + } + serviceComponentNode.getObject().add("ServiceComponentInfo/cluster_name"); + serviceComponentNode.getObject().add("ServiceComponentInfo/service_name"); + serviceComponentNode.getObject().add("ServiceComponentInfo/component_name"); + serviceComponentNode.getObject().add("ServiceComponentInfo/recovery_enabled"); String hostType = Resource.Type.Host.name(); String hostComponentType = Resource.Type.HostComponent.name(); @@ -214,9 +228,119 @@ public class ClusterBlueprintRenderer extends BaseRenderer implements Renderer { blueprintResource.setProperty("configurations", processConfigurations(topology)); + //Fetch settings section for blueprint + blueprintResource.setProperty("settings", getSettings(clusterNode)); + return blueprintResource; } + /*** + * Constructs the Settings object of the following form: + * "settings": [ { + "recovery_settings": [ + { + "recovery_enabled": "true" + } ] }, + { + "service_settings": [ { + "name": "HDFS", + "recovery_enabled": "true", + "credential_store_enabled": "true" + }, + { + "name": "TEZ", + "recovery_enabled": "false" + }, + { + "name": "HIVE", + "recovery_enabled": "false" + } ] }, + { + "component_settings": [ { + "name": "DATANODE", + "recovery_enabled": "true" + } ] } ] + * + * @param clusterNode + * @return A Collection<Map<String, Object>> which represents the Setting Object + */ + private Collection<Map<String, Object>> getSettings(TreeNode<Resource> clusterNode) { + LOG.info("ClusterBlueprintRenderer: getSettings()"); + + //Initialize collections to create appropriate json structure + Collection<Map<String, Object>> blueprintSetting = new ArrayList<Map<String, Object>>(); + + Set<Map<String, String>> recoverySettingValue = new HashSet<Map<String, String>>(); + Set<Map<String, String>> serviceSettingValue = new HashSet<Map<String, String>>(); + Set<Map<String, String>> componentSettingValue = new HashSet<Map<String, String>>(); + + HashMap<String, String> property = new HashMap<>(); + HashMap<String, String> componentProperty = new HashMap<>(); + Boolean globalRecoveryEnabled = false; + + //Fetch the services, to obtain ServiceInfo and ServiceComponents + Collection<TreeNode<Resource>> serviceChildren = clusterNode.getChild("services").getChildren(); + for (TreeNode serviceNode : serviceChildren) { + ResourceImpl service = (ResourceImpl) serviceNode.getObject(); + Map<String, Object> ServiceInfoMap = service.getPropertiesMap().get("ServiceInfo"); + + //service_settings population + property = new HashMap<>(); + if (ServiceInfoMap.get("credential_store_supported").equals("true")) { + if (ServiceInfoMap.get("credential_store_enabled").equals("true")) { + property.put("name", ServiceInfoMap.get("service_name").toString()); + property.put("credential_store_enabled", "true"); + } + } + + //Fetch the service Components to obtain ServiceComponentInfo + Collection<TreeNode<Resource>> componentChildren = serviceNode.getChild("components").getChildren(); + for (TreeNode componentNode : componentChildren) { + ResourceImpl component = (ResourceImpl) componentNode.getObject(); + Map<String, Object> ServiceComponentInfoMap = component.getPropertiesMap().get("ServiceComponentInfo"); + + if (ServiceComponentInfoMap.get("recovery_enabled").equals("true")) { + globalRecoveryEnabled = true; + property.put("name", ServiceInfoMap.get("service_name").toString()); + property.put("recovery_enabled", "true"); + + //component_settings population + componentProperty = new HashMap<>(); + componentProperty.put("name", ServiceComponentInfoMap.get("component_name").toString()); + componentProperty.put("recovery_enabled", "true"); + } + } + + if (!property.isEmpty()) + serviceSettingValue.add(property); + if (!componentProperty.isEmpty()) + componentSettingValue.add(componentProperty); + } + //recovery_settings population + property = new HashMap<>(); + if (globalRecoveryEnabled) { + property.put("recovery_enabled", "true"); + } else { + property.put("recovery_enabled", "false"); + } + recoverySettingValue.add(property); + + //Add all the different setting values. + Map<String, Object> settingMap = new HashMap<>(); + settingMap.put("recovery_settings", recoverySettingValue); + blueprintSetting.add(settingMap); + + settingMap = new HashMap<>(); + settingMap.put("service_settings", serviceSettingValue); + blueprintSetting.add(settingMap); + + settingMap = new HashMap<>(); + settingMap.put("component_settings", componentSettingValue); + blueprintSetting.add(settingMap); + + return blueprintSetting; + } + private Map<String, Object> getKerberosDescriptor(ClusterController clusterController, String clusterName) throws AmbariException { PredicateBuilder pb = new PredicateBuilder(); Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals(clusterName).and(). http://git-wip-us.apache.org/repos/asf/ambari/blob/f4e65c27/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java index 1fe48df..a761c62 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/ClusterBlueprintRendererTest.java @@ -56,6 +56,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -238,6 +239,148 @@ public class ClusterBlueprintRendererTest { assertTrue(propertyTree.getChild("Host/HostComponent").getObject().contains("HostRoles/component_name")); } + public TreeNode<Resource> createResultTreeSettingsObject(TreeNode<Resource> resultTree){ + Resource clusterResource = new ResourceImpl(Resource.Type.Cluster); + + clusterResource.setProperty("Clusters/cluster_name", "testCluster"); + clusterResource.setProperty("Clusters/version", "HDP-1.3.3"); + + TreeNode<Resource> clusterTree = resultTree.addChild(clusterResource, "Cluster:1"); + + TreeNode<Resource> servicesTree = clusterTree.addChild(null, "services"); + servicesTree.setProperty("isCollection", "true"); + + //Scenario 1 : Service with Credential Store enabled, Recovery enabled for Component:1 and not for Component:2 + Resource serviceResource1 = new ResourceImpl(Resource.Type.Service); + serviceResource1.setProperty("ServiceInfo/service_name","Service:1"); + serviceResource1.setProperty("ServiceInfo/credential_store_supported","true"); + serviceResource1.setProperty("ServiceInfo/credential_store_enabled","true"); + TreeNode<Resource> serviceTree = servicesTree.addChild(serviceResource1, "Service:1"); + + Resource ttComponentResource = new ResourceImpl(Resource.Type.Component); + ttComponentResource.setProperty("ServiceComponentInfo/component_name", "Component:1"); + ttComponentResource.setProperty("ServiceComponentInfo/cluster_name", "testCluster"); + ttComponentResource.setProperty("ServiceComponentInfo/service_name", "Service:1"); + ttComponentResource.setProperty("ServiceComponentInfo/recovery_enabled", "true"); + + Resource dnComponentResource = new ResourceImpl(Resource.Type.Component); + dnComponentResource.setProperty("ServiceComponentInfo/component_name", "Component:2"); + dnComponentResource.setProperty("ServiceComponentInfo/cluster_name", "testCluster"); + dnComponentResource.setProperty("ServiceComponentInfo/service_name", "Service:1"); + dnComponentResource.setProperty("ServiceComponentInfo/recovery_enabled", "false"); + + TreeNode<Resource> componentsTree1 = serviceTree.addChild(null, "components"); + componentsTree1.setProperty("isCollection", "true"); + + componentsTree1.addChild(ttComponentResource, "Component:1"); + componentsTree1.addChild(dnComponentResource, "Component:2"); + + //Scenario 2 :Service with Credential Store disabled, Recovery enabled for Component:1 + Resource serviceResource2 = new ResourceImpl(Resource.Type.Service); + serviceResource2.setProperty("ServiceInfo/service_name","Service:2"); + serviceResource2.setProperty("ServiceInfo/credential_store_supported","true"); + serviceResource2.setProperty("ServiceInfo/credential_store_enabled","false"); + serviceTree = servicesTree.addChild(serviceResource2, "Service:2"); + + ttComponentResource = new ResourceImpl(Resource.Type.Component); + ttComponentResource.setProperty("ServiceComponentInfo/component_name", "Component:1"); + ttComponentResource.setProperty("ServiceComponentInfo/cluster_name", "testCluster"); + ttComponentResource.setProperty("ServiceComponentInfo/service_name", "Service:2"); + ttComponentResource.setProperty("ServiceComponentInfo/recovery_enabled", "true"); + + TreeNode<Resource> componentsTree2 = serviceTree.addChild(null, "components"); + componentsTree2.setProperty("isCollection", "true"); + + componentsTree2.addChild(ttComponentResource, "Component:1"); + + //Scenario 3 :Service with both Credential Store and Recovery enabled as false + Resource serviceResource3 = new ResourceImpl(Resource.Type.Service); + serviceResource3.setProperty("ServiceInfo/service_name","Service:3"); + serviceResource3.setProperty("ServiceInfo/credential_store_supported","false"); + serviceResource3.setProperty("ServiceInfo/credential_store_enabled","false"); + serviceTree = servicesTree.addChild(serviceResource3, "Service:3"); + + ttComponentResource = new ResourceImpl(Resource.Type.Component); + ttComponentResource.setProperty("ServiceComponentInfo/component_name", "Component:1"); + ttComponentResource.setProperty("ServiceComponentInfo/cluster_name", "testCluster"); + ttComponentResource.setProperty("ServiceComponentInfo/service_name", "Service:3"); + ttComponentResource.setProperty("ServiceComponentInfo/recovery_enabled", "false"); + + TreeNode<Resource> componentsTree3 = serviceTree.addChild(null, "components"); + componentsTree3.setProperty("isCollection", "true"); + + componentsTree3.addChild(ttComponentResource, "Component:1"); + + //Add empty configurations + Resource configurationsResource = new ResourceImpl(Resource.Type.Configuration); + clusterTree.addChild(configurationsResource, "configurations"); + + //Add empty hosts + Resource hostResource = new ResourceImpl(Resource.Type.Host); + clusterTree.addChild(hostResource, "hosts"); + + return resultTree; + } + + @Test + public void testGetSettings_instance(){ + Result result = new ResultImpl(true); + + TreeNode<Resource> resultTree = createResultTreeSettingsObject(result.getResultTree()); + + ClusterBlueprintRenderer renderer = new TestBlueprintRenderer(topology); + Result blueprintResult = renderer.finalizeResult(result); + TreeNode<Resource> blueprintTree = blueprintResult.getResultTree(); + TreeNode<Resource> blueprintNode = blueprintTree.getChildren().iterator().next(); + Resource blueprintResource = blueprintNode.getObject(); + Map<String, Map<String, Object>> propertiesMap = blueprintResource.getPropertiesMap(); + Map<String,Object> children = propertiesMap.get(""); + + //Verify if required information is present in actual result + assertTrue(children.containsKey("settings")); + + List<Map<String,Object>> settingValues = (ArrayList)children.get("settings"); + Boolean isRecoverySettings = false; + Boolean isComponentSettings = false; + Boolean isServiceSettings = false; + + //Verify actual values + for(Map<String,Object> settingProp : settingValues){ + if(settingProp.containsKey("recovery_settings")){ + isRecoverySettings = true; + HashSet<Map<String,String>> checkPropSize = (HashSet)settingProp.get("recovery_settings"); + assertEquals(1,checkPropSize.size()); + assertEquals("true",checkPropSize.iterator().next().get("recovery_enabled")); + + } + if(settingProp.containsKey("component_settings")){ + isComponentSettings = true; + HashSet<Map<String,String>> checkPropSize = (HashSet)settingProp.get("component_settings"); + assertEquals(1,checkPropSize.size()); + Map<String, String> finalProp = checkPropSize.iterator().next(); + assertEquals("Component:1",finalProp.get("name")); + assertEquals("true",finalProp.get("recovery_enabled")); + } + if(settingProp.containsKey("service_settings")){ + isServiceSettings = true; + HashSet<Map<String,String>> checkPropSize = (HashSet)settingProp.get("service_settings"); + assertEquals(2,checkPropSize.size()); + for(Map<String,String> finalProp : checkPropSize){ + if(finalProp.containsKey("credential_store_enabled")){ + assertEquals("Service:1",finalProp.get("name")); + assertEquals("true",finalProp.get("recovery_enabled")); + } + assertFalse(finalProp.get("name").equals("Service:3")); + } + } + } + //Verify if required information is present in actual result + assertTrue(isRecoverySettings); + assertTrue(isComponentSettings); + assertTrue(isServiceSettings); + + } + @Test public void testFinalizeProperties__instance_noComponentNode() { QueryInfo rootQuery = new QueryInfo(new ClusterResourceDefinition(), new HashSet<String>());