AMBARI-22325 Cluster template object initial version (benyoka)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/94712bc4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/94712bc4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/94712bc4 Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2 Commit: 94712bc41056bca596899333c3d65f494473012f Parents: c5c3c7e Author: Balazs Bence Sari <beny...@apache.org> Authored: Fri Nov 17 22:20:20 2017 +0100 Committer: Doroszlai, Attila <adorosz...@hortonworks.com> Committed: Fri Nov 24 13:30:46 2017 +0100 ---------------------------------------------------------------------- .../server/topology/BlueprintV2Factory.java | 53 ++--- .../ambari/server/topology/Credential.java | 8 +- .../topology/ProvisionClusterTemplate.java | 198 +++++++++++++++++++ .../ProvisionClusterTemplateFactory.java | 48 +++++ .../server/topology/BlueprintImplV2Test.java | 173 ++++++++++++++++ .../topology/ProvisionClusterTemplateTest.java | 30 +++ .../validators/BlueprintImplV2Test.java | 175 ---------------- .../blueprintv2/cluster_template_v2.json | 66 +++++++ 8 files changed, 552 insertions(+), 199 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Factory.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Factory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Factory.java index e16ba86..3262c54 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Factory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Factory.java @@ -56,33 +56,35 @@ public class BlueprintV2Factory { // Host Groups protected static final String HOST_GROUP_PROPERTY_ID = "host_groups"; - protected static final String HOST_GROUP_NAME_PROPERTY_ID = "name"; - protected static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality"; +// protected static final String HOST_GROUP_NAME_PROPERTY_ID = "name"; +// protected static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality"; // Host Group Components - protected static final String COMPONENT_PROPERTY_ID ="components"; +// protected static final String COMPONENT_PROPERTY_ID ="components"; protected static final String COMPONENT_NAME_PROPERTY_ID ="name"; - protected static final String COMPONENT_PROVISION_ACTION_PROPERTY_ID = "provision_action"; +// protected static final String COMPONENT_PROVISION_ACTION_PROPERTY_ID = "provision_action"; // Configurations - protected static final String CONFIGURATION_PROPERTY_ID = "configurations"; +// protected static final String CONFIGURATION_PROPERTY_ID = "configurations"; protected static final String PROPERTIES_PROPERTY_ID = "properties"; - protected static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes"; +// protected static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes"; - protected static final String SETTINGS_PROPERTY_ID = "settings"; +// protected static final String SETTINGS_PROPERTY_ID = "settings"; - private boolean prettyPrintJson = false; private static BlueprintV2DAO blueprintDAO; private static RepositoryVersionDAO repositoryVersionDAO; private StackV2Factory stackFactory; - protected BlueprintV2Factory() { + private ObjectMapper objectMapper; + protected BlueprintV2Factory() { + createObjectMapper(); } protected BlueprintV2Factory(StackV2Factory stackFactory) { this.stackFactory = stackFactory; + createObjectMapper(); } public static BlueprintV2Factory create(AmbariManagementController controller) { @@ -100,7 +102,7 @@ public class BlueprintV2Factory { } public BlueprintV2 convertFromJson(String json) throws IOException { - BlueprintImplV2 blueprintV2 = createObjectMapper().readValue(json, BlueprintImplV2.class); + BlueprintImplV2 blueprintV2 = getObjectMapper().readValue(json, BlueprintImplV2.class); blueprintV2.postDeserialization(); updateStacks(blueprintV2); return blueprintV2; @@ -119,7 +121,7 @@ public class BlueprintV2Factory { } public Map<String, Object> convertToMap(BlueprintV2Entity entity) throws IOException { - return createObjectMapper().readValue(entity.getContent(), new TypeReference<Map<String, Object>>(){}); + return getObjectMapper().readValue(entity.getContent(), new TypeReference<Map<String, Object>>(){}); } private StackV2 parseStack(StackId stackId, String repositoryVersion) { @@ -143,7 +145,7 @@ public class BlueprintV2Factory { } public String convertToJson(BlueprintV2 blueprint) throws JsonProcessingException { - return createObjectMapper().writeValueAsString(blueprint); + return getObjectMapper().writeValueAsString(blueprint); } @@ -161,7 +163,7 @@ public class BlueprintV2Factory { //todo: should throw a checked exception from here throw new IllegalArgumentException("Blueprint name must be provided"); } - ObjectMapper om = createObjectMapper(); + ObjectMapper om = getObjectMapper(); String json = om.writeValueAsString(properties); BlueprintImplV2 blueprint = om.readValue(json, BlueprintImplV2.class); blueprint.postDeserialization(); @@ -171,25 +173,30 @@ public class BlueprintV2Factory { } public boolean isPrettyPrintJson() { - return prettyPrintJson; + return objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT);; } public void setPrettyPrintJson(boolean prettyPrintJson) { - this.prettyPrintJson = prettyPrintJson; + if (prettyPrintJson) { + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + } + else { + objectMapper.disable(SerializationFeature.INDENT_OUTPUT); + } } - public ObjectMapper createObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + private void createObjectMapper() { + objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule("CustomModel", Version.unknownVersion()); SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver(); resolver.addMapping(HostGroupV2.class, HostGroupV2Impl.class); module.setAbstractTypes(resolver); - mapper.registerModule(module); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - if (prettyPrintJson) { - mapper.enable(SerializationFeature.INDENT_OUTPUT); - } - return mapper; + objectMapper.registerModule(module); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java index 3146e2f..25b9521 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java @@ -19,6 +19,8 @@ package org.apache.ambari.server.topology; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.ambari.server.security.encryption.CredentialStoreType; /** @@ -46,7 +48,11 @@ public class Credential { */ private CredentialStoreType type; - public Credential(String alias, String principal, String key, CredentialStoreType type) { + @JsonCreator + public Credential(@JsonProperty("alias") String alias, + @JsonProperty("principal") String principal, + @JsonProperty("key") String key, + @JsonProperty("type") CredentialStoreType type) { this.alias = alias; this.principal = principal; this.key = key; http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplate.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplate.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplate.java new file mode 100644 index 0000000..60f0fc2 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplate.java @@ -0,0 +1,198 @@ +package org.apache.ambari.server.topology; + +import java.util.Collection; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.ambari.server.controller.internal.ProvisionAction; + +public class ProvisionClusterTemplate { + + private String blueprint; + @JsonProperty("default_password") + private String defaultPassword; + @JsonProperty("config_recommendation_strategy") + private ConfigRecommendationStrategy configRecommendationStrategy; + @JsonProperty("provision_action") + private ProvisionAction provisionAction; + private Collection<ProvisionClusterTemplate.Service> services; + @JsonProperty("host_groups") + private Collection<ProvisionClusterTemplate.HostGroup> hostGroups; + private Collection<Credential> credentials; + @JsonProperty("security") + private SecurityConfiguration securityConfiguration; + + public String getBlueprint() { + return blueprint; + } + + public void setBlueprint(String blueprint) { + this.blueprint = blueprint; + } + + public String getDefaultPassword() { + return defaultPassword; + } + + public void setDefaultPassword(String defaultPassword) { + this.defaultPassword = defaultPassword; + } + + public Collection<Service> getServices() { + return services; + } + + public void setServices(Collection<Service> services) { + this.services = services; + } + + public Collection<Credential> getCredentials() { + return credentials; + } + + public void setCredentials(Collection<Credential> credentials) { + this.credentials = credentials; + } + + public SecurityConfiguration getSecurityConfiguration() { + return securityConfiguration; + } + + public void setSecurityConfiguration(SecurityConfiguration securityConfiguration) { + this.securityConfiguration = securityConfiguration; + } + + public ConfigRecommendationStrategy getConfigRecommendationStrategy() { + return configRecommendationStrategy; + } + + public void setConfigRecommendationStrategy(ConfigRecommendationStrategy configRecommendationStrategy) { + this.configRecommendationStrategy = configRecommendationStrategy; + } + + public ProvisionAction getProvisionAction() { + return provisionAction; + } + + public void setProvisionAction(ProvisionAction provisionAction) { + this.provisionAction = provisionAction; + } + + public Collection<HostGroup> getHostGroups() { + return hostGroups; + } + + public void setHostGroups(Collection<HostGroup> hostGroups) { + this.hostGroups = hostGroups; + } + + public static class HostGroup implements Configurable { + private String name; + @JsonIgnore + private Configuration configuration; + private Collection<Host> hosts; + @JsonProperty("host_count") + private Integer hostCount; + @JsonProperty("host_predicate") + private String hostPredicate; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public Configuration getConfiguration() { + return configuration; + } + + @Override + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public Collection<Host> getHosts() { + return hosts; + } + + public void setHosts(Collection<Host> hosts) { + this.hosts = hosts; + } + + public Integer getHostCount() { + return hostCount; + } + + public void setHostCount(Integer hostCount) { + this.hostCount = hostCount; + } + + public String getHostPredicate() { + return hostPredicate; + } + + public void setHostPredicate(String hostPredicate) { + this.hostPredicate = hostPredicate; + } + } + + public static class Service implements Configurable { + private String name; + @JsonProperty("service_group") + private String serviceGroup; + @JsonIgnore + private Configuration configuration; + + @Override + public Configuration getConfiguration() { + return configuration; + } + + @Override + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getServiceGroup() { + return serviceGroup; + } + + public void setServiceGroup(String serviceGroup) { + this.serviceGroup = serviceGroup; + } + } + + public static class Host { + private String fqdn; + @JsonProperty("rack_info") + private String rackInfo; + + public String getFqdn() { + return fqdn; + } + + public void setFqdn(String fqdn) { + this.fqdn = fqdn; + } + + public String getRackInfo() { + return rackInfo; + } + + public void setRackInfo(String rackInfo) { + this.rackInfo = rackInfo; + } + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplateFactory.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplateFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplateFactory.java new file mode 100644 index 0000000..c66b6f6 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ProvisionClusterTemplateFactory.java @@ -0,0 +1,48 @@ +package org.apache.ambari.server.topology; + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class ProvisionClusterTemplateFactory { + + private ObjectMapper objectMapper; + + public ProvisionClusterTemplateFactory() { + createObjectMapper(); + } + + public boolean isPrettyPrintJson() { + return objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT);; + } + + public void setPrettyPrintJson(boolean prettyPrintJson) { + if (prettyPrintJson) { + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + } + else { + objectMapper.disable(SerializationFeature.INDENT_OUTPUT); + } + } + + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + private void createObjectMapper() { + objectMapper = new ObjectMapper(); +// SimpleModule module = new SimpleModule("CustomModel", Version.unknownVersion()); +// SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver(); +// resolver.addMapping(HostGroupV2.class, HostGroupV2Impl.class); +// module.setAbstractTypes(resolver); +// objectMapper.registerModule(module); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + public ProvisionClusterTemplate convertFromJson(String clusterTemplateJson) throws IOException { + return objectMapper.readValue(clusterTemplateJson, ProvisionClusterTemplate.class); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/test/java/org/apache/ambari/server/topology/BlueprintImplV2Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/BlueprintImplV2Test.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/BlueprintImplV2Test.java new file mode 100644 index 0000000..548ee18 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/BlueprintImplV2Test.java @@ -0,0 +1,173 @@ +/* + * 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.topology; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.ambari.server.controller.StackV2; +import org.apache.ambari.server.controller.StackV2Factory; +import org.apache.ambari.server.state.StackId; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.io.Resources; + +public class BlueprintImplV2Test { + + static String BLUEPRINTV2_JSON; + static String BLUEPRINTV2_2_JSON; + + BlueprintV2Factory blueprintFactory; + + @BeforeClass + public static void setUpClass() throws Exception { + BLUEPRINTV2_JSON = Resources.toString(Resources.getResource("blueprintv2/blueprintv2.json"), Charsets.UTF_8); + BLUEPRINTV2_2_JSON = Resources.toString(Resources.getResource("blueprintv2/blueprintv2_2.json"), Charsets.UTF_8); + } + + @Before + public void setUp() throws Exception { + StackV2Factory stackFactory = mock(StackV2Factory.class); + when(stackFactory.create(any(StackId.class))).thenAnswer(invocation -> { + StackId stackId = invocation.getArgumentAt(0, StackId.class); + StackV2 stack = new StackV2(stackId.getStackName(), stackId.getStackVersion(), stackId.getStackVersion() + ".0-1", + new HashMap<>(), new HashMap<>(), new HashMap<>(), + new HashMap<>(), new HashMap<>(), new HashMap<>(), + new HashMap<>(), new HashMap<>(), new HashMap<>()); + return stack; + }); + blueprintFactory = BlueprintV2Factory.create(stackFactory); + blueprintFactory.setPrettyPrintJson(true); + } + + @Test + public void testSerialization_parseJsonAsBlueprint() throws Exception { + BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_JSON); + assertEquals(new StackId("HDPCORE", "3.0.0"), + bp.getServiceGroups().iterator().next().getServices().iterator().next().getStack().getStackId()); + assertEquals(2, bp.getStackIds().size()); + assertEquals(7, bp.getAllServiceIds().size()); + assertEquals(2, bp.getServiceGroups().size()); + } + + @Test + public void testSerialization_parseJsonAsMap() throws Exception { + ObjectMapper mapper = blueprintFactory.getObjectMapper(); + Map<String, Object> blueprintAsMap = mapper.readValue(BLUEPRINTV2_JSON, HashMap.class); + assertEquals(2, getAsMap(blueprintAsMap, "cluster_settings").size()); + assertEquals(2, getAsMap(blueprintAsMap, "Blueprints").size()); + assertEquals("blueprint-def", getByPath(blueprintAsMap, + ImmutableList.of("Blueprints", "blueprint_name"))); + assertEquals(2, getAsList(blueprintAsMap, "service_groups").size()); + assertEquals("StreamSG", getByPath(blueprintAsMap, + ImmutableList.of("service_groups", 1, "name"))); + assertEquals(2, getAsList(blueprintAsMap, "repository_versions").size()); + assertEquals(1, getAsList(blueprintAsMap, "host_groups").size()); + assertEquals("host_group_1", getByPath(blueprintAsMap, + ImmutableList.of("host_groups", 0, "name"))); + System.out.println(blueprintAsMap); + } + + @Test + public void testSerialization_serializeBlueprint() throws Exception { + BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_JSON); + String serialized = blueprintFactory.convertToJson(bp); + // Test that serialized blueprint can be read again + bp = blueprintFactory.convertFromJson(serialized); + assertEquals(2, bp.getStackIds().size()); + assertEquals(7, bp.getAllServiceIds().size()); + assertEquals(2, bp.getServiceGroups().size()); + } + + @Test + public void testSerialization2_parseJsonAsBlueprint() throws Exception { + BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_2_JSON); + assertEquals(new StackId("HDP", "3.0.0"), + bp.getServiceGroups().iterator().next().getServices().iterator().next().getStack().getStackId()); + assertEquals(1, bp.getStackIds().size()); + assertEquals(4, bp.getAllServiceIds().size()); + assertEquals(1, bp.getServiceGroups().size()); + } + + @Test + public void testSerialization2_parseJsonAsMap() throws Exception { + ObjectMapper mapper = blueprintFactory.getObjectMapper(); + Map<String, Object> blueprintAsMap = mapper.readValue(BLUEPRINTV2_2_JSON, HashMap.class); + assertEquals(2, getAsMap(blueprintAsMap, "cluster_settings").size()); + assertEquals(2, getAsMap(blueprintAsMap, "Blueprints").size()); + assertEquals("blueprint-def", getByPath(blueprintAsMap, + ImmutableList.of("Blueprints", "blueprint_name"))); + assertEquals(1, getAsList(blueprintAsMap, "service_groups").size()); + assertEquals("CoreSG", getByPath(blueprintAsMap, + ImmutableList.of("service_groups", 0, "name"))); + assertEquals(1, getAsList(blueprintAsMap, "repository_versions").size()); + assertEquals(1, getAsList(blueprintAsMap, "host_groups").size()); + assertEquals("host_group_1", getByPath(blueprintAsMap, + ImmutableList.of("host_groups", 0, "name"))); + System.out.println(blueprintAsMap); + } + + @Test + public void testSerialization2_serializeBlueprint() throws Exception { + BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_2_JSON); + String serialized = blueprintFactory.convertToJson(bp); + // Test that serialized blueprint can be read again + bp = blueprintFactory.convertFromJson(serialized); + assertEquals(1, bp.getStackIds().size()); + assertEquals(4, bp.getAllServiceIds().size()); + assertEquals(1, bp.getServiceGroups().size()); + } + + private static Map<String, Object> getAsMap(Map<String, Object> parentMap, String key) { + return (Map<String, Object>)parentMap.get(key); + } + + private static List<Object> getAsList(Map<String, Object> parentMap, String key) { + return (List<Object>)parentMap.get(key); + } + + private static Object getByPath(Map<String, Object> initialMap, List<Object> path) { + Object returnValue = initialMap; + for(Object key: path) { + if (key instanceof String) { // this element is a map + returnValue = ((Map<String, Object>)returnValue).get(key); + Preconditions.checkNotNull(returnValue, "No value for key: " + key); + } + else if (key instanceof Integer) { // this element is an arraylist + returnValue = ((List<Object>)returnValue).get((Integer)key); + } + else { + throw new IllegalArgumentException("Invalid path element: " + key); + } + } + return returnValue; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/test/java/org/apache/ambari/server/topology/ProvisionClusterTemplateTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ProvisionClusterTemplateTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ProvisionClusterTemplateTest.java new file mode 100644 index 0000000..b9179b6 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ProvisionClusterTemplateTest.java @@ -0,0 +1,30 @@ +package org.apache.ambari.server.topology; + +import java.io.IOException; + +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import org.junit.Test; + +public class ProvisionClusterTemplateTest { + + public static final String CLUSTER_TEMPLATE = getResource("blueprintv2/cluster_template_v2.json"); + + + @Test + public void testProvisionClusterTemplate() throws Exception { + ProvisionClusterTemplateFactory factory = new ProvisionClusterTemplateFactory(); + ProvisionClusterTemplate template = factory.convertFromJson(CLUSTER_TEMPLATE); + System.out.println(template); + } + + + private static String getResource(String fileName) { + try { + return Resources.toString(Resources.getResource(fileName), Charsets.UTF_8); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/test/java/org/apache/ambari/server/topology/validators/BlueprintImplV2Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/validators/BlueprintImplV2Test.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/validators/BlueprintImplV2Test.java deleted file mode 100644 index ee2ea1c..0000000 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/validators/BlueprintImplV2Test.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.topology.validators; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.ambari.server.controller.StackV2; -import org.apache.ambari.server.controller.StackV2Factory; -import org.apache.ambari.server.state.StackId; -import org.apache.ambari.server.topology.BlueprintV2; -import org.apache.ambari.server.topology.BlueprintV2Factory; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Charsets; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.io.Resources; - -public class BlueprintImplV2Test { - - static String BLUEPRINTV2_JSON; - static String BLUEPRINTV2_2_JSON; - - BlueprintV2Factory blueprintFactory; - - @BeforeClass - public static void setUpClass() throws Exception { - BLUEPRINTV2_JSON = Resources.toString(Resources.getResource("blueprintv2/blueprintv2.json"), Charsets.UTF_8); - BLUEPRINTV2_2_JSON = Resources.toString(Resources.getResource("blueprintv2/blueprintv2_2.json"), Charsets.UTF_8); - } - - @Before - public void setUp() throws Exception { - StackV2Factory stackFactory = mock(StackV2Factory.class); - when(stackFactory.create(any(StackId.class))).thenAnswer(invocation -> { - StackId stackId = invocation.getArgumentAt(0, StackId.class); - StackV2 stack = new StackV2(stackId.getStackName(), stackId.getStackVersion(), stackId.getStackVersion() + ".0-1", - new HashMap<>(), new HashMap<>(), new HashMap<>(), - new HashMap<>(), new HashMap<>(), new HashMap<>(), - new HashMap<>(), new HashMap<>(), new HashMap<>()); - return stack; - }); - blueprintFactory = BlueprintV2Factory.create(stackFactory); - blueprintFactory.setPrettyPrintJson(true); - } - - @Test - public void testSerialization_parseJsonAsBlueprint() throws Exception { - BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_JSON); - assertEquals(new StackId("HDPCORE", "3.0.0"), - bp.getServiceGroups().iterator().next().getServices().iterator().next().getStack().getStackId()); - assertEquals(2, bp.getStackIds().size()); - assertEquals(7, bp.getAllServiceIds().size()); - assertEquals(2, bp.getServiceGroups().size()); - } - - @Test - public void testSerialization_parseJsonAsMap() throws Exception { - ObjectMapper mapper = blueprintFactory.createObjectMapper(); - Map<String, Object> blueprintAsMap = mapper.readValue(BLUEPRINTV2_JSON, HashMap.class); - assertEquals(2, getAsMap(blueprintAsMap, "cluster_settings").size()); - assertEquals(2, getAsMap(blueprintAsMap, "Blueprints").size()); - assertEquals("blueprint-def", getByPath(blueprintAsMap, - ImmutableList.of("Blueprints", "blueprint_name"))); - assertEquals(2, getAsList(blueprintAsMap, "service_groups").size()); - assertEquals("StreamSG", getByPath(blueprintAsMap, - ImmutableList.of("service_groups", 1, "name"))); - assertEquals(2, getAsList(blueprintAsMap, "repository_versions").size()); - assertEquals(1, getAsList(blueprintAsMap, "host_groups").size()); - assertEquals("host_group_1", getByPath(blueprintAsMap, - ImmutableList.of("host_groups", 0, "name"))); - System.out.println(blueprintAsMap); - } - - @Test - public void testSerialization_serializeBlueprint() throws Exception { - BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_JSON); - String serialized = blueprintFactory.convertToJson(bp); - // Test that serialized blueprint can be read again - bp = blueprintFactory.convertFromJson(serialized); - assertEquals(2, bp.getStackIds().size()); - assertEquals(7, bp.getAllServiceIds().size()); - assertEquals(2, bp.getServiceGroups().size()); - } - - @Test - public void testSerialization2_parseJsonAsBlueprint() throws Exception { - BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_2_JSON); - assertEquals(new StackId("HDP", "3.0.0"), - bp.getServiceGroups().iterator().next().getServices().iterator().next().getStack().getStackId()); - assertEquals(1, bp.getStackIds().size()); - assertEquals(4, bp.getAllServiceIds().size()); - assertEquals(1, bp.getServiceGroups().size()); - } - - @Test - public void testSerialization2_parseJsonAsMap() throws Exception { - ObjectMapper mapper = blueprintFactory.createObjectMapper(); - Map<String, Object> blueprintAsMap = mapper.readValue(BLUEPRINTV2_2_JSON, HashMap.class); - assertEquals(2, getAsMap(blueprintAsMap, "cluster_settings").size()); - assertEquals(2, getAsMap(blueprintAsMap, "Blueprints").size()); - assertEquals("blueprint-def", getByPath(blueprintAsMap, - ImmutableList.of("Blueprints", "blueprint_name"))); - assertEquals(1, getAsList(blueprintAsMap, "service_groups").size()); - assertEquals("CoreSG", getByPath(blueprintAsMap, - ImmutableList.of("service_groups", 0, "name"))); - assertEquals(1, getAsList(blueprintAsMap, "repository_versions").size()); - assertEquals(1, getAsList(blueprintAsMap, "host_groups").size()); - assertEquals("host_group_1", getByPath(blueprintAsMap, - ImmutableList.of("host_groups", 0, "name"))); - System.out.println(blueprintAsMap); - } - - @Test - public void testSerialization2_serializeBlueprint() throws Exception { - BlueprintV2 bp = blueprintFactory.convertFromJson(BLUEPRINTV2_2_JSON); - String serialized = blueprintFactory.convertToJson(bp); - // Test that serialized blueprint can be read again - bp = blueprintFactory.convertFromJson(serialized); - assertEquals(1, bp.getStackIds().size()); - assertEquals(4, bp.getAllServiceIds().size()); - assertEquals(1, bp.getServiceGroups().size()); - } - - private static Map<String, Object> getAsMap(Map<String, Object> parentMap, String key) { - return (Map<String, Object>)parentMap.get(key); - } - - private static List<Object> getAsList(Map<String, Object> parentMap, String key) { - return (List<Object>)parentMap.get(key); - } - - private static Object getByPath(Map<String, Object> initialMap, List<Object> path) { - Object returnValue = initialMap; - for(Object key: path) { - if (key instanceof String) { // this element is a map - returnValue = ((Map<String, Object>)returnValue).get(key); - Preconditions.checkNotNull(returnValue, "No value for key: " + key); - } - else if (key instanceof Integer) { // this element is an arraylist - returnValue = ((List<Object>)returnValue).get((Integer)key); - } - else { - throw new IllegalArgumentException("Invalid path element: " + key); - } - } - return returnValue; - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/94712bc4/ambari-server/src/test/resources/blueprintv2/cluster_template_v2.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/blueprintv2/cluster_template_v2.json b/ambari-server/src/test/resources/blueprintv2/cluster_template_v2.json new file mode 100644 index 0000000..1fb0b04 --- /dev/null +++ b/ambari-server/src/test/resources/blueprintv2/cluster_template_v2.json @@ -0,0 +1,66 @@ +{ + "blueprint": "blueprint-name", + "default_password": "super-secret-password", + "services": [ + { + "service_group": "CORE_SG", + "name": "ZK1", + "configurations": [ + { + "zoo.cfg": { + "properties": { + "dataDir": "/zookeeper2" + } + } + } + ] + }, + { + "service_group": "CORE_SG", + "name": "HDFS", + "configurations": [ + { + "hdfs-site": { + "properties": { + "property-name": "property-value" + } + } + } + ] + } + + ], + "host_groups": [ + { + "name": "host-group-1", + "configurations": [ + { + "yarn-site": { + "properties": { + "property-name": "property-value" + } + } + } + ], + "hosts": [ + { + "fqdn": "host.domain.com" + }, + { + "fqdn": "host2.domain.com" + } + ] + } + ], + "credentials": [ + { + "alias": "kdc.admin.credential", + "principal": "principal", + "key": "key", + "type": "TEMPORARY" + } + ], + "security": { + "type": "NONE" + } +}