/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.api.query.render;
import static org.easymock.EasyMock.anyLong;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.api.query.QueryInfo;
import org.apache.ambari.server.api.resources.ClusterResourceDefinition;
import org.apache.ambari.server.api.resources.HostComponentResourceDefinition;
import org.apache.ambari.server.api.resources.HostResourceDefinition;
import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.api.services.ResultImpl;
import org.apache.ambari.server.api.util.TreeNode;
import org.apache.ambari.server.api.util.TreeNodeImpl;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.controller.KerberosHelperImpl;
import org.apache.ambari.server.controller.internal.ArtifactResourceProvider;
import org.apache.ambari.server.controller.internal.ClusterControllerImpl;
import org.apache.ambari.server.controller.internal.ResourceImpl;
import org.apache.ambari.server.controller.internal.Stack;
import org.apache.ambari.server.controller.spi.ClusterController;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.cluster.ClustersImpl;
import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
import org.apache.ambari.server.topology.AmbariContext;
import org.apache.ambari.server.topology.Blueprint;
import org.apache.ambari.server.topology.ClusterTopology;
import org.apache.ambari.server.topology.Component;
import org.apache.ambari.server.topology.Configuration;
import org.apache.ambari.server.topology.HostGroup;
import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyException;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* ClusterBlueprintRenderer unit tests.
*/
@SuppressWarnings("unchecked")
@RunWith(PowerMockRunner.class)
@PrepareForTest({AmbariContext.class, AmbariServer.class})
public class ClusterBlueprintRendererTest {
private static final ClusterTopology topology = createNiceMock(ClusterTopology.class);
private static final ClusterController clusterController = createNiceMock(ClusterControllerImpl.class);
private static final AmbariContext ambariContext = createNiceMock(AmbariContext.class);
private static final Cluster cluster = createNiceMock(Cluster.class);
private static final Clusters clusters = createNiceMock(ClustersImpl.class);
private static final AmbariManagementController controller = createNiceMock(AmbariManagementControllerImpl.class);
private static final KerberosHelper kerberosHelper = createNiceMock(KerberosHelperImpl.class);
private static final KerberosDescriptor kerberosDescriptor = createNiceMock(KerberosDescriptor.class);
private static final Blueprint blueprint = createNiceMock(Blueprint.class);
private static final Stack stack = createNiceMock(Stack.class);
private static final HostGroup group1 = createNiceMock(HostGroup.class);
private static final HostGroup group2 = createNiceMock(HostGroup.class);
private static final Configuration emptyConfiguration = new Configuration(new HashMap<String, Map<String, String>>(),
new HashMap<String, Map<String, Map<String, String>>>());
private static final Map<String, Map<String, String>> clusterProps = new HashMap<>();
private static final Map<String, Map<String, Map<String, String>>> clusterAttributes =
new HashMap<>();
private static final Configuration clusterConfig = new Configuration(clusterProps, clusterAttributes);
@Before
public void setup() throws Exception {
Map<String, String> clusterTypeProps = new HashMap<>();
clusterProps.put("test-type-one", clusterTypeProps);
clusterTypeProps.put("propertyOne", "valueOne");
Map<String, Map<String, String>> clusterTypeAttributes = new HashMap<>();
clusterAttributes.put("test-type-one", clusterTypeAttributes);
Map<String, String> clusterAttributeProps = new HashMap<>();
clusterAttributeProps.put("propertyOne", "true");
clusterTypeAttributes.put("final", clusterAttributeProps);
Collection<Component> group1Components = Arrays.asList(
new Component("JOBTRACKER"), new Component("TASKTRACKER"), new Component("NAMENODE"), new Component("DATANODE"), new Component("AMBARI_SERVER"));
Collection<Component> group2Components = Arrays.asList(new Component("TASKTRACKER"), new Component("DATANODE"));
Map<String, Configuration> hostGroupConfigs = new HashMap<>();
hostGroupConfigs.put("host_group_1", emptyConfiguration);
hostGroupConfigs.put("host_group_2", emptyConfiguration);
Map<String, HostGroup> hostGroups = new HashMap<>();
hostGroups.put("host_group_1", group1);
hostGroups.put("host_group_2", group2);
HostGroupInfo group1Info = new HostGroupInfo("host_group_1");
group1Info.addHost("host1");
group1Info.setConfiguration(emptyConfiguration);
HostGroupInfo group2Info = new HostGroupInfo("host_group_2");
Map<String, HostGroupInfo> groupInfoMap = new HashMap<>();
group2Info.addHosts(Arrays.asList("host2", "host3"));
group2Info.setConfiguration(emptyConfiguration);
groupInfoMap.put("host_group_1", group1Info);
groupInfoMap.put("host_group_2", group2Info);
expect(topology.isNameNodeHAEnabled()).andReturn(false).anyTimes();
expect(topology.getConfiguration()).andReturn(clusterConfig).anyTimes();
expect(topology.getBlueprint()).andReturn(blueprint).anyTimes();
expect(topology.getHostGroupInfo()).andReturn(groupInfoMap).anyTimes();
expect(blueprint.getStack()).andReturn(stack).anyTimes();
expect(blueprint.getHostGroups()).andReturn(hostGroups).anyTimes();
expect(blueprint.getHostGroup("host_group_1")).andReturn(group1).anyTimes();
expect(blueprint.getHostGroup("host_group_2")).andReturn(group2).anyTimes();
expect(stack.getName()).andReturn("HDP").anyTimes();
expect(stack.getVersion()).andReturn("1.3.3").anyTimes();
expect(group1.getName()).andReturn("host_group_1").anyTimes();
expect(group2.getName()).andReturn("host_group_2").anyTimes();
expect(group1.getComponents()).andReturn(group1Components).anyTimes();
expect(group2.getComponents()).andReturn(group2Components).anyTimes();
expect(topology.getAmbariContext()).andReturn(ambariContext).anyTimes();
expect(topology.getClusterId()).andReturn(1L).anyTimes();
PowerMock.mockStatic(AmbariServer.class);
expect(AmbariServer.getController()).andReturn(controller).anyTimes();
PowerMock.replay(AmbariServer.class);
expect(clusters.getCluster("clusterName")).andReturn(cluster).anyTimes();
expect(controller.getKerberosHelper()).andReturn(kerberosHelper).anyTimes();
expect(controller.getClusters()).andReturn(clusters).anyTimes();
expect(kerberosHelper.getKerberosDescriptor(cluster)).andReturn(kerberosDescriptor).anyTimes();
Set<String> properties = new HashSet<String>();
properties.add("core-site/hadoop.security.auth_to_local");
expect(kerberosDescriptor.getAllAuthToLocalProperties()).andReturn(properties).anyTimes();
expect(ambariContext.getClusterName(1L)).andReturn("clusterName").anyTimes();
replay(topology, blueprint, stack, group1, group2, ambariContext, clusters, controller, kerberosHelper, cluster, kerberosDescriptor);
}
private void setupMocksForKerberosEnabledCluster() throws Exception {
AmbariContext ambariContext = createNiceMock(AmbariContext.class);
expect(ambariContext.getClusterName(anyLong())).andReturn("clusterName").anyTimes();
PowerMock.mockStatic(AmbariContext.class);
expect(AmbariContext.getClusterController()).andReturn(clusterController).anyTimes();
expect(AmbariContext.getController()).andReturn(controller).anyTimes();
reset(topology);
HostGroupInfo group1Info = new HostGroupInfo("host_group_1");
group1Info.addHost("host1");
group1Info.setConfiguration(emptyConfiguration);
HostGroupInfo group2Info = new HostGroupInfo("host_group_2");
Map<String, HostGroupInfo> groupInfoMap = new HashMap<>();
group2Info.addHosts(Arrays.asList("host2", "host3"));
group2Info.setConfiguration(emptyConfiguration);
groupInfoMap.put("host_group_1", group1Info);
groupInfoMap.put("host_group_2", group2Info);
expect(topology.isNameNodeHAEnabled()).andReturn(false).anyTimes();
expect(topology.getConfiguration()).andReturn(clusterConfig).anyTimes();
expect(topology.getBlueprint()).andReturn(blueprint).anyTimes();
expect(topology.getHostGroupInfo()).andReturn(groupInfoMap).anyTimes();
expect(topology.getClusterId()).andReturn(new Long(1)).anyTimes();
expect(topology.getAmbariContext()).andReturn(ambariContext).anyTimes();
expect(topology.isClusterKerberosEnabled()).andReturn(true).anyTimes();
ResourceProvider resourceProvider = createStrictMock(ResourceProvider.class);
expect(clusterController.ensureResourceProvider(Resource.Type.Artifact)).andReturn(resourceProvider).once();
Resource resource = createStrictMock(Resource.class);
Set<Resource> result = Collections.singleton(resource);
expect(resourceProvider.getResources((Request) anyObject(Request.class),
(Predicate) anyObject(Predicate.class))).andReturn(result).once();
Map<String, Map<String, Object>> resourcePropertiesMap = new HashMap<>();
resourcePropertiesMap.put(ArtifactResourceProvider.ARTIFACT_DATA_PROPERTY, Collections.<String, Object>emptyMap());
Map<String, Object> propertiesMap = new HashMap<>();
propertiesMap.put("testProperty", "testValue");
resourcePropertiesMap.put(ArtifactResourceProvider.ARTIFACT_DATA_PROPERTY + "/properties", propertiesMap);
expect(resource.getPropertiesMap()).andReturn(resourcePropertiesMap).once();
PowerMock.replay(AmbariContext.class);
replay(ambariContext, topology, clusterController, resource, resourceProvider);
}
@After
public void tearDown() {
verify(topology, blueprint, stack, group1, group2, ambariContext, clusters, controller, kerberosHelper, cluster, kerberosDescriptor);
reset(topology, blueprint, stack, group1, group2, ambariContext, clusters, controller, kerberosHelper, cluster, kerberosDescriptor);
}
@Test
public void testFinalizeProperties__instance() {
QueryInfo rootQuery = new QueryInfo(new ClusterResourceDefinition(), new HashSet<String>());
TreeNode<QueryInfo> queryTree = new TreeNodeImpl<>(null, rootQuery, "Cluster");
rootQuery.getProperties().add("foo/bar");
rootQuery.getProperties().add("prop1");
QueryInfo hostInfo = new QueryInfo(new HostResourceDefinition(), new HashSet<String>());
queryTree.addChild(hostInfo, "Host");
QueryInfo hostComponentInfo = new QueryInfo(new HostComponentResourceDefinition(), new HashSet<String>());
queryTree.getChild("Host").addChild(hostComponentInfo, "HostComponent");
ClusterBlueprintRenderer renderer = new ClusterBlueprintRenderer();
TreeNode<Set<String>> propertyTree = renderer.finalizeProperties(queryTree, false);
Set<String> rootProperties = propertyTree.getObject();
assertEquals(2, rootProperties.size());
assertNotNull(propertyTree.getChild("Host"));
assertTrue(propertyTree.getChild("Host").getObject().isEmpty());
assertNotNull(propertyTree.getChild("Host/HostComponent"));
assertEquals(1, propertyTree.getChild("Host/HostComponent").getObject().size());
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>());
TreeNode<QueryInfo> queryTree = new TreeNodeImpl<>(null, rootQuery, "Cluster");
rootQuery.getProperties().add("foo/bar");
rootQuery.getProperties().add("prop1");
ClusterBlueprintRenderer renderer = new ClusterBlueprintRenderer();
TreeNode<Set<String>> propertyTree = renderer.finalizeProperties(queryTree, false);
Set<String> rootProperties = propertyTree.getObject();
assertEquals(2, rootProperties.size());
assertNotNull(propertyTree.getChild("Host"));
assertTrue(propertyTree.getChild("Host").getObject().isEmpty());
assertNotNull(propertyTree.getChild("Host/HostComponent"));
assertEquals(1, propertyTree.getChild("Host/HostComponent").getObject().size());
assertTrue(propertyTree.getChild("Host/HostComponent").getObject().contains("HostRoles/component_name"));
}
@Test
public void testFinalizeResult_kerberos() throws Exception{
setupMocksForKerberosEnabledCluster();
Result result = new ResultImpl(true);
createClusterResultTree(result.getResultTree());
ClusterBlueprintRenderer renderer = new TestBlueprintRenderer(topology);
Result blueprintResult = renderer.finalizeResult(result);
TreeNode<Resource> blueprintTree = blueprintResult.getResultTree();
assertNull(blueprintTree.getStringProperty("isCollection"));
assertEquals(1, blueprintTree.getChildren().size());
TreeNode<Resource> blueprintNode = blueprintTree.getChildren().iterator().next();
assertEquals(0, blueprintNode.getChildren().size());
Resource blueprintResource = blueprintNode.getObject();
Map<String, Map<String, Object>> properties = blueprintResource.getPropertiesMap();
assertEquals("HDP", properties.get("Blueprints").get("stack_name"));
assertEquals("1.3.3", properties.get("Blueprints").get("stack_version"));
Map<String, Object> securityProperties = (Map<String, Object>) properties.get("Blueprints").get("security");
assertEquals("KERBEROS", securityProperties.get("type"));
assertNotNull(((Map<String, Object>) securityProperties.get("kerberos_descriptor")).get("properties"));
}
@Test
public void testFinalizeResult() throws Exception{
Result result = new ResultImpl(true);
createClusterResultTree(result.getResultTree());
ClusterBlueprintRenderer renderer = new TestBlueprintRenderer(topology);
Result blueprintResult = renderer.finalizeResult(result);
TreeNode<Resource> blueprintTree = blueprintResult.getResultTree();
assertNull(blueprintTree.getStringProperty("isCollection"));
assertEquals(1, blueprintTree.getChildren().size());
TreeNode<Resource> blueprintNode = blueprintTree.getChildren().iterator().next();
assertEquals(0, blueprintNode.getChildren().size());
Resource blueprintResource = blueprintNode.getObject();
Map<String, Map<String, Object>> properties = blueprintResource.getPropertiesMap();
assertEquals("HDP", properties.get("Blueprints").get("stack_name"));
assertEquals("1.3.3", properties.get("Blueprints").get("stack_version"));
Collection<Map<String, Object>> host_groups = (Collection<Map<String, Object>>) properties.get("").get("host_groups");
assertEquals(2, host_groups.size());
for (Map<String, Object> hostGroupProperties : host_groups) {
String host_group_name = (String) hostGroupProperties.get("name");
if (host_group_name.equals("host_group_1")) {
assertEquals("1", hostGroupProperties.get("cardinality"));
Collection<Map<String, String>> components = (Collection<Map<String, String>>) hostGroupProperties.get("components");
// 4 specified components and ambari server
assertEquals(5, components.size());
Set<String> expectedValues = new HashSet<>(
Arrays.asList("JOBTRACKER", "TASKTRACKER", "NAMENODE", "DATANODE", "AMBARI_SERVER"));
Set<String> actualValues = new HashSet<>();
for (Map<String, String> componentProperties : components) {
assertEquals(1, componentProperties.size());
actualValues.add(componentProperties.get("name"));
}
assertEquals(expectedValues, actualValues);
} else if (host_group_name.equals("host_group_2")) {
// cardinality is 2 because 2 hosts share same topology
assertEquals("2", hostGroupProperties.get("cardinality"));
Collection<Map<String, String>> components = (Collection<Map<String, String>>) hostGroupProperties.get("components");
assertEquals(2, components.size());
Set<String> expectedValues = new HashSet<>(
Arrays.asList("TASKTRACKER", "DATANODE"));
Set<String> actualValues = new HashSet<>();
for (Map<String, String> componentProperties : components) {
assertEquals(1, componentProperties.size());
actualValues.add(componentProperties.get("name"));
}
assertEquals(expectedValues, actualValues);
}
}
}
@Test
public void testFinalizeResultWithAttributes() throws Exception{
ServiceInfo hdfsService = new ServiceInfo();
hdfsService.setName("HDFS");
ServiceInfo mrService = new ServiceInfo();
mrService.setName("MAPREDUCE");
Result result = new ResultImpl(true);
Map<String, Object> testDesiredConfigMap =
new HashMap<>();
DesiredConfig testDesiredConfig =
new DesiredConfig();
testDesiredConfig.setTag("test-tag-one");
testDesiredConfigMap.put("test-type-one", testDesiredConfig);
createClusterResultTree(result.getResultTree(), testDesiredConfigMap);
ClusterBlueprintRenderer renderer = new TestBlueprintRenderer(topology);
Result blueprintResult = renderer.finalizeResult(result);
TreeNode<Resource> blueprintTree = blueprintResult.getResultTree();
assertNull(blueprintTree.getStringProperty("isCollection"));
assertEquals(1, blueprintTree.getChildren().size());
TreeNode<Resource> blueprintNode = blueprintTree.getChildren().iterator().next();
assertEquals(0, blueprintNode.getChildren().size());
Resource blueprintResource = blueprintNode.getObject();
Map<String, Map<String, Object>> properties = blueprintResource.getPropertiesMap();
assertEquals("HDP", properties.get("Blueprints").get("stack_name"));
assertEquals("1.3.3", properties.get("Blueprints").get("stack_version"));
Collection<Map<String, Object>> host_groups = (Collection<Map<String, Object>>) properties.get("").get("host_groups");
assertEquals(2, host_groups.size());
for (Map<String, Object> hostGroupProperties : host_groups) {
String host_group_name = (String) hostGroupProperties.get("name");
if (host_group_name.equals("host_group_1")) {
assertEquals("1", hostGroupProperties.get("cardinality"));
Collection<Map<String, String>> components = (Collection<Map<String, String>>) hostGroupProperties.get("components");
// 4 specified components and ambari server
assertEquals(5, components.size());
Set<String> expectedValues = new HashSet<>(
Arrays.asList("JOBTRACKER", "TASKTRACKER", "NAMENODE", "DATANODE", "AMBARI_SERVER"));
Set<String> actualValues = new HashSet<>();
for (Map<String, String> componentProperties : components) {
assertEquals(1, componentProperties.size());
actualValues.add(componentProperties.get("name"));
}
assertEquals(expectedValues, actualValues);
} else if (host_group_name.equals("host_group_2")) {
// cardinality is 2 because 2 hosts share same topology
assertEquals("2", hostGroupProperties.get("cardinality"));
Collection<Map<String, String>> components = (Collection<Map<String, String>>) hostGroupProperties.get("components");
assertEquals(2, components.size());
Set<String> expectedValues = new HashSet<>(
Arrays.asList("TASKTRACKER", "DATANODE"));
Set<String> actualValues = new HashSet<>();
for (Map<String, String> componentProperties : components) {
assertEquals(1, componentProperties.size());
actualValues.add(componentProperties.get("name"));
}
assertEquals(expectedValues, actualValues);
}
}
List<Map<String, Map<String, Map<String, ?>>>> configurationsResult =
(List<Map<String, Map<String, Map<String, ?>>>>)blueprintResource.getPropertyValue("configurations");
assertEquals("Incorrect number of config maps added",
1, configurationsResult.size());
Map<String, Map<String, ?>> configMap =
configurationsResult.iterator().next().get("test-type-one");
assertNotNull("Expected config map was not included", configMap);
assertEquals("Incorrect number of maps added under expected type",
2, configMap.size());
assertTrue("Expected properties map was not found",
configMap.containsKey("properties"));
assertTrue("Expected properties_attributes map was not found",
configMap.containsKey("properties_attributes"));
Map<String, ?> propertiesResult =
configMap.get("properties");
assertEquals("Incorrect number of config properties found",
1, propertiesResult.size());
Map<String, ?> attributesResult =
configMap.get("properties_attributes");
assertEquals("Incorrect number of config attributes found",
1, attributesResult.size());
// verify the correct properties were added to the exported Blueprint
assertEquals("Incorrect property value included",
"valueOne", propertiesResult.get("propertyOne"));
// verify that the expected attributes were added to the exported Blueprint
assertNotNull("Expected attribute not found in exported Blueprint",
attributesResult.get("final"));
assertTrue("Attribute type map was not included",
attributesResult.get("final") instanceof Map);
Map<String, ?> finalMap =
(Map<String, ?>)attributesResult.get("final");
assertEquals("Attribute value is not correct",
"true", finalMap.get("propertyOne"));
}
@Test
public void testClusterRendererDefaults() throws Exception {
Renderer clusterBlueprintRenderer =
new ClusterBlueprintRenderer();
assertFalse("ClusterBlueprintRenderer should not require property provider input",
clusterBlueprintRenderer.requiresPropertyProviderInput());
}
//todo: collection resource
private void createClusterResultTree(TreeNode<Resource> resultTree) throws Exception {
createClusterResultTree(resultTree, null);
}
private void createClusterResultTree(TreeNode<Resource> resultTree, final Map<String, Object> desiredConfig) throws Exception{
Resource clusterResource = new ResourceImpl(Resource.Type.Cluster) {
@Override
public Map<String, Map<String, Object>> getPropertiesMap() {
Map<String, Map<String, Object>> originalMap =
super.getPropertiesMap();
if (desiredConfig == null) {
// override the properties map for simpler testing
originalMap.put("Clusters/desired_configs", Collections.<String, Object>emptyMap());
} else {
// allow for unit tests to customize this, needed for attributes export testing
originalMap.put("Clusters/desired_configs", desiredConfig);
}
return originalMap;
}
};
clusterResource.setProperty("Clusters/cluster_name", "testCluster");
clusterResource.setProperty("Clusters/version", "HDP-1.3.3");
TreeNode<Resource> clusterTree = resultTree.addChild(clusterResource, "Cluster:1");
// add empty services resource for basic unit testing
Resource servicesResource = new ResourceImpl(Resource.Type.Service);
clusterTree.addChild(servicesResource, "services");
Resource configurationsResource = new ResourceImpl(Resource.Type.Configuration);
TreeNode<Resource> configurations = clusterTree.addChild(configurationsResource, "configurations");
Resource resourceOne = new ResourceImpl(Resource.Type.Configuration) {
@Override
public Map<String, Map<String, Object>> getPropertiesMap() {
Map<String, Map<String, Object>> originalMap =
super.getPropertiesMap();
// return null for properties, to simulate upgrade case
originalMap.put("properties", null);
return originalMap;
}
};
resourceOne.setProperty("type", "mapreduce-log4j");
configurations.addChild(resourceOne, "resourceOne");
Resource resourceTwo = new ResourceImpl(Resource.Type.Configuration) {
@Override
public Map<String, Map<String, Object>> getPropertiesMap() {
Map<String, Map<String, Object>> originalMap =
super.getPropertiesMap();
// return test properties, to simulate valid configuration entry
originalMap.put("properties", Collections.<String, Object>singletonMap("propertyOne", "valueOne"));
originalMap.put("properties_attributes", Collections.<String, Object>singletonMap("final", Collections.singletonMap("propertyOne", "true")));
return originalMap;
}
};
resourceTwo.setProperty("type", "test-type-one");
resourceTwo.setProperty("tag", "test-tag-one");
configurations.addChild(resourceTwo, "resourceTwo");
Resource blueprintOne = new ResourceImpl(Resource.Type.Blueprint);
blueprintOne.setProperty("Blueprints/blueprint_name", "blueprint-testCluster");
clusterTree.addChild(blueprintOne, "Blueprints");
TreeNode<Resource> hostsTree = clusterTree.addChild(null, "hosts");
hostsTree.setProperty("isCollection", "true");
// host 1 : ambari host
Resource hostResource = new ResourceImpl(Resource.Type.Host);
hostResource.setProperty("Hosts/host_name", getLocalHostName());
TreeNode<Resource> hostTree = hostsTree.addChild(hostResource, "Host:1");
TreeNode<Resource> hostComponentsTree = hostTree.addChild(null, "host_components");
hostComponentsTree.setProperty("isCollection", "true");
// host 1 components
Resource nnComponentResource = new ResourceImpl(Resource.Type.HostComponent);
nnComponentResource.setProperty("HostRoles/component_name", "NAMENODE");
Resource dnComponentResource = new ResourceImpl(Resource.Type.HostComponent);
dnComponentResource.setProperty("HostRoles/component_name", "DATANODE");
Resource jtComponentResource = new ResourceImpl(Resource.Type.HostComponent);
jtComponentResource.setProperty("HostRoles/component_name", "JOBTRACKER");
Resource ttComponentResource = new ResourceImpl(Resource.Type.HostComponent);
ttComponentResource.setProperty("HostRoles/component_name", "TASKTRACKER");
hostComponentsTree.addChild(nnComponentResource, "HostComponent:1");
hostComponentsTree.addChild(dnComponentResource, "HostComponent:2");
hostComponentsTree.addChild(jtComponentResource, "HostComponent:3");
hostComponentsTree.addChild(ttComponentResource, "HostComponent:4");
// host 2
Resource host2Resource = new ResourceImpl(Resource.Type.Host);
host2Resource.setProperty("Hosts/host_name", "testHost2");
TreeNode<Resource> host2Tree = hostsTree.addChild(host2Resource, "Host:2");
TreeNode<Resource> host2ComponentsTree = host2Tree.addChild(null, "host_components");
host2ComponentsTree.setProperty("isCollection", "true");
// host 2 components
host2ComponentsTree.addChild(dnComponentResource, "HostComponent:1");
host2ComponentsTree.addChild(ttComponentResource, "HostComponent:2");
// host 3 : same topology as host 2
Resource host3Resource = new ResourceImpl(Resource.Type.Host);
host3Resource.setProperty("Hosts/host_name", "testHost3");
TreeNode<Resource> host3Tree = hostsTree.addChild(host3Resource, "Host:3");
TreeNode<Resource> host3ComponentsTree = host3Tree.addChild(null, "host_components");
host3ComponentsTree.setProperty("isCollection", "true");
// host 3 components
host3ComponentsTree.addChild(dnComponentResource, "HostComponent:1");
host3ComponentsTree.addChild(ttComponentResource, "HostComponent:2");
}
private String getLocalHostName() throws UnknownHostException {
return InetAddress.getLocalHost().getHostName();
}
private static class TestBlueprintRenderer extends ClusterBlueprintRenderer {
private ClusterTopology topology;
public TestBlueprintRenderer(ClusterTopology topology) {
this.topology = topology;
}
@Override
protected ClusterTopology createClusterTopology(TreeNode<Resource> clusterNode)
throws InvalidTopologyTemplateException, InvalidTopologyException {
return topology;
}
}
}