AMBARI-22253. Make ProvisionClusterRequestTest work (adoroszlai)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c8f46458 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c8f46458 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c8f46458 Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2 Commit: c8f46458ff06ed24dcd99504812759d0ffd68f03 Parents: 4e45eb0 Author: Doroszlai, Attila <adorosz...@hortonworks.com> Authored: Fri Dec 1 19:02:37 2017 +0100 Committer: Doroszlai, Attila <adorosz...@hortonworks.com> Committed: Fri Dec 8 20:24:25 2017 +0100 ---------------------------------------------------------------------- .../controller/internal/BaseClusterRequest.java | 103 ++-- .../internal/ProvisionClusterRequest.java | 7 +- .../ambari/server/topology/BlueprintV2.java | 2 +- .../ambari/server/topology/BlueprintV2Impl.java | 15 +- .../ambari/server/topology/HostGroupInfo.java | 3 + .../ambari/server/topology/HostGroupV2.java | 3 + .../server/topology/PersistedStateImpl.java | 8 +- .../server/topology/TopologyTemplate.java | 16 +- .../BlueprintConfigurationProcessorTest.java | 1 - .../internal/ClusterResourceProviderTest.java | 10 +- .../internal/ProvisionClusterRequestTest.java | 471 +++++++------------ .../server/topology/TopologyManagerTest.java | 93 ++-- 12 files changed, 285 insertions(+), 447 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java index 4a32529..ade7295 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java @@ -18,9 +18,11 @@ package org.apache.ambari.server.controller.internal; +import static java.util.stream.Collectors.toSet; + +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -35,7 +37,6 @@ import org.apache.ambari.server.topology.BlueprintV2; import org.apache.ambari.server.topology.BlueprintV2Factory; import org.apache.ambari.server.topology.Configuration; import org.apache.ambari.server.topology.HostGroupInfo; -import org.apache.ambari.server.topology.InvalidTopologyTemplateException; import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.Service; import org.apache.ambari.server.topology.TopologyRequest; @@ -49,38 +50,8 @@ public abstract class BaseClusterRequest implements TopologyRequest { * blueprint deploy by default. */ public static final String PROVISION_ACTION_PROPERTY = "provision_action"; - /** - * host group info map - */ - private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<>(); - - protected ProvisionAction provisionAction; - - /** - * cluster id - */ - protected Long clusterId; - - /** - * blueprint - */ - //todo: change interface to only return blueprint name - protected BlueprintV2 blueprint; - /** - * security configuration - */ - protected SecurityConfiguration securityConfiguration; - - /** - * blueprint factory - */ - protected static BlueprintV2Factory blueprintFactory; - - /** - * List of services - */ - protected Collection<Service> serviceConfigs; + private static BlueprintV2Factory blueprintFactory; /** * Lexer used to obtain property names from a predicate string @@ -92,9 +63,15 @@ public abstract class BaseClusterRequest implements TopologyRequest { */ private static ResourceProvider hostResourceProvider; + private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<>(); + protected ProvisionAction provisionAction; + protected Long clusterId; + protected BlueprintV2 blueprint; + protected SecurityConfiguration securityConfiguration; + protected Collection<Service> serviceConfigs; public static void init(AmbariManagementController controller) { - blueprintFactory = BlueprintV2Factory.create(controller); + setBlueprintFactory(BlueprintV2Factory.create(controller)); } @Override @@ -128,79 +105,57 @@ public abstract class BaseClusterRequest implements TopologyRequest { * * @param predicate predicate to validate * - * @throws InvalidTopologyTemplateException if any of the properties specified in the predicate are invalid - * for the Host resource type + * @throws IllegalArgumentException if any of the properties specified in the predicate are invalid for the Host resource type */ - protected void validateHostPredicateProperties(String predicate) throws InvalidTopologyTemplateException { + public static void validateHostPredicateProperties(String predicate) { Token[] tokens; try { tokens = queryLexer.tokens(predicate); } catch (InvalidQueryException e) { - throw new InvalidTopologyTemplateException( - String.format("The specified host query is invalid: %s", e.getMessage())); + throw new IllegalArgumentException(String.format("The specified host query is invalid: %s", e.getMessage())); } - Set<String> propertyIds = new HashSet<>(); - for (Token token : tokens) { - if (token.getType() == Token.TYPE.PROPERTY_OPERAND) { - propertyIds.add(token.getValue()); - } - } + Set<String> propertyIds = Arrays.stream(tokens) + .filter(t -> t.getType() == Token.TYPE.PROPERTY_OPERAND) + .map(Token::getValue) + .collect(toSet()); Set<String> invalidProperties = ensureHostProvider().checkPropertyIds(propertyIds); if (! invalidProperties.isEmpty()) { - throw new InvalidTopologyTemplateException(String.format( + throw new IllegalArgumentException(String.format( "Invalid Host Predicate. The following properties are not valid for a host predicate: %s", invalidProperties)); } } - /** - * Set the request blueprint. - * - * @param blueprint blueprint - */ protected void setBlueprint(BlueprintV2 blueprint) { this.blueprint = blueprint; } - /** - * Set the request configuration. - * - * @param configuration configuration - */ - @Deprecated - protected void setConfiguration(Configuration configuration) { - } - - /** - * Get the blueprint factory. - */ protected BlueprintV2Factory getBlueprintFactory() { return blueprintFactory; } - public SecurityConfiguration getSecurityConfiguration() { return securityConfiguration; } - /** - * Get the host resource provider instance. - * - * @return host resourece provider instance - */ private static synchronized ResourceProvider ensureHostProvider() { if (hostResourceProvider == null) { - hostResourceProvider = ClusterControllerHelper.getClusterController(). - ensureResourceProvider(Resource.Type.Host); + ResourceProvider provider = ClusterControllerHelper.getClusterController().ensureResourceProvider(Resource.Type.Host); + setHostResourceProvider(provider); } return hostResourceProvider; } - /** - * Get requested @ProvisionClusterRequest.ProvisionAction - */ + static void setHostResourceProvider(ResourceProvider provider) { // exposed for tests + hostResourceProvider = provider; + } + + public static void setBlueprintFactory(BlueprintV2Factory factory) { // exposed for tests + blueprintFactory = factory; + } + public ProvisionAction getProvisionAction() { return provisionAction; } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java index bad2311..09eb888 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java @@ -73,6 +73,7 @@ public class ProvisionClusterRequest extends BaseClusterRequest { throws InvalidTopologyTemplateException { this.topologyTemplate = topologyTemplate; + topologyTemplate.validate(); clusterName = String.valueOf(properties.get(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID)); @@ -186,8 +187,10 @@ public class ProvisionClusterRequest extends BaseClusterRequest { HostGroupInfo output = new HostGroupInfo(input.getName()); output.setPredicate(input.getHostPredicate()); output.setRequestedCount(input.getHostCount()); - output.addHosts(input.getHosts().stream().map(TopologyTemplate.Host::getFqdn).collect(toSet())); - input.getHosts().forEach(h -> output.addHostRackInfo(h.getFqdn(), h.getRackInfo())); + if (input.getHosts() != null) { + output.addHosts(input.getHosts().stream().map(TopologyTemplate.Host::getFqdn).collect(toSet())); + input.getHosts().forEach(h -> output.addHostRackInfo(h.getFqdn(), h.getRackInfo())); + } output.setConfiguration(input.getConfiguration()); return output; } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2.java index 9921430..b12674a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2.java @@ -53,7 +53,7 @@ public interface BlueprintV2 { * Get the hot groups contained in the blueprint. * @return map of host group name to host group */ - Map<String, ? extends HostGroupV2> getHostGroups(); + Map<String, HostGroupV2> getHostGroups(); /** * Get stacks associated with the blueprint. http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Impl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Impl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Impl.java index 77fe5d8..224e6b7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Impl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintV2Impl.java @@ -56,7 +56,7 @@ public class BlueprintV2Impl implements BlueprintV2 { // Transient fields @JsonIgnore - private Map<String, HostGroupV2Impl> hostGroupMap = new HashMap<>(); + private Map<String, HostGroupV2> hostGroupMap = new HashMap<>(); @JsonIgnore private Map<StackId, StackV2> stacks; @@ -111,9 +111,9 @@ public class BlueprintV2Impl implements BlueprintV2 { } @JsonProperty("host_groups") - public void setHostGroups(Collection<HostGroupV2Impl> hostGroups) { + public void setHostGroups(Collection<? extends HostGroupV2> hostGroups) { this.hostGroupMap = hostGroups.stream().collect(toMap( - HostGroupV2Impl::getName, + HostGroupV2::getName, Function.identity() )); } @@ -136,7 +136,7 @@ public class BlueprintV2Impl implements BlueprintV2 { @Override @JsonIgnore - public Map<String, ? extends HostGroupV2> getHostGroups() { + public Map<String, HostGroupV2> getHostGroups() { return hostGroupMap; } @@ -377,13 +377,12 @@ public class BlueprintV2Impl implements BlueprintV2 { // Set HostGroup -> Services and Component -> Service references - for (HostGroupV2Impl hg: hostGroupMap.values()) { + for (HostGroupV2 hg : hostGroupMap.values()) { hg.setServiceMap(hg.getServiceIds().stream().collect(toMap( - Function.identity(), - serviceId -> this.services.get(serviceId) + Function.identity(), this::getService ))); for (ComponentV2 comp: hg.getComponents()) { - comp.setService(hg.getService(comp.getServiceId())); + comp.setService(getService(comp.getServiceId())); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupInfo.java index 8e3d237..0c6b247 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupInfo.java @@ -33,6 +33,8 @@ import org.apache.ambari.server.controller.spi.Predicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Strings; + /** * Host Group information specific to a cluster instance. */ @@ -154,6 +156,7 @@ public class HostGroupInfo { */ public void addHosts(Collection<String> hosts) { Collection<String> lower = hosts.stream() + .filter(s -> !Strings.isNullOrEmpty(s)) .map(String::toLowerCase) .collect(toSet()); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupV2.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupV2.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupV2.java index 4d3d1f0..f08085f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupV2.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostGroupV2.java @@ -19,6 +19,7 @@ package org.apache.ambari.server.topology; import java.util.Collection; +import java.util.Map; import java.util.regex.Pattern; import org.apache.ambari.server.controller.internal.ProvisionAction; @@ -132,5 +133,7 @@ public interface HostGroupV2 { * @return the cardinality specified for the hostgroup */ String getCardinality(); + + void setServiceMap(Map<ServiceId, Service> serviceMap); } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java index 8b370ec..56e52c7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java @@ -399,12 +399,8 @@ public class PersistedStateImpl implements PersistedState { try { blueprint = blueprintFactory.getBlueprint(entity.getBlueprintName()); - } catch (NoSuchBlueprintException e) { - throw new RuntimeException("Unable to load blueprint while replaying topology request: " + e, e); - } catch (IOException e) { - throw new RuntimeException("Unable to load blueprint while replaying topology request: " + e, e); - } catch (NoSuchStackException e) { - throw new RuntimeException("Unable to load blueprint while replaying topology request: " + e, e); + } catch (NoSuchBlueprintException | IOException | NoSuchStackException e) { + throw new RuntimeException("Unable to load blueprint while replaying topology request: " + e.getMessage(), e); } // load Service configurations from db, set Blueprint service config as parent for each services = new ArrayList<>(); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyTemplate.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyTemplate.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyTemplate.java index ffed3be..aa01101 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyTemplate.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyTemplate.java @@ -27,6 +27,7 @@ import java.util.function.Function; import javax.annotation.Nullable; +import org.apache.ambari.server.controller.internal.BaseClusterRequest; import org.apache.ambari.server.controller.internal.ProvisionAction; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -187,16 +188,23 @@ public class TopologyTemplate { this.hostPredicate = hostPredicate; } - void validate() throws IllegalStateException { + public void validate() { Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Host group name must be specified"); - Preconditions.checkArgument(hostCount > 0 || !hosts.isEmpty(), + boolean hasHostCount = hostCount > 0; + boolean hasHostList = hosts != null && !hosts.isEmpty(); + Preconditions.checkArgument(hasHostCount || hasHostList, "Host group '%s' must contain either 'hosts' or 'host_count'", name); - Preconditions.checkArgument(hostCount == 0 || hosts.isEmpty(), + Preconditions.checkArgument(!hasHostCount || !hasHostList, "Host group '%s' must not contain both 'hosts' and 'host_count'", name); Preconditions.checkArgument(hostPredicate == null || hostCount > 0, "Host group '%s' must not specify 'host_predicate' without 'host_count'", name); - hosts.forEach(Host::validate); + if (hasHostList) { + hosts.forEach(Host::validate); + } + if (hostPredicate != null) { + BaseClusterRequest.validateHostPredicateProperties(hostPredicate); + } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java index f9765f2..b64369a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java @@ -8238,7 +8238,6 @@ public class BlueprintConfigurationProcessorTest extends EasyMockSupport { expect(topologyRequestMock.getClusterId()).andReturn(1L).anyTimes(); expect(topologyRequestMock.getBlueprint()).andReturn(null).anyTimes(); - expect(topologyRequestMock.getConfiguration()).andReturn(configuration).anyTimes(); expect(topologyRequestMock.getHostGroupInfo()).andReturn(hostGroupInfo).anyTimes(); replay(bp, topologyRequestMock); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java index 3d15c7a..19f564a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java @@ -60,8 +60,8 @@ import org.apache.ambari.server.security.authorization.AuthorizationException; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.State; -import org.apache.ambari.server.topology.Blueprint; -import org.apache.ambari.server.topology.BlueprintFactory; +import org.apache.ambari.server.topology.BlueprintV2; +import org.apache.ambari.server.topology.BlueprintV2Factory; import org.apache.ambari.server.topology.InvalidTopologyException; import org.apache.ambari.server.topology.SecurityConfiguration; import org.apache.ambari.server.topology.SecurityConfigurationFactory; @@ -96,15 +96,15 @@ public class ClusterResourceProviderTest { private static final TopologyRequestFactory topologyFactory = createStrictMock(TopologyRequestFactory.class); private final static SecurityConfigurationFactory securityFactory = createMock(SecurityConfigurationFactory.class); private static final ProvisionClusterRequest topologyRequest = createNiceMock(ProvisionClusterRequest.class); - private static final BlueprintFactory blueprintFactory = createStrictMock(BlueprintFactory.class); - private static final Blueprint blueprint = createNiceMock(Blueprint.class); + private static final BlueprintV2Factory blueprintFactory = createStrictMock(BlueprintV2Factory.class); + private static final BlueprintV2 blueprint = createNiceMock(BlueprintV2.class); private static final RequestStatusResponse requestStatusResponse = createNiceMock(RequestStatusResponse.class); private static final Gson gson = new Gson(); @Before public void setup() throws Exception{ ClusterResourceProvider.init(topologyManager, topologyFactory, securityFactory, gson); - ProvisionClusterRequest.init(null); + BaseClusterRequest.setBlueprintFactory(blueprintFactory); provider = new ClusterResourceProvider(controller); expect(blueprintFactory.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).anyTimes(); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java index 0e1ad30..bcb386a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequestTest.java @@ -18,7 +18,6 @@ package org.apache.ambari.server.controller.internal; -import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.verify; @@ -27,54 +26,48 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.powermock.api.easymock.PowerMock.createStrictMock; import static org.powermock.api.easymock.PowerMock.replay; import static org.powermock.api.easymock.PowerMock.reset; -import java.lang.reflect.Field; 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.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.Set; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.security.encryption.CredentialStoreType; import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilderTest; -import org.apache.ambari.server.topology.Blueprint; -import org.apache.ambari.server.topology.BlueprintFactory; +import org.apache.ambari.server.topology.BlueprintV2; +import org.apache.ambari.server.topology.BlueprintV2Factory; import org.apache.ambari.server.topology.Configuration; +import org.apache.ambari.server.topology.Credential; import org.apache.ambari.server.topology.HostGroupInfo; import org.apache.ambari.server.topology.InvalidTopologyTemplateException; import org.apache.ambari.server.topology.TopologyRequest; +import org.apache.ambari.server.topology.TopologyTemplate; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableMap; /** * Unit tests for ProvisionClusterRequest. */ -@SuppressWarnings("unchecked") public class ProvisionClusterRequestTest { private static final String CLUSTER_NAME = "cluster_name"; private static final String BLUEPRINT_NAME = "blueprint_name"; + private static final Map<String, Object> REQUEST_PROPERTIES = ImmutableMap.of(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, CLUSTER_NAME); - private static final BlueprintFactory blueprintFactory = createStrictMock(BlueprintFactory.class); - private static final Blueprint blueprint = createNiceMock(Blueprint.class); - private static final ResourceProvider hostResourceProvider = createMock(ResourceProvider.class); - private static final Configuration blueprintConfig = new Configuration( - Collections.emptyMap(), - Collections.emptyMap()); + private static final BlueprintV2Factory blueprintFactory = createNiceMock(BlueprintV2Factory.class); + private static final BlueprintV2 blueprint = createNiceMock(BlueprintV2.class); + private static final ResourceProvider hostResourceProvider = createNiceMock(ResourceProvider.class); + private static final Configuration blueprintConfig = Configuration.createEmpty(); @Rule public ExpectedException expectedException = ExpectedException.none(); @@ -82,17 +75,13 @@ public class ProvisionClusterRequestTest { @Before public void setUp() throws Exception { reset(blueprintFactory, blueprint, hostResourceProvider); - ProvisionClusterRequest.init(null); - // set host resource provider field - Class clazz = BaseClusterRequest.class; - Field f = clazz.getDeclaredField("hostResourceProvider"); - f.setAccessible(true); - f.set(null, hostResourceProvider); - - expect(blueprintFactory.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).once(); + + BaseClusterRequest.setBlueprintFactory(blueprintFactory); + BaseClusterRequest.setHostResourceProvider(hostResourceProvider); + + expect(blueprintFactory.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).anyTimes(); expect(blueprint.getConfiguration()).andReturn(blueprintConfig).anyTimes(); - expect(hostResourceProvider.checkPropertyIds(Collections.singleton("Hosts/host_name"))). - andReturn(Collections.emptySet()).once(); + expect(hostResourceProvider.checkPropertyIds(Collections.singleton("Hosts/host_name"))).andReturn(Collections.emptySet()).anyTimes(); replay(blueprintFactory, blueprint, hostResourceProvider); } @@ -104,12 +93,9 @@ public class ProvisionClusterRequestTest { @Test public void testHostNameSpecified() throws Exception { - // reset host resource provider expectations to none since we are not specifying a host predicate - reset(hostResourceProvider); - replay(hostResourceProvider); - Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestPropertiesNameOnly(BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -135,32 +121,14 @@ public class ProvisionClusterRequestTest { assertEquals("prop1Value", group1TypeProperties.get("hostGroup1Prop1")); assertEquals("prop2Value", group1TypeProperties.get("hostGroup1Prop2")); assertTrue(group1Configuration.getAttributes().isEmpty()); - - // cluster scoped configuration - Configuration clusterScopeConfiguration = provisionClusterRequest.getConfiguration(); - assertSame(blueprintConfig, clusterScopeConfiguration.getParentConfiguration()); - assertEquals(1, clusterScopeConfiguration.getProperties().size()); - Map<String, String> clusterScopedProperties = clusterScopeConfiguration.getProperties().get("someType"); - assertEquals(1, clusterScopedProperties.size()); - assertEquals("someValue", clusterScopedProperties.get("property1")); - // attributes - Map<String, Map<String, Map<String, String>>> clusterScopedAttributes = clusterScopeConfiguration.getAttributes(); - assertEquals(1, clusterScopedAttributes.size()); - Map<String, Map<String, String>> clusterScopedTypeAttributes = clusterScopedAttributes.get("someType"); - assertEquals(1, clusterScopedTypeAttributes.size()); - Map<String, String> clusterScopedTypePropertyAttributes = clusterScopedTypeAttributes.get("attribute1"); - assertEquals(1, clusterScopedTypePropertyAttributes.size()); - assertEquals("someAttributePropValue", clusterScopedTypePropertyAttributes.get("property1")); } @Test public void testHostCountSpecified() throws Exception { - // reset host resource provider expectations to none since we are not specifying a host predicate - reset(hostResourceProvider); - replay(hostResourceProvider); - Map<String, Object> properties = createBlueprintRequestPropertiesCountOnly(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestPropertiesCountOnly(BLUEPRINT_NAME); + topology.getHostGroups().iterator().next().setHostPredicate(null); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -190,28 +158,12 @@ public class ProvisionClusterRequestTest { Map<String, String> group2Type1Prop1Attributes = group2Type1Attributes.get("attribute1"); assertEquals(1, group2Type1Prop1Attributes.size()); assertEquals("attribute1Prop10-value", group2Type1Prop1Attributes.get("hostGroup2Prop10")); - - // cluster scoped configuration - Configuration clusterScopeConfiguration = provisionClusterRequest.getConfiguration(); - assertSame(blueprintConfig, clusterScopeConfiguration.getParentConfiguration()); - assertEquals(1, clusterScopeConfiguration.getProperties().size()); - Map<String, String> clusterScopedProperties = clusterScopeConfiguration.getProperties().get("someType"); - assertEquals(1, clusterScopedProperties.size()); - assertEquals("someValue", clusterScopedProperties.get("property1")); - // attributes - Map<String, Map<String, Map<String, String>>> clusterScopedAttributes = clusterScopeConfiguration.getAttributes(); - assertEquals(1, clusterScopedAttributes.size()); - Map<String, Map<String, String>> clusterScopedTypeAttributes = clusterScopedAttributes.get("someType"); - assertEquals(1, clusterScopedTypeAttributes.size()); - Map<String, String> clusterScopedTypePropertyAttributes = clusterScopedTypeAttributes.get("attribute1"); - assertEquals(1, clusterScopedTypePropertyAttributes.size()); - assertEquals("someAttributePropValue", clusterScopedTypePropertyAttributes.get("property1")); } @Test public void testMultipleGroups() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName()); assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType()); @@ -259,49 +211,24 @@ public class ProvisionClusterRequestTest { Map<String, String> group2Type1Prop1Attributes = group2Type1Attributes.get("attribute1"); assertEquals(1, group2Type1Prop1Attributes.size()); assertEquals("attribute1Prop10-value", group2Type1Prop1Attributes.get("hostGroup2Prop10")); - - // cluster scoped configuration - Configuration clusterScopeConfiguration = provisionClusterRequest.getConfiguration(); - assertSame(blueprintConfig, clusterScopeConfiguration.getParentConfiguration()); - assertEquals(1, clusterScopeConfiguration.getProperties().size()); - Map<String, String> clusterScopedProperties = clusterScopeConfiguration.getProperties().get("someType"); - assertEquals(1, clusterScopedProperties.size()); - assertEquals("someValue", clusterScopedProperties.get("property1")); - // attributes - Map<String, Map<String, Map<String, String>>> clusterScopedAttributes = clusterScopeConfiguration.getAttributes(); - assertEquals(1, clusterScopedAttributes.size()); - Map<String, Map<String, String>> clusterScopedTypeAttributes = clusterScopedAttributes.get("someType"); - assertEquals(1, clusterScopedTypeAttributes.size()); - Map<String, String> clusterScopedTypePropertyAttributes = clusterScopedTypeAttributes.get("attribute1"); - assertEquals(1, clusterScopedTypePropertyAttributes.size()); - assertEquals("someAttributePropValue", clusterScopedTypePropertyAttributes.get("property1")); } - @Test(expected= InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void test_NoHostGroupInfo() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ((Collection)properties.get("host_groups")).clear(); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + topology.getHostGroups().clear(); - // reset default host resource provider expectations to none - reset(hostResourceProvider); - replay(hostResourceProvider); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } @Test - public void test_Creditentials() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - HashMap<String, String> credentialHashMap = new HashMap<>(); - credentialHashMap.put("alias", "testAlias"); - credentialHashMap.put("principal", "testPrincipal"); - credentialHashMap.put("key", "testKey"); - credentialHashMap.put("type", "temporary"); - Set<Map<String, String>> credentialsSet = new HashSet<>(); - credentialsSet.add(credentialHashMap); - properties.put("credentials", credentialsSet); - - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); + public void testCredentials() throws Exception { + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + Credential credential = new Credential("testAlias", "testPrincipal", "testKey", CredentialStoreType.TEMPORARY); + topology.setCredentials(Collections.singleton(credential)); + + ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getAlias(), "testAlias"); assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getPrincipal(), "testPrincipal"); @@ -309,122 +236,98 @@ public class ProvisionClusterRequestTest { assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getType().name(), "TEMPORARY"); } - - @Test - public void test_CreditentialsInvalidType() throws Exception { - expectedException.expect(InvalidTopologyTemplateException.class); - expectedException.expectMessage("credential.type [TESTTYPE] is invalid. acceptable values: " + - Arrays.toString(CredentialStoreType.values())); - - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - HashMap<String, String> credentialHashMap = new HashMap<>(); - credentialHashMap.put("alias", "testAlias"); - credentialHashMap.put("principal", "testPrincipal"); - credentialHashMap.put("key", "testKey"); - credentialHashMap.put("type", "testType"); - Set<Map<String, String>> credentialsSet = new HashSet<>(); - credentialsSet.add(credentialHashMap); - properties.put("credentials", credentialsSet); - - ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null); - } - - @Test(expected= InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void test_GroupInfoMissingName() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ((Collection<Map<String, Object>>)properties.get("host_groups")).iterator().next().remove("name"); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + topology.getHostGroups().iterator().next().setName(null); // reset default host resource provider expectations to none - reset(hostResourceProvider); - replay(hostResourceProvider); + reset(hostResourceProvider, blueprintFactory); + replay(hostResourceProvider, blueprintFactory); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } - @Test(expected= InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void test_NoHostsInfo() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ((Collection<Map<String, Object>>)properties.get("host_groups")).iterator().next().remove("hosts"); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + topology.getHostGroups().forEach(hg -> hg.setHosts(null)); - // reset default host resource provider expectations to none - reset(hostResourceProvider); - replay(hostResourceProvider); + reset(blueprintFactory); + replay(blueprintFactory); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } - @Test(expected = InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void test_NoHostNameOrHostCount() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); // remove fqdn property for a group that contains fqdn not host_count - for (Map<String, Object> groupProps : (Collection<Map<String, Object>>) properties.get("host_groups")) { - Collection<Map<String, Object>> hostInfo = (Collection<Map<String, Object>>) groupProps.get("hosts"); - Map<String, Object> next = hostInfo.iterator().next(); - if (next.containsKey("fqdn")) { - next.remove("fqdn"); - break; - } - } - - // reset default host resource provider expectations to none - reset(hostResourceProvider); - replay(hostResourceProvider); + topology.getHostGroups().forEach( + hg -> hg.getHosts().forEach( + h -> h.setFqdn(null) + ) + ); + + reset(blueprintFactory); + replay(blueprintFactory); // should result in an exception - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } - @Test(expected = InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void testInvalidPredicateProperty() throws Exception { - reset(hostResourceProvider); + reset(hostResourceProvider, blueprintFactory); // checkPropertyIds() returns invalid property names expect(hostResourceProvider.checkPropertyIds(Collections.singleton("Hosts/host_name"))). andReturn(Collections.singleton("Hosts/host_name")); - replay(hostResourceProvider); + replay(hostResourceProvider, blueprintFactory); // should result in an exception due to invalid property in host predicate - new ProvisionClusterRequest(null, createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null); + new ProvisionClusterRequest(createBlueprintRequestProperties(BLUEPRINT_NAME), REQUEST_PROPERTIES, null); } - @Test(expected = InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void testHostNameAndCountSpecified() throws Exception { // reset host resource provider expectations to none since we are not specifying a host predicate - reset(hostResourceProvider); - replay(hostResourceProvider); + reset(hostResourceProvider, blueprintFactory); + replay(hostResourceProvider, blueprintFactory); - Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_count", "5"); + TopologyTemplate topology = createBlueprintRequestPropertiesNameOnly(BLUEPRINT_NAME); + topology.getHostGroups().iterator().next().setHostCount(5); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } - @Test(expected = InvalidTopologyTemplateException.class) + @Test(expected = IllegalArgumentException.class) public void testHostNameAndPredicateSpecified() throws Exception { // reset host resource provider expectations to none since we are not specifying a host predicate - reset(hostResourceProvider); - replay(hostResourceProvider); + reset(hostResourceProvider, blueprintFactory); + replay(hostResourceProvider, blueprintFactory); - Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME); - ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_predicate", "Hosts/host_name=myTestHost"); + TopologyTemplate topology = createBlueprintRequestPropertiesNameOnly(BLUEPRINT_NAME); + topology.getHostGroups().iterator().next().setHostPredicate("Hosts/host_name=myTestHost"); // should result in an exception due to both host name and host count being specified - new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); } @Test public void testQuickLinksProfile_NoDataInRequest() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + ProvisionClusterRequest request = new ProvisionClusterRequest(topology, REQUEST_PROPERTIES, null); assertNull("No quick links profile is expected", request.getQuickLinksProfileJson()); } @Test public void testQuickLinksProfile_OnlyGlobalFilterDataInRequest() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + Map<String, Object> properties = new HashMap<>(REQUEST_PROPERTIES); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_FILTERS_PROPERTY, - Sets.newHashSet(QuickLinksProfileBuilderTest.filter(null, null, true))); + Collections.singleton(QuickLinksProfileBuilderTest.filter(null, null, true))); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(topology, properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[]}", request.getQuickLinksProfileJson()); @@ -432,14 +335,15 @@ public class ProvisionClusterRequestTest { @Test public void testQuickLinksProfile_OnlyServiceFilterDataInRequest() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + Map<String, Object> properties = new HashMap<>(REQUEST_PROPERTIES); Map<String, String> filter = QuickLinksProfileBuilderTest.filter(null, null, true); - Map<String, Object> hdfs = QuickLinksProfileBuilderTest.service("HDFS", null, Sets.newHashSet(filter)); - Set<Map<String, Object>> services = Sets.newHashSet(hdfs); + Map<String, Object> hdfs = QuickLinksProfileBuilderTest.service("HDFS", null, Collections.singleton(filter)); + Set<Map<String, Object>> services = Collections.singleton(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + ProvisionClusterRequest request = new ProvisionClusterRequest(topology, properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", request.getQuickLinksProfileJson()); @@ -447,18 +351,18 @@ public class ProvisionClusterRequestTest { @Test public void testQuickLinksProfile_BothGlobalAndServiceLevelFilters() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + Map<String, Object> properties = new HashMap<>(REQUEST_PROPERTIES); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_FILTERS_PROPERTY, - Sets.newHashSet(QuickLinksProfileBuilderTest.filter(null, null, true))); + Collections.singleton(QuickLinksProfileBuilderTest.filter(null, null, true))); Map<String, String> filter = QuickLinksProfileBuilderTest.filter(null, null, true); - Map<String, Object> hdfs = QuickLinksProfileBuilderTest.service("HDFS", null, Sets.newHashSet(filter)); - Set<Map<String, Object>> services = Sets.newHashSet(hdfs); + Map<String, Object> hdfs = QuickLinksProfileBuilderTest.service("HDFS", null, Collections.singleton(filter)); + Set<Map<String, Object>> services = Collections.singleton(hdfs); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); - System.out.println(request.getQuickLinksProfileJson()); + ProvisionClusterRequest request = new ProvisionClusterRequest(topology, properties, null); assertEquals("Quick links profile doesn't match expected", "{\"filters\":[{\"visible\":true}],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}", request.getQuickLinksProfileJson()); @@ -466,141 +370,94 @@ public class ProvisionClusterRequestTest { @Test(expected = InvalidTopologyTemplateException.class) public void testQuickLinksProfile_InvalidRequestData() throws Exception { - Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME); + TopologyTemplate topology = createBlueprintRequestProperties(BLUEPRINT_NAME); + Map<String, Object> properties = new HashMap<>(REQUEST_PROPERTIES); properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, "Hello World!"); - ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null); + new ProvisionClusterRequest(topology, properties, null); } - public static Map<String, Object> createBlueprintRequestProperties(String clusterName, String blueprintName) { - Map<String, Object> properties = new LinkedHashMap<>(); - - properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName); - properties.put(ClusterResourceProvider.BLUEPRINT, blueprintName); - - Collection<Map<String, Object>> hostGroups = new ArrayList<>(); - properties.put("host_groups", hostGroups); - - // host group 1 - Map<String, Object> hostGroup1Properties = new HashMap<>(); - hostGroups.add(hostGroup1Properties); - hostGroup1Properties.put("name", "group1"); - Collection<Map<String, String>> hostGroup1Hosts = new ArrayList<>(); - hostGroup1Properties.put("hosts", hostGroup1Hosts); - Map<String, String> hostGroup1HostProperties = new HashMap<>(); - hostGroup1HostProperties.put("fqdn", "host1.myDomain.com"); - hostGroup1Hosts.add(hostGroup1HostProperties); - // host group 1 scoped configuration - // version 1 configuration syntax - Collection<Map<String, String>> hostGroup1Configurations = new ArrayList<>(); - hostGroup1Properties.put("configurations", hostGroup1Configurations); - Map<String, String> hostGroup1Configuration1 = new HashMap<>(); - hostGroup1Configuration1.put("foo-type/hostGroup1Prop1", "prop1Value"); - hostGroup1Configuration1.put("foo-type/hostGroup1Prop2", "prop2Value"); - hostGroup1Configurations.add(hostGroup1Configuration1); - - // host group 2 - Map<String, Object> hostGroup2Properties = new HashMap<>(); - hostGroups.add(hostGroup2Properties); - hostGroup2Properties.put("name", "group2"); - hostGroup2Properties.put("host_count", "5"); - hostGroup2Properties.put("host_predicate", "Hosts/host_name=myTestHost"); - - // host group 2 scoped configuration - // version 2 configuration syntax - Collection<Map<String, String>> hostGroup2Configurations = new ArrayList<>(); - hostGroup2Properties.put("configurations", hostGroup2Configurations); - Map<String, String> hostGroup2Configuration1 = new HashMap<>(); - hostGroup2Configuration1.put("foo-type/properties/hostGroup2Prop1", "prop1Value"); - hostGroup2Configuration1.put("foo-type/properties_attributes/attribute1/hostGroup2Prop10", "attribute1Prop10-value"); - hostGroup2Configurations.add(hostGroup2Configuration1); - - // cluster scoped configuration - Collection<Map<String, String>> clusterConfigurations = new ArrayList<>(); - properties.put("configurations", clusterConfigurations); - - Map<String, String> clusterConfigurationProperties = new HashMap<>(); - clusterConfigurations.add(clusterConfigurationProperties); - clusterConfigurationProperties.put("someType/properties/property1", "someValue"); - clusterConfigurationProperties.put("someType/properties_attributes/attribute1/property1", "someAttributePropValue"); - - return properties; + public static TopologyTemplate createBlueprintRequestProperties(String blueprintName) { + TopologyTemplate topology = new TopologyTemplate(); + topology.setBlueprint(blueprintName); + + Collection<TopologyTemplate.HostGroup> hostGroups = new ArrayList<>(); + hostGroups.add(createHostGroupWithHosts()); + hostGroups.add(createHostGroupWithHostCount()); + topology.setHostGroups(hostGroups); // must come after host group creation, since it processes + + // createClusterConfig(); TODO what's up with it? + + return topology; } - public static Map<String, Object> createBlueprintRequestPropertiesNameOnly(String clusterName, String blueprintName) { - Map<String, Object> properties = new LinkedHashMap<>(); - - properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName); - properties.put(ClusterResourceProvider.BLUEPRINT, blueprintName); - - Collection<Map<String, Object>> hostGroups = new ArrayList<>(); - properties.put("host_groups", hostGroups); - - // host group 1 - Map<String, Object> hostGroup1Properties = new HashMap<>(); - hostGroups.add(hostGroup1Properties); - hostGroup1Properties.put("name", "group1"); - Collection<Map<String, String>> hostGroup1Hosts = new ArrayList<>(); - hostGroup1Properties.put("hosts", hostGroup1Hosts); - Map<String, String> hostGroup1HostProperties = new HashMap<>(); - hostGroup1HostProperties.put("fqdn", "host1.myDomain.com"); - hostGroup1Hosts.add(hostGroup1HostProperties); - // host group 1 scoped configuration - // version 1 configuration syntax - Collection<Map<String, String>> hostGroup1Configurations = new ArrayList<>(); - hostGroup1Properties.put("configurations", hostGroup1Configurations); - Map<String, String> hostGroup1Configuration1 = new HashMap<>(); - hostGroup1Configuration1.put("foo-type/hostGroup1Prop1", "prop1Value"); - hostGroup1Configuration1.put("foo-type/hostGroup1Prop2", "prop2Value"); - hostGroup1Configurations.add(hostGroup1Configuration1); - - // cluster scoped configuration - Collection<Map<String, String>> clusterConfigurations = new ArrayList<>(); - properties.put("configurations", clusterConfigurations); - - Map<String, String> clusterConfigurationProperties = new HashMap<>(); - clusterConfigurations.add(clusterConfigurationProperties); - clusterConfigurationProperties.put("someType/properties/property1", "someValue"); - clusterConfigurationProperties.put("someType/properties_attributes/attribute1/property1", "someAttributePropValue"); - - return properties; + private static TopologyTemplate createBlueprintRequestPropertiesNameOnly(String blueprintName) { + TopologyTemplate topology = new TopologyTemplate(); + topology.setBlueprint(blueprintName); + + Collection<TopologyTemplate.HostGroup> hostGroups = new ArrayList<>(); + hostGroups.add(createHostGroupWithHosts()); + topology.setHostGroups(hostGroups); // must come after host group creation, since it processes + + // createClusterConfig(); TODO what's up with it? + + return topology; } - public static Map<String, Object> createBlueprintRequestPropertiesCountOnly(String clusterName, String blueprintName) { - Map<String, Object> properties = new LinkedHashMap<>(); + public static TopologyTemplate createBlueprintRequestPropertiesCountOnly(String blueprintName) { + TopologyTemplate topology = new TopologyTemplate(); + topology.setBlueprint(blueprintName); + + Collection<TopologyTemplate.HostGroup> hostGroups = new ArrayList<>(); + hostGroups.add(createHostGroupWithHostCount()); + topology.setHostGroups(hostGroups); // must come after host group creation, since it processes - properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName); - properties.put(ClusterResourceProvider.BLUEPRINT, blueprintName); + // createClusterConfig(); - Collection<Map<String, Object>> hostGroups = new ArrayList<>(); - properties.put("host_groups", hostGroups); + return topology; + } - // host group 2 - Map<String, Object> hostGroup2Properties = new HashMap<>(); - hostGroups.add(hostGroup2Properties); - hostGroup2Properties.put("name", "group2"); - // count with no predicate - hostGroup2Properties.put("host_count", "5"); + private static TopologyTemplate.HostGroup createHostGroupWithHostCount() { + TopologyTemplate.HostGroup hg = new TopologyTemplate.HostGroup(); - // host group 2 scoped configuration + hg.setName("group2"); + hg.setHostCount(5); + hg.setHostPredicate("Hosts/host_name=myTestHost"); + + // host group scoped configuration // version 2 configuration syntax - Collection<Map<String, String>> hostGroup2Configurations = new ArrayList<>(); - hostGroup2Properties.put("configurations", hostGroup2Configurations); - Map<String, String> hostGroup2Configuration1 = new HashMap<>(); - hostGroup2Configuration1.put("foo-type/properties/hostGroup2Prop1", "prop1Value"); - hostGroup2Configuration1.put("foo-type/properties_attributes/attribute1/hostGroup2Prop10", "attribute1Prop10-value"); - hostGroup2Configurations.add(hostGroup2Configuration1); - - // cluster scoped configuration - Collection<Map<String, String>> clusterConfigurations = new ArrayList<>(); - properties.put("configurations", clusterConfigurations); - - Map<String, String> clusterConfigurationProperties = new HashMap<>(); - clusterConfigurations.add(clusterConfigurationProperties); - clusterConfigurationProperties.put("someType/properties/property1", "someValue"); - clusterConfigurationProperties.put("someType/properties_attributes/attribute1/property1", "someAttributePropValue"); - - return properties; + hg.getConfiguration().setProperty("foo-type", "hostGroup2Prop1", "prop1Value"); + hg.getConfiguration().setAttribute("foo-type", "hostGroup2Prop10", "attribute1", "attribute1Prop10-value"); + + return hg; } + + private static TopologyTemplate.HostGroup createHostGroupWithHosts() { + TopologyTemplate.HostGroup hg = new TopologyTemplate.HostGroup(); + + hg.setName("group1"); + + Collection<TopologyTemplate.Host> hosts = new ArrayList<>(); + hg.setHosts(hosts); + + TopologyTemplate.Host host = new TopologyTemplate.Host(); + host.setFqdn("host1.myDomain.com"); + hosts.add(host); + + // host group scoped configuration + // version 1 configuration syntax + hg.getConfiguration().setProperty("foo-type", "hostGroup1Prop1", "prop1Value"); + hg.getConfiguration().setProperty("foo-type", "hostGroup1Prop2", "prop2Value"); + + return hg; + } + + private static Configuration createClusterConfig() { + Configuration clusterConfig = Configuration.createEmpty(); + clusterConfig.setProperty("someType", "property1", "someValue"); + clusterConfig.setAttribute("someType", "property1", "attribute1", "someAttributePropValue"); + return clusterConfig; + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/c8f46458/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java index 289874f..e370df6 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/TopologyManagerTest.java @@ -44,12 +44,12 @@ import java.util.TreeMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.controller.ClusterRequest; import org.apache.ambari.server.controller.ConfigurationRequest; import org.apache.ambari.server.controller.RequestStatusResponse; import org.apache.ambari.server.controller.ShortTaskStatus; +import org.apache.ambari.server.controller.internal.BaseClusterRequest; import org.apache.ambari.server.controller.internal.HostResourceProvider; import org.apache.ambari.server.controller.internal.ProvisionClusterRequest; import org.apache.ambari.server.controller.internal.ScaleClusterRequest; @@ -63,7 +63,6 @@ import org.apache.ambari.server.orm.dao.SettingDAO; import org.apache.ambari.server.orm.entities.SettingEntity; import org.apache.ambari.server.security.authorization.AuthorizationHelper; import org.apache.ambari.server.security.encryption.CredentialStoreService; -import org.apache.ambari.server.stack.NoSuchStackException; import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfile; import org.apache.ambari.server.topology.tasks.ConfigureClusterTask; @@ -86,6 +85,8 @@ import org.powermock.api.easymock.PowerMock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.google.common.collect.ImmutableMap; + /** * TopologyManager unit tests */ @@ -112,7 +113,7 @@ public class TopologyManagerTest { private TopologyManager topologyManagerReplay = new TopologyManager(); @Mock(type = MockType.NICE) - private Blueprint blueprint; + private BlueprintV2 blueprint; @Mock(type = MockType.NICE) private Stack stack; @@ -140,9 +141,9 @@ public class TopologyManagerTest { @Mock(type = MockType.NICE) private PersistedState persistedState; @Mock(type = MockType.NICE) - private HostGroup group1; + private HostGroupV2 group1; @Mock(type = MockType.NICE) - private HostGroup group2; + private HostGroupV2 group2; @Mock(type = MockType.STRICT) private SecurityConfigurationFactory securityConfigurationFactory; @Mock(type = MockType.STRICT) @@ -186,11 +187,15 @@ public class TopologyManagerTest { private HostGroupInfo group2Info = new HostGroupInfo("group2"); private Map<String, HostGroupInfo> groupInfoMap = new HashMap<>(); - private Collection<Component> group1Components = Arrays.asList(new Component("component1"), new Component("component2"), new Component("component3")); - private Collection<Component> group2Components = Arrays.asList(new Component("component3"), new Component("component4")); + private ComponentV2 component1 = new ComponentV2(); + private ComponentV2 component2 = new ComponentV2(); + private ComponentV2 component3 = new ComponentV2(); + private ComponentV2 component4 = new ComponentV2(); + private Collection<ComponentV2> group1Components = Arrays.asList(component1, component2, component3); + private Collection<ComponentV2> group2Components = Arrays.asList(component3, component4); - private Map<String, Collection<String>> group1ServiceComponents = new HashMap<>(); - private Map<String, Collection<String>> group2ServiceComponents = new HashMap<>(); + private Map<String, Collection<ComponentV2>> group1ServiceComponents = new HashMap<>(); + private Map<String, Collection<ComponentV2>> group2ServiceComponents = new HashMap<>(); private Map<String, Collection<String>> serviceComponents = new HashMap<>(); @@ -230,33 +235,45 @@ public class TopologyManagerTest { groupInfoMap.put("group1", group1Info); groupInfoMap.put("group2", group2Info); - Map<String, HostGroup> groupMap = new HashMap<>(); - groupMap.put("group1", group1); - groupMap.put("group2", group2); + Map<String, HostGroupV2> groupMap = ImmutableMap.of("group1", group1, "group2", group2); + + ServiceId serviceId1 = ServiceId.of("service1", "CORE"); + ServiceId serviceId2 = ServiceId.of("service2", "CORE"); + component1.setType("component1"); + component1.setServiceGroup(serviceId1.getServiceGroup()); + component1.setServiceName(serviceId1.getName()); + component2.setType("component2"); + component2.setServiceGroup(serviceId2.getServiceGroup()); + component2.setServiceName(serviceId2.getName()); + component3.setType("component3"); + component3.setServiceGroup(serviceId1.getServiceGroup()); + component3.setServiceName(serviceId1.getName()); + component4.setType("component4"); + component4.setServiceGroup(serviceId2.getServiceGroup()); + component4.setServiceName(serviceId2.getName()); serviceComponents.put("service1", Arrays.asList("component1", "component3")); serviceComponents.put("service2", Arrays.asList("component2", "component4")); - group1ServiceComponents.put("service1", Arrays.asList("component1", "component3")); - group1ServiceComponents.put("service2", Collections.singleton("component2")); - group2ServiceComponents.put("service2", Collections.singleton("component3")); - group2ServiceComponents.put("service2", Collections.singleton("component4")); + group1ServiceComponents.put("service1", Arrays.asList(component1, component3)); + group1ServiceComponents.put("service2", Collections.singleton(component2)); + group2ServiceComponents.put("service1", Collections.singleton(component3)); + group2ServiceComponents.put("service2", Collections.singleton(component4)); expect(blueprint.getHostGroup("group1")).andReturn(group1).anyTimes(); expect(blueprint.getHostGroup("group2")).andReturn(group2).anyTimes(); - expect(blueprint.getComponents("service1")).andReturn(Arrays.asList("component1", "component3")).anyTimes(); - expect(blueprint.getComponents("service2")).andReturn(Arrays.asList("component2", "component4")).anyTimes(); + expect(blueprint.getComponents(serviceId1)).andReturn(Arrays.asList(component1, component3)).anyTimes(); + expect(blueprint.getComponents(serviceId2)).andReturn(Arrays.asList(component2, component4)).anyTimes(); expect(blueprint.getConfiguration()).andReturn(bpConfiguration).anyTimes(); expect(blueprint.getHostGroups()).andReturn(groupMap).anyTimes(); - expect(blueprint.getHostGroupsForComponent("component1")).andReturn(Collections.singleton(group1)).anyTimes(); - expect(blueprint.getHostGroupsForComponent("component2")).andReturn(Collections.singleton(group1)).anyTimes(); - expect(blueprint.getHostGroupsForComponent("component3")).andReturn(Arrays.asList(group1, group2)).anyTimes(); - expect(blueprint.getHostGroupsForComponent("component4")).andReturn(Collections.singleton(group2)).anyTimes(); - expect(blueprint.getHostGroupsForService("service1")).andReturn(Arrays.asList(group1, group2)).anyTimes(); - expect(blueprint.getHostGroupsForService("service2")).andReturn(Arrays.asList(group1, group2)).anyTimes(); + expect(blueprint.getHostGroupsForComponent(component1)).andReturn(Collections.singleton(group1)).anyTimes(); + expect(blueprint.getHostGroupsForComponent(component2)).andReturn(Collections.singleton(group1)).anyTimes(); + expect(blueprint.getHostGroupsForComponent(component3)).andReturn(Arrays.asList(group1, group2)).anyTimes(); + expect(blueprint.getHostGroupsForComponent(component4)).andReturn(Collections.singleton(group2)).anyTimes(); + expect(blueprint.getHostGroupsForService(serviceId1)).andReturn(Arrays.asList(group1, group2)).anyTimes(); + expect(blueprint.getHostGroupsForService(serviceId2)).andReturn(Arrays.asList(group1, group2)).anyTimes(); expect(blueprint.getName()).andReturn(BLUEPRINT_NAME).anyTimes(); - expect(blueprint.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); - expect(blueprint.getStack()).andReturn(stack).anyTimes(); + expect(blueprint.getAllServiceNames()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); expect(blueprint.getRepositorySettings()).andReturn(new ArrayList<>()).anyTimes(); // don't expect toEntity() @@ -294,23 +311,21 @@ public class TopologyManagerTest { expect(group1.getCardinality()).andReturn("test cardinality").anyTimes(); expect(group1.containsMasterComponent()).andReturn(true).anyTimes(); expect(group1.getComponents()).andReturn(group1Components).anyTimes(); - expect(group1.getComponents("service1")).andReturn(group1ServiceComponents.get("service1")).anyTimes(); - expect(group1.getComponents("service2")).andReturn(group1ServiceComponents.get("service1")).anyTimes(); + expect(group1.getComponentsByServiceId(serviceId1)).andReturn(group1ServiceComponents.get("service1")).anyTimes(); + expect(group1.getComponentsByServiceId(serviceId2)).andReturn(group1ServiceComponents.get("service1")).anyTimes(); expect(group1.getConfiguration()).andReturn(topoGroup1Config).anyTimes(); expect(group1.getName()).andReturn("group1").anyTimes(); - expect(group1.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); - expect(group1.getStack()).andReturn(stack).anyTimes(); + expect(group1.getServiceNames()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); expect(group2.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes(); expect(group2.getCardinality()).andReturn("test cardinality").anyTimes(); expect(group2.containsMasterComponent()).andReturn(false).anyTimes(); expect(group2.getComponents()).andReturn(group2Components).anyTimes(); - expect(group2.getComponents("service1")).andReturn(group2ServiceComponents.get("service1")).anyTimes(); - expect(group2.getComponents("service2")).andReturn(group2ServiceComponents.get("service2")).anyTimes(); + expect(group2.getComponentsByServiceId(serviceId1)).andReturn(group2ServiceComponents.get("service1")).anyTimes(); + expect(group2.getComponentsByServiceId(serviceId2)).andReturn(group2ServiceComponents.get("service2")).anyTimes(); expect(group2.getConfiguration()).andReturn(topoGroup2Config).anyTimes(); expect(group2.getName()).andReturn("group2").anyTimes(); - expect(group2.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); - expect(group2.getStack()).andReturn(stack).anyTimes(); + expect(group2.getServiceNames()).andReturn(Arrays.asList("service1", "service2")).anyTimes(); expect(logicalRequestFactory.createRequest(eq(1L), (TopologyRequest) anyObject(), capture(clusterTopologyCapture))). @@ -406,8 +421,8 @@ public class TopologyManagerTest { expect(persistedState.getAllRequests()).andReturn(allRequests).anyTimes(); expect(persistedState.getProvisionRequest(CLUSTER_ID)).andReturn(logicalRequest).anyTimes(); expect(ambariContext.isTopologyResolved(CLUSTER_ID)).andReturn(true).anyTimes(); - expect(group1.addComponent("KERBEROS_CLIENT")).andReturn(true).anyTimes(); - expect(group2.addComponent("KERBEROS_CLIENT")).andReturn(true).anyTimes(); + // TODO expect(group1.addComponent("KERBEROS_CLIENT")).andReturn(true).anyTimes(); + // TODO expect(group2.addComponent("KERBEROS_CLIENT")).andReturn(true).anyTimes(); replayAll(); @@ -535,7 +550,7 @@ public class TopologyManagerTest { } @Test(expected = InvalidTopologyException.class) - public void testScaleHosts__alreadyExistingHost() throws InvalidTopologyTemplateException, InvalidTopologyException, AmbariException, NoSuchStackException { + public void testScaleHosts__alreadyExistingHost() throws Exception { HashSet<Map<String, Object>> propertySet = new HashSet<>(); Map<String,Object> properties = new TreeMap<>(); properties.put(HostResourceProvider.HOST_HOST_NAME_PROPERTY_ID, "host1"); @@ -543,9 +558,9 @@ public class TopologyManagerTest { properties.put(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID, CLUSTER_NAME); properties.put(HostResourceProvider.BLUEPRINT_PROPERTY_ID, BLUEPRINT_NAME); propertySet.add(properties); - BlueprintFactory bpfMock = EasyMock.createNiceMock(BlueprintFactory.class); + BlueprintV2Factory bpfMock = EasyMock.createNiceMock(BlueprintV2Factory.class); EasyMock.expect(bpfMock.getBlueprint(BLUEPRINT_NAME)).andReturn(blueprint).anyTimes(); - ScaleClusterRequest.init(null); + BaseClusterRequest.setBlueprintFactory(bpfMock); replay(bpfMock); expect(persistedState.getAllRequests()).andReturn(new HashMap<ClusterTopology, List<LogicalRequest>>()).anyTimes(); replayAll();