You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ad...@apache.org on 2017/12/01 18:02:56 UTC

[1/2] ambari git commit: AMBARI-22253. Use TopologyTemplate object model instead of maps (adoroszlai)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-14714-blueprintv2 87a7d61fe -> fd550ca89


AMBARI-22253. Use TopologyTemplate object model instead of maps (adoroszlai)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ba267a8c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ba267a8c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ba267a8c

Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2
Commit: ba267a8c1b113f12e09cd528816255d4594b7153
Parents: 87a7d61
Author: Doroszlai, Attila <ad...@hortonworks.com>
Authored: Fri Dec 1 06:59:08 2017 +0100
Committer: Doroszlai, Attila <ad...@hortonworks.com>
Committed: Fri Dec 1 11:13:16 2017 +0100

----------------------------------------------------------------------
 .../internal/ClusterResourceProvider.java       |  72 ++--
 .../internal/ProvisionClusterRequest.java       | 409 +++----------------
 .../internal/ScaleClusterRequest.java           |   3 +-
 .../ambari/server/topology/AmbariContext.java   |   6 +-
 .../server/topology/ConfigurationFactory.java   |  10 -
 .../ambari/server/topology/Credential.java      |   8 +
 .../ambari/server/topology/HostGroupInfo.java   |  14 +-
 .../server/topology/PersistedStateImpl.java     |   5 +-
 .../ambari/server/topology/TopologyManager.java |   2 -
 .../server/topology/TopologyRequestFactory.java |   2 +-
 .../topology/TopologyRequestFactoryImpl.java    |   4 +-
 .../server/topology/TopologyTemplate.java       |  77 ++--
 .../internal/ClusterResourceProviderTest.java   |  42 +-
 .../internal/ProvisionClusterRequestTest.java   |  34 +-
 .../ClusterDeployWithStartOnlyTest.java         |   1 -
 ...InstallWithoutStartOnComponentLevelTest.java |   1 -
 .../ClusterInstallWithoutStartTest.java         |   1 -
 17 files changed, 178 insertions(+), 513 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index 61e0f99..8cdd195 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -17,7 +17,7 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import java.util.Arrays;
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -56,8 +56,12 @@ import org.apache.ambari.server.topology.SecurityConfiguration;
 import org.apache.ambari.server.topology.SecurityConfigurationFactory;
 import org.apache.ambari.server.topology.TopologyManager;
 import org.apache.ambari.server.topology.TopologyRequestFactory;
+import org.apache.ambari.server.topology.TopologyTemplate;
+import org.apache.ambari.server.topology.TopologyTemplateFactory;
 import org.springframework.security.core.Authentication;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.gson.Gson;
 
 
@@ -127,46 +131,40 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
   /**
    * The cluster primary key properties.
    */
-  private static Set<String> pkPropertyIds =
-    new HashSet<>(Arrays.asList(new String[]{CLUSTER_ID_PROPERTY_ID}));
+  private static final Set<String> PK_PROPERTY_IDS = ImmutableSet.of(CLUSTER_ID_PROPERTY_ID);
 
   /**
    * The key property ids for a cluster resource.
    */
-  private static Map<Resource.Type, String> keyPropertyIds = new HashMap<>();
-  static {
-    keyPropertyIds.put(Resource.Type.Cluster, CLUSTER_NAME_PROPERTY_ID);
-  }
+  private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = ImmutableMap.of(Resource.Type.Cluster, CLUSTER_NAME_PROPERTY_ID);
 
   /**
    * The property ids for a cluster resource.
    */
-  private static Set<String> propertyIds = new HashSet<>();
+  private static final Set<String> PROPERTY_IDS = ImmutableSet.of(
+    CLUSTER_ID_PROPERTY_ID,
+    CLUSTER_NAME_PROPERTY_ID,
+    CLUSTER_VERSION_PROPERTY_ID,
+    CLUSTER_PROVISIONING_STATE_PROPERTY_ID,
+    CLUSTER_SECURITY_TYPE_PROPERTY_ID,
+    CLUSTER_DESIRED_CONFIGS_PROPERTY_ID,
+    CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID,
+    CLUSTER_TOTAL_HOSTS_PROPERTY_ID,
+    CLUSTER_HEALTH_REPORT_PROPERTY_ID,
+    CLUSTER_CREDENTIAL_STORE_PROPERTIES_PROPERTY_ID,
+    BLUEPRINT,
+    SESSION_ATTRIBUTES,
+    SECURITY,
+    CREDENTIALS,
+    QUICKLINKS_PROFILE
+  );
 
   /**
    * Used to serialize to/from json.
    */
   private static Gson jsonSerializer;
 
-
-  static {
-    propertyIds.add(CLUSTER_ID_PROPERTY_ID);
-    propertyIds.add(CLUSTER_NAME_PROPERTY_ID);
-    propertyIds.add(CLUSTER_VERSION_PROPERTY_ID);
-    propertyIds.add(CLUSTER_PROVISIONING_STATE_PROPERTY_ID);
-    propertyIds.add(CLUSTER_SECURITY_TYPE_PROPERTY_ID);
-    propertyIds.add(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID);
-    propertyIds.add(CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID);
-    propertyIds.add(CLUSTER_TOTAL_HOSTS_PROPERTY_ID);
-    propertyIds.add(CLUSTER_HEALTH_REPORT_PROPERTY_ID);
-    propertyIds.add(CLUSTER_CREDENTIAL_STORE_PROPERTIES_PROPERTY_ID);
-    propertyIds.add(BLUEPRINT);
-    propertyIds.add(SESSION_ATTRIBUTES);
-    propertyIds.add(SECURITY);
-    propertyIds.add(CREDENTIALS);
-    propertyIds.add(QUICKLINKS_PROFILE);
-  }
-
+  private final TopologyTemplateFactory topologyTemplateFactory;
 
   // ----- Constructors ----------------------------------------------------
 
@@ -176,7 +174,9 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
    * @param managementController  the management controller
    */
   ClusterResourceProvider(AmbariManagementController managementController) {
-    super(propertyIds, keyPropertyIds, managementController);
+    super(PROPERTY_IDS, KEY_PROPERTY_IDS, managementController);
+
+    topologyTemplateFactory = new TopologyTemplateFactory();
 
     setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_ADD_DELETE_CLUSTERS));
     setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_ADD_DELETE_CLUSTERS));
@@ -188,7 +188,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
 
   @Override
   protected Set<String> getPKPropertyIds() {
-    return pkPropertyIds;
+    return PK_PROPERTY_IDS;
   }
 
   /**
@@ -206,8 +206,6 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
     baseUnsupported.remove("credentials");
     baseUnsupported.remove("config_recommendation_strategy");
     baseUnsupported.remove("provision_action");
-    baseUnsupported.remove(ProvisionClusterRequest.REPO_VERSION_PROPERTY);
-    baseUnsupported.remove(ProvisionClusterRequest.REPO_VERSION_ID_PROPERTY);
     return checkConfigPropertyIds(baseUnsupported, "Clusters");
   }
 
@@ -226,10 +224,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
 
   @Override
   protected RequestStatus createResourcesAuthorized(Request request)
-      throws SystemException,
-             UnsupportedPropertyException,
-             ResourceAlreadyExistsException,
-             NoSuchParentResourceException {
+      throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
 
     RequestStatusResponse createResponse = null;
     for (final Map<String, Object> properties : request.getProperties()) {
@@ -526,14 +521,15 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
         "' based on blueprint '" + String.valueOf(properties.get(BLUEPRINT)) + "'.");
 
     String rawRequestBody = requestInfoProperties.get(Request.REQUEST_INFO_BODY_PROPERTY);
-    Map<String, Object> rawBodyMap = jsonSerializer.<Map<String, Object>>fromJson(rawRequestBody, Map.class);
+    Map<String, Object> rawBodyMap = jsonSerializer.fromJson(rawRequestBody, Map.class);
     SecurityConfiguration securityConfiguration =
       securityConfigurationFactory.createSecurityConfigurationFromRequest(rawBodyMap, false);
 
     ProvisionClusterRequest createClusterRequest;
     try {
-      createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties, securityConfiguration);
-    } catch (InvalidTopologyTemplateException e) {
+      TopologyTemplate topologyTemplate = topologyTemplateFactory.convertFromJson(rawRequestBody);
+      createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(topologyTemplate, properties, securityConfiguration);
+    } catch (InvalidTopologyTemplateException | IOException e) {
       throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e);
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 a38b314..bad2311 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
@@ -17,171 +17,67 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import static org.apache.ambari.server.topology.ConfigurationFactory.toBranchMapList;
-import static org.apache.ambari.server.topology.ConfigurationFactory.toLeafMapList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
-import org.apache.ambari.server.security.encryption.CredentialStoreType;
 import org.apache.ambari.server.stack.NoSuchStackException;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilder;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileEvaluationException;
 import org.apache.ambari.server.topology.ConfigRecommendationStrategy;
 import org.apache.ambari.server.topology.Configuration;
-import org.apache.ambari.server.topology.ConfigurationFactory;
 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.NoSuchBlueprintException;
 import org.apache.ambari.server.topology.SecurityConfiguration;
 import org.apache.ambari.server.topology.Service;
-import org.apache.ambari.server.topology.ServiceId;
-import org.apache.commons.lang.StringUtils;
+import org.apache.ambari.server.topology.TopologyTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Enums;
-import com.google.common.base.Strings;
-
 /**
  * Request for provisioning a cluster.
  */
 public class ProvisionClusterRequest extends BaseClusterRequest {
-  /**
-   * host groups property name
-   */
-  public static final String HOSTGROUPS_PROPERTY = "host_groups";
-
-  /**
-   * host group name property name
-   */
-  public static final String HOSTGROUP_NAME_PROPERTY = "name";
-
-  /**
-   * host group host count property name
-   */
-  public static final String HOSTGROUP_HOST_COUNT_PROPERTY = "host_count";
-
-  /**
-   * host group host predicate property name
-   */
-  public static final String HOSTGROUP_HOST_PREDICATE_PROPERTY = "host_predicate";
-
-  /**
-   * host group host fqdn property name
-   */
-  public static final String HOSTGROUP_HOST_FQDN_PROPERTY = "fqdn";
-
-
-  /**
-   * rack info property name
-   */
-  public static final String HOSTGROUP_HOST_RACK_INFO_PROPERTY = "rack_info";
-
-  /**
-   * host group hosts property name
-   */
-  public static final String HOSTGROUP_HOSTS_PROPERTY = "hosts";
-
-  /**
-   * configurations property name
-   */
-  public static final String CONFIGURATIONS_PROPERTY = "configurations";
-
-  /**
-   * services property name
-   */
-  public static final String SERVICES_PROPERTY = "services";
-
-  /**
-   * default password property name
-   */
-  public static final String DEFAULT_PASSWORD_PROPERTY = "default_password";
-
-  /**
-   * configuration recommendation strategy property name
-   */
-  public static final String CONFIG_RECOMMENDATION_STRATEGY = "config_recommendation_strategy";
 
-  /**
-   * The repo version to use
-   */
-  public static final String REPO_VERSION_PROPERTY = "repository_version";
-
-  /**
-   * The repo version id to use
-   */
-  public static final String REPO_VERSION_ID_PROPERTY = "repository_version_id";
+  private final static Logger LOG = LoggerFactory.getLogger(ProvisionClusterRequest.class);
 
   /**
    * The global quick link filters property
    */
-  public static final String QUICKLINKS_PROFILE_FILTERS_PROPERTY = "quicklinks_profile/filters";
+  static final String QUICKLINKS_PROFILE_FILTERS_PROPERTY = "quicklinks_profile/filters";
 
   /**
    * The service and component level quick link filters property
    */
-  public static final String QUICKLINKS_PROFILE_SERVICES_PROPERTY = "quicklinks_profile/services";
-  public static final String SERVICE_GROUP_NAME_PROPERETY = "service_group";
-  public static final String SERVICE_NAME_PROPERTY = "name";
-
-  /**
-   * cluster name
-   */
-  private String clusterName;
-
-  /**
-   * default password
-   */
-  private String defaultPassword;
-
-  private Map<String, Credential> credentialsMap;
-
-  /**
-   * configuration recommendation strategy
-   */
-  private final ConfigRecommendationStrategy configRecommendationStrategy;
-
-  private String repoVersion;
-
-  private Long repoVersionId;
+  static final String QUICKLINKS_PROFILE_SERVICES_PROPERTY = "quicklinks_profile/services";
 
+  private final String clusterName;
+  private final TopologyTemplate topologyTemplate;
+  private final Map<String, Credential> credentialsMap;
   private final String quickLinksProfileJson;
 
-  private final static Logger LOG = LoggerFactory.getLogger(ProvisionClusterRequest.class);
-
   /**
    * Constructor.
    *
-   * @param properties  request properties
+   * @param topologyTemplate requested topology
    * @param securityConfiguration  security config related properties
    */
-  public ProvisionClusterRequest(Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws
-    InvalidTopologyTemplateException {
-    setClusterName(String.valueOf(properties.get(
-      ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID)));
+  public ProvisionClusterRequest(TopologyTemplate topologyTemplate, Map<String, Object> properties, SecurityConfiguration securityConfiguration)
+      throws InvalidTopologyTemplateException {
 
-    if (properties.containsKey(REPO_VERSION_PROPERTY)) {
-      repoVersion = properties.get(REPO_VERSION_PROPERTY).toString();
-    }
-
-    if (properties.containsKey(REPO_VERSION_ID_PROPERTY)) {
-      repoVersionId = Long.parseLong(properties.get(REPO_VERSION_ID_PROPERTY).toString());
-    }
+    this.topologyTemplate = topologyTemplate;
 
-    if (properties.containsKey(DEFAULT_PASSWORD_PROPERTY)) {
-      defaultPassword = String.valueOf(properties.get(DEFAULT_PASSWORD_PROPERTY));
-    }
+    clusterName = String.valueOf(properties.get(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID));
 
     try {
-      parseBlueprint(properties);
+      parseBlueprint();
     } catch (NoSuchStackException e) {
       throw new InvalidTopologyTemplateException("The specified stack doesn't exist: " + e, e);
     } catch (NoSuchBlueprintException e) {
@@ -189,12 +85,12 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
     }
 
     this.securityConfiguration = securityConfiguration;
-    serviceConfigs = parseServiceConfigs(properties);
-    parseHostGroupInfo(properties);
-    this.credentialsMap = parseCredentials(properties);
-    this.configRecommendationStrategy = parseConfigRecommendationStrategy(properties);
+    serviceConfigs = mergeServiceConfigs();
+    processHostGroups();
+    credentialsMap = this.topologyTemplate.getCredentials().stream()
+      .collect(toMap(Credential::getAlias, Function.identity()));
 
-    setProvisionAction(parseProvisionAction(properties));
+    setProvisionAction(topologyTemplate.getProvisionAction());
 
     try {
       this.quickLinksProfileJson = processQuickLinksProfile(properties);
@@ -203,31 +99,18 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
     }
   }
 
-  private List<Service> parseServiceConfigs(Map<String, Object> properties) throws InvalidTopologyTemplateException {
-    // parse service configs and merge with BP service configs
+  private List<Service> mergeServiceConfigs() throws InvalidTopologyTemplateException {
+    // merge with BP service configs
     List<Service> serviceConfigs = new ArrayList<>();
-    Collection<Map<String, Object>> services = toBranchMapList(properties.get(SERVICES_PROPERTY));
-    if (services != null) {
-      for (Map<String, Object> serviceMap : services) {
-        String serviceName = (String) serviceMap.get(SERVICE_NAME_PROPERTY);
-        if (StringUtils.isEmpty(serviceName)) {
-          throw new InvalidTopologyTemplateException("Service name must be specified.");
-        }
-        String serviceGroupName = (String) serviceMap.get(SERVICE_GROUP_NAME_PROPERETY);
-        if (StringUtils.isEmpty(serviceGroupName)) {
-          throw new InvalidTopologyTemplateException("Service group name must be specified for service: " + serviceName);
-        }
-        Configuration configuration = ConfigurationFactory.toConfiguration(toLeafMapList(serviceMap.get(CONFIGURATIONS_PROPERTY)));
-        ServiceId serviceId = ServiceId.of(serviceName, serviceGroupName);
-        Service service = blueprint.getServiceById(serviceId);
-        if (service == null) {
-          throw new InvalidTopologyTemplateException("Service: " + serviceName + " in service group: "
-            + serviceGroupName + " not found.");
-        }
-        configuration.setParentConfiguration(service.getConfiguration());
-        service.setConfiguration(configuration);
-        serviceConfigs.add(service);
+    for (TopologyTemplate.Service s : topologyTemplate.getServices()) {
+      Service service = blueprint.getServiceById(s.getId());
+      if (service == null) {
+        throw new InvalidTopologyTemplateException("Service: " + s.getName() + " in service group: " + s.getServiceGroup() + " not found.");
       }
+      Configuration configuration = s.getConfiguration();
+      configuration.setParentConfiguration(service.getConfiguration());
+      service.setConfiguration(configuration);
+      serviceConfigs.add(service);
     }
     return serviceConfigs;
   }
@@ -240,41 +123,6 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
   }
 
 
-  private Map<String, Credential> parseCredentials(Map<String, Object> properties) throws
-    InvalidTopologyTemplateException {
-    HashMap<String, Credential> credentialHashMap = new HashMap<>();
-    Collection<Map<String, String>> credentialsSet = toLeafMapList(properties.get(ClusterResourceProvider.CREDENTIALS));
-    if (credentialsSet != null) {
-      for (Map<String, String> credentialMap : credentialsSet) {
-        String alias = Strings.emptyToNull(credentialMap.get("alias"));
-        if (alias == null) {
-          throw new InvalidTopologyTemplateException("credential.alias property is missing.");
-        }
-        String principal = Strings.emptyToNull(credentialMap.get("principal"));
-        if (principal == null) {
-          throw new InvalidTopologyTemplateException("credential.principal property is missing.");
-        }
-        String key = Strings.emptyToNull(credentialMap.get("key"));
-        if (key == null) {
-          throw new InvalidTopologyTemplateException("credential.key is missing.");
-        }
-        String typeString = Strings.emptyToNull(credentialMap.get("type"));
-        if (typeString == null) {
-          throw new InvalidTopologyTemplateException("credential.type is missing.");
-        }
-        CredentialStoreType type = Enums.getIfPresent(CredentialStoreType.class, typeString.toUpperCase()).orNull();
-        if (type == null) {
-          throw new InvalidTopologyTemplateException(
-            String.format("credential.type [%s] is invalid. acceptable values: %s", typeString.toUpperCase(),
-              Arrays.toString(CredentialStoreType.values())
-            ));
-        }
-        credentialHashMap.put(alias, new Credential(alias, principal, key, type));
-      }
-    }
-    return credentialHashMap;
-  }
-
   public Map<String, Credential> getCredentialsMap() {
     return credentialsMap;
   }
@@ -283,12 +131,8 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
     return clusterName;
   }
 
-  public void setClusterName(String clusterName) {
-    this.clusterName = clusterName;
-  }
-
   public ConfigRecommendationStrategy getConfigRecommendationStrategy() {
-    return configRecommendationStrategy;
+    return topologyTemplate.getConfigRecommendationStrategy();
   }
 
   @Override
@@ -311,15 +155,13 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
   }
 
   /**
-   * Parse blueprint.
-   *
-   * @param properties  request properties
+   * Load the blueprint specified in the request from the DB.
    *
    * @throws NoSuchStackException     if specified stack doesn't exist
    * @throws NoSuchBlueprintException if specified blueprint doesn't exist
    */
-  private void parseBlueprint(Map<String, Object> properties) throws NoSuchStackException, NoSuchBlueprintException {
-    String blueprintName = String.valueOf(properties.get(ClusterResourceProvider.BLUEPRINT));
+  private void parseBlueprint() throws NoSuchStackException, NoSuchBlueprintException {
+    String blueprintName = topologyTemplate.getBlueprint();
     // set blueprint field
     try {
       setBlueprint(getBlueprintFactory().getBlueprint(blueprintName));
@@ -333,174 +175,21 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
     }
   }
 
-  /**
-   * Parse host group information.
-   *
-   * @param properties  request properties
-   *
-   * @throws InvalidTopologyTemplateException  if any validation checks on properties fail
-   */
-  private void parseHostGroupInfo(Map<String, Object> properties) throws InvalidTopologyTemplateException {
-    Collection<Map<String, Object>> hostGroups = toBranchMapList(properties.get(HOSTGROUPS_PROPERTY));
-
-    if (hostGroups == null || hostGroups.isEmpty()) {
-      throw new InvalidTopologyTemplateException("'host_groups' element must be included in cluster create body");
-    }
-
-    for (Map<String, Object> hostGroupProperties : hostGroups) {
-      processHostGroup(hostGroupProperties);
-    }
-  }
-
-  /**
-   * Process host group properties.
-   *
-   * @param hostGroupProperties  host group properties
-   *
-   * @throws InvalidTopologyTemplateException if any validation checks on properties fail
-   */
-  private void processHostGroup(Map<String, Object> hostGroupProperties) throws InvalidTopologyTemplateException {
-    String name = String.valueOf(hostGroupProperties.get(HOSTGROUP_NAME_PROPERTY));
-    // String.valueOf() converts null to "null"
-    if (name == null || name.equals("null") || name.isEmpty()) {
-      throw new InvalidTopologyTemplateException("All host groups must contain a 'name' element");
-    }
-
-    HostGroupInfo hostGroupInfo = new HostGroupInfo(name);
-    getHostGroupInfo().put(name, hostGroupInfo);
-
-    processHostCountAndPredicate(hostGroupProperties, hostGroupInfo);
-    processGroupHosts(name, toLeafMapList(hostGroupProperties.get(HOSTGROUP_HOSTS_PROPERTY)), hostGroupInfo);
-
-    // don't set the parent configuration
-    hostGroupInfo.setConfiguration(ConfigurationFactory.toConfiguration(toLeafMapList(hostGroupProperties.get(CONFIGURATIONS_PROPERTY))));
-  }
-
-  /**
-   * Process host count and host predicate for a host group.
-   *
-   * @param hostGroupProperties  host group properties
-   * @param hostGroupInfo        associated host group info instance
-   *
-   * @throws InvalidTopologyTemplateException  specified host group properties fail validation
-   */
-  private void processHostCountAndPredicate(Map<String, Object> hostGroupProperties, HostGroupInfo hostGroupInfo)
-    throws InvalidTopologyTemplateException {
-
-    if (hostGroupProperties.containsKey(HOSTGROUP_HOST_COUNT_PROPERTY)) {
-      hostGroupInfo.setRequestedCount(Integer.valueOf(String.valueOf(
-        hostGroupProperties.get(HOSTGROUP_HOST_COUNT_PROPERTY))));
-      LOG.info("Stored expected hosts count {} for group {}",
-        hostGroupInfo.getRequestedHostCount(), hostGroupInfo.getHostGroupName());
-    }
-
-    if (hostGroupProperties.containsKey(HOSTGROUP_HOST_PREDICATE_PROPERTY)) {
-      if (hostGroupInfo.getRequestedHostCount() == 0) {
-        throw new InvalidTopologyTemplateException(String.format(
-          "Host group '%s' must not specify 'host_predicate' without 'host_count'",
-          hostGroupInfo.getHostGroupName()));
-      }
-
-      String hostPredicate = String.valueOf(hostGroupProperties.get(HOSTGROUP_HOST_PREDICATE_PROPERTY));
-      validateHostPredicateProperties(hostPredicate);
-      try {
-        hostGroupInfo.setPredicate(hostPredicate);
-        LOG.info("Compiled host predicate {} for group {}", hostPredicate, hostGroupInfo.getHostGroupName());
-      } catch (InvalidQueryException e) {
-        throw new InvalidTopologyTemplateException(
-          String.format("Unable to compile host predicate '%s': %s", hostPredicate, e), e);
-      }
-    }
-  }
-
-  /**
-   * Process host group hosts.
-   *
-   * @param name           host group name
-   * @param hosts          collection of host group host properties
-   * @param hostGroupInfo  associated host group info instance
-   *
-   * @throws InvalidTopologyTemplateException specified host group properties fail validation
-   */
-  private void processGroupHosts(String name, Collection<Map<String, String>> hosts, HostGroupInfo hostGroupInfo)
-    throws InvalidTopologyTemplateException {
-
-    if (hosts != null) {
-      if (hostGroupInfo.getRequestedHostCount() != 0) {
-        throw new InvalidTopologyTemplateException(String.format(
-          "Host group '%s' must not contain both a 'hosts' element and a 'host_count' value", name));
-      }
-
-      if (hostGroupInfo.getPredicate() != null) {
-        throw new InvalidTopologyTemplateException(String.format(
-          "Host group '%s' must not contain both a 'hosts' element and a 'host_predicate' value", name));
-      }
-
-      for (Map<String, String> hostProperties : hosts) {
-        if (hostProperties.containsKey(HOSTGROUP_HOST_FQDN_PROPERTY)) {
-          hostGroupInfo.addHost(hostProperties.get(HOSTGROUP_HOST_FQDN_PROPERTY));
-        }
-
-        if (hostProperties.containsKey(HOSTGROUP_HOST_RACK_INFO_PROPERTY)) {
-          hostGroupInfo.addHostRackInfo(
-            hostProperties.get(HOSTGROUP_HOST_FQDN_PROPERTY),
-            hostProperties.get(HOSTGROUP_HOST_RACK_INFO_PROPERTY));
-        }
-      }
-    }
-
-    if (hostGroupInfo.getRequestedHostCount() == 0) {
-      throw new InvalidTopologyTemplateException(String.format(
-        "Host group '%s' must contain at least one 'hosts/fqdn' or a 'host_count' value", name));
-    }
-  }
-
-  /**
-   * Parse config recommendation strategy. Throws exception in case of the value is not correct.
-   * The default value is {@link ConfigRecommendationStrategy#NEVER_APPLY}
-   * @param properties request properties
-   * @throws InvalidTopologyTemplateException specified config recommendation strategy property fail validation
-   */
-  private ConfigRecommendationStrategy parseConfigRecommendationStrategy(Map<String, Object> properties) throws InvalidTopologyTemplateException {
-    return getEnumValue(properties, CONFIG_RECOMMENDATION_STRATEGY, ConfigRecommendationStrategy.class, ConfigRecommendationStrategy.NEVER_APPLY);
+  private void processHostGroups() {
+    getHostGroupInfo().putAll(topologyTemplate.getHostGroups().stream()
+      .map(this::processHostGroup)
+      .collect(toMap(HostGroupInfo::getHostGroupName, Function.identity())));
   }
 
-  /**
-   * Parse Provision Action specified in RequestInfo properties.
-   */
-  private ProvisionAction parseProvisionAction(Map<String, Object> properties) throws InvalidTopologyTemplateException {
-    return getEnumValue(properties, PROVISION_ACTION_PROPERTY, ProvisionAction.class, ProvisionAction.INSTALL_AND_START);
-  }
-
-  private static <T extends Enum<T>> T getEnumValue(Map<String, ?> properties, String key, Class<T> enumType, T defaultValue)
-    throws InvalidTopologyTemplateException {
-
-    Object obj = properties.get(key);
-    if (obj == null) {
-      return defaultValue;
-    }
-
-    String name = String.valueOf(obj);
-    try {
-      return Enum.valueOf(enumType, name);
-    } catch (IllegalArgumentException e) {
-      String msg = String.format("Unsupported '%s' value: '%s'", key, name);
-      throw new InvalidTopologyTemplateException(msg);
-    }
-  }
-
-  /**
-   * @return the repository version, if any
-   */
-  public String getRepositoryVersion() {
-    return repoVersion;
-  }
-
-  /**
-   * @return the repository version id or {@code null}
-   */
-  public Long getRepositoryVersionId(){
-    return repoVersionId;
+  // TODO get rid of duplicate topology host group representation
+  private HostGroupInfo processHostGroup(TopologyTemplate.HostGroup input) {
+    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()));
+    output.setConfiguration(input.getConfiguration());
+    return output;
   }
 
   /**
@@ -511,7 +200,7 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
   }
 
   public String getDefaultPassword() {
-    return defaultPassword;
+    return topologyTemplate.getDefaultPassword();
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
index 1284c26..a3a764f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
@@ -24,7 +24,6 @@ import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.stack.NoSuchStackException;
 import org.apache.ambari.server.topology.BlueprintV2;
 import org.apache.ambari.server.topology.Configuration;
@@ -156,7 +155,7 @@ public class ScaleClusterRequest extends BaseClusterRequest {
         validateHostPredicateProperties(predicate);
         try {
           hostGroupInfo.setPredicate(predicate);
-        } catch (InvalidQueryException e) {
+        } catch (IllegalArgumentException e) {
           throw new InvalidTopologyTemplateException(
               String.format("Unable to compile host predicate '%s': %s", predicate, e), e);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index a12e066..20df9e68 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -58,7 +58,6 @@ import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
 import org.apache.ambari.server.controller.internal.ConfigGroupResourceProvider;
 import org.apache.ambari.server.controller.internal.HostComponentResourceProvider;
 import org.apache.ambari.server.controller.internal.HostResourceProvider;
-import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
 import org.apache.ambari.server.controller.internal.RequestImpl;
 import org.apache.ambari.server.controller.internal.ServiceDependencyResourceProvider;
 import org.apache.ambari.server.controller.internal.ServiceGroupDependencyResourceProvider;
@@ -250,9 +249,8 @@ public class AmbariContext {
 
         if (null == repoVersion) {
           throw new IllegalArgumentException(String.format(
-            "Could not identify repository version with stack %s and version %s for installing services. "
-              + "Specify a valid version with '%s'",
-            stackId, stack.getRepoVersion(), ProvisionClusterRequest.REPO_VERSION_PROPERTY));
+            "Could not identify repository version with stack %s and version %s for installing services.",
+            stackId, stack.getRepoVersion()));
         }
 
         // only use a STANDARD repo when creating a new cluster

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/topology/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ConfigurationFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ConfigurationFactory.java
index 63a96e5..d8fcd81 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/ConfigurationFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ConfigurationFactory.java
@@ -70,16 +70,6 @@ public class ConfigurationFactory {
     }
   }
 
-  @SuppressWarnings("unchecked")
-  public static Collection<Map<String, Object>> toBranchMapList(Object o) {
-    return (Collection<Map<String, Object>>) o;
-  }
-
-  @SuppressWarnings("unchecked")
-  public static Collection<Map<String, String>> toLeafMapList(Object o) {
-    return (Collection<Map<String, String>>) o;
-  }
-
   /**
    * The structure of blueprints is evolving where multiple resource
    * structures are to be supported. This class abstracts the population

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 637cfe8..1858368 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
@@ -23,6 +23,7 @@ import org.apache.ambari.server.security.encryption.CredentialStoreType;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
 
 /**
  * Holds credential info submitted in a cluster create template.
@@ -75,4 +76,11 @@ public class Credential {
   public CredentialStoreType getType() {
     return type;
   }
+
+  public void validate() {
+    Preconditions.checkNotNull(alias, "credential.alias is missing");
+    Preconditions.checkNotNull(principal, "credential.principal is missing");
+    Preconditions.checkNotNull(key, "credential.key is missing");
+    Preconditions.checkNotNull(type, "credential.type is missing or invalid");
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 8ddc088..8e3d237 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
@@ -192,11 +192,17 @@ public class HostGroupInfo {
    * Set the host predicate for the host group.
    *
    * @param predicateString  host predicate as a string
-   * @throws InvalidQueryException if compilation of the predicate fails
+   * @throws IllegalArgumentException if compilation of the predicate fails
    */
-  public void setPredicate(String predicateString) throws InvalidQueryException {
-    this.predicate = PREDICATE_COMPILER.compile(predicateString);
-    this.predicateString = predicateString;
+  public void setPredicate(String predicateString) {
+    if (predicateString != null) {
+      try {
+        this.predicate = PREDICATE_COMPILER.compile(predicateString);
+        this.predicateString = predicateString;
+      } catch (InvalidQueryException e) {
+        throw new IllegalArgumentException(e);
+      }
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 3bfa644..6d0c794 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
@@ -29,7 +29,6 @@ import javax.inject.Singleton;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
-import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.controller.internal.BaseClusterRequest;
 import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
@@ -501,8 +500,8 @@ public class PersistedStateImpl implements PersistedState {
             if (hostPredicate != null) {
               try {
                 groupInfo.setPredicate(hostPredicate);
-              } catch (InvalidQueryException e) {
-                // log error but proceed with now predicate set
+              } catch (IllegalArgumentException e) {
+                // log error but proceed with no predicate set
                 LOG.error(String.format(
                     "Failed to compile predicate '%s' during request replay: %s", hostPredicate, e), e);
               }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
index 3b7dcc8..75711c1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
@@ -274,8 +274,6 @@ public class TopologyManager {
 
     final ClusterTopology topology = new ClusterTopologyImpl(ambariContext, request);
     final String clusterName = request.getClusterName();
-    final String repoVersion = request.getRepositoryVersion();
-    final Long repoVersionID = request.getRepositoryVersionId();
 
     // get the id prior to creating ambari resources which increments the counter
     final Long provisionId = ambariContext.getNextRequestId();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java
index 751e2d7..dd48f27 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactory.java
@@ -28,6 +28,6 @@ import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
  */
 public interface TopologyRequestFactory {
 
-  ProvisionClusterRequest createProvisionClusterRequest(Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException;
+  ProvisionClusterRequest createProvisionClusterRequest(TopologyTemplate topology, Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException;
   // todo: use to create other request types
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java
index ff79f52..a7336cf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequestFactoryImpl.java
@@ -28,8 +28,8 @@ import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
  */
 public class TopologyRequestFactoryImpl implements TopologyRequestFactory {
   @Override
-  public ProvisionClusterRequest createProvisionClusterRequest(Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException {
-    return new ProvisionClusterRequest(properties, securityConfiguration);
+  public ProvisionClusterRequest createProvisionClusterRequest(TopologyTemplate topology, Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws InvalidTopologyTemplateException {
+    return new ProvisionClusterRequest(topology, properties, securityConfiguration);
 
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 4b9e19b..ffed3be 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
@@ -32,33 +32,24 @@ import org.apache.ambari.server.controller.internal.ProvisionAction;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 
 public class TopologyTemplate {
 
-  private String blueprint = null;
-
-  @JsonProperty("default_password")
-  private String defaultPassword = null;
-
-  @JsonProperty("config_recommendation_strategy")
-  private ConfigRecommendationStrategy configRecommendationStrategy;
-
-  @JsonProperty("provision_action")
-  private ProvisionAction provisionAction;
-
+  private String blueprint;
+  private String defaultPassword;
+  private ConfigRecommendationStrategy configRecommendationStrategy = ConfigRecommendationStrategy.NEVER_APPLY;
+  private ProvisionAction provisionAction = ProvisionAction.INSTALL_AND_START;
   private Map<ServiceId, TopologyTemplate.Service> servicesById = Collections.emptyMap();
-
   private Map<String, TopologyTemplate.HostGroup> hostGroups = Collections.emptyMap();
-
-  private Collection<Credential> credentials;
-
-  @JsonProperty("security")
-  private SecurityConfiguration securityConfiguration;
+  private Collection<Credential> credentials = Collections.emptySet();
+  private SecurityConfiguration securityConfiguration = SecurityConfiguration.NONE;
 
   public String getBlueprint() {
     return blueprint;
   }
 
+  @JsonProperty("blueprint")
   public void setBlueprint(String blueprint) {
     this.blueprint = blueprint;
   }
@@ -67,6 +58,7 @@ public class TopologyTemplate {
     return defaultPassword;
   }
 
+  @JsonProperty("default_password")
   public void setDefaultPassword(String defaultPassword) {
     this.defaultPassword = defaultPassword;
   }
@@ -97,6 +89,7 @@ public class TopologyTemplate {
     return securityConfiguration;
   }
 
+  @JsonProperty("security")
   public void setSecurityConfiguration(SecurityConfiguration securityConfiguration) {
     this.securityConfiguration = securityConfiguration;
   }
@@ -105,6 +98,7 @@ public class TopologyTemplate {
     return configRecommendationStrategy;
   }
 
+  @JsonProperty("config_recommendation_strategy")
   public void setConfigRecommendationStrategy(ConfigRecommendationStrategy configRecommendationStrategy) {
     this.configRecommendationStrategy = configRecommendationStrategy;
   }
@@ -113,6 +107,7 @@ public class TopologyTemplate {
     return provisionAction;
   }
 
+  @JsonProperty("provision_action")
   public void setProvisionAction(ProvisionAction provisionAction) {
     this.provisionAction = provisionAction;
   }
@@ -132,23 +127,24 @@ public class TopologyTemplate {
   }
 
   public void validate() throws IllegalStateException {
+    Preconditions.checkArgument(hostGroups != null && !hostGroups.isEmpty(), "At least one host group must be specified");
     getHostGroups().forEach(HostGroup::validate);
+    getServices().forEach(Service::validate);
+    getCredentials().forEach(Credential::validate);
   }
 
   public static class HostGroup implements Configurable {
     private String name;
-    @JsonIgnore
-    private Configuration configuration;
+    private Configuration configuration = Configuration.createEmpty();
     private Collection<Host> hosts = Collections.emptyList();
-    @JsonProperty("host_count")
-    private int hostCount = 0;
-    @JsonProperty("host_predicate")
+    private int hostCount;
     private String hostPredicate;
 
     public String getName() {
       return name;
     }
 
+    @JsonProperty("name")
     public void setName(String name) {
       this.name = name;
     }
@@ -158,6 +154,7 @@ public class TopologyTemplate {
       return configuration;
     }
 
+    @JsonIgnore
     @Override
     public void setConfiguration(Configuration configuration) {
       this.configuration = configuration;
@@ -167,6 +164,7 @@ public class TopologyTemplate {
       return hosts;
     }
 
+    @JsonProperty("hosts")
     public void setHosts(Collection<Host> hosts) {
       this.hosts = hosts;
     }
@@ -175,6 +173,7 @@ public class TopologyTemplate {
       return hostCount;
     }
 
+    @JsonProperty("host_count")
     public void setHostCount(int hostCount) {
       this.hostCount = hostCount;
     }
@@ -183,29 +182,35 @@ public class TopologyTemplate {
       return hostPredicate;
     }
 
+    @JsonProperty("host_predicate")
     public void setHostPredicate(String hostPredicate) {
       this.hostPredicate = hostPredicate;
     }
 
     void validate() throws IllegalStateException {
-      Preconditions.checkState((hostCount == 0 && null == hostPredicate) || getHosts().isEmpty(),
-        "Invalid custer topology template. Host group %s must have either declatere its hosts or " +
-          "hostcount (and optionally host predicate)", name);
+      Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Host group name must be specified");
+      Preconditions.checkArgument(hostCount > 0 || !hosts.isEmpty(),
+        "Host group '%s' must contain either 'hosts' or 'host_count'", name);
+      Preconditions.checkArgument(hostCount == 0 || hosts.isEmpty(),
+        "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);
     }
   }
 
   public static class Service implements Configurable {
     private String name;
-    @JsonProperty("service_group")
     private String serviceGroup;
-    @JsonIgnore
-    private Configuration configuration;
+    private Configuration configuration = Configuration.createEmpty();
 
     @Override
     public Configuration getConfiguration() {
       return configuration;
     }
 
+    @JsonIgnore
     @Override
     public void setConfiguration(Configuration configuration) {
       this.configuration = configuration;
@@ -220,6 +225,7 @@ public class TopologyTemplate {
       return name;
     }
 
+    @JsonProperty("name")
     public void setName(String name) {
       this.name = name;
     }
@@ -228,20 +234,26 @@ public class TopologyTemplate {
       return serviceGroup;
     }
 
+    @JsonProperty("service_group")
     public void setServiceGroup(String serviceGroup) {
       this.serviceGroup = serviceGroup;
     }
+
+    public void validate() {
+      Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Service name must be specified");
+      Preconditions.checkArgument(!Strings.isNullOrEmpty(serviceGroup), "Service group name must be specified for service %s", name);
+    }
   }
 
   public static class Host {
     private String fqdn;
-    @JsonProperty("rack_info")
-    private String  rackInfo;
+    private String rackInfo;
 
     public String getFqdn() {
       return fqdn;
     }
 
+    @JsonProperty("fqdn")
     public void setFqdn(String fqdn) {
       this.fqdn = fqdn;
     }
@@ -250,9 +262,14 @@ public class TopologyTemplate {
       return rackInfo;
     }
 
+    @JsonProperty("rack_info")
     public void setRackInfo(String rackInfo) {
       this.rackInfo = rackInfo;
     }
+
+    public void validate() {
+      Preconditions.checkArgument(!Strings.isNullOrEmpty(fqdn), "Host name must be specified");
+    }
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 6e503a6..3d15c7a 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
@@ -154,7 +154,7 @@ public class ClusterResourceProviderTest {
 
     expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null)
       .once();
-    expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once();
+    expect(topologyFactory.createProvisionClusterRequest(null, properties, null)).andReturn(topologyRequest).once();
     expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once();
     expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes();
 
@@ -187,7 +187,7 @@ public class ClusterResourceProviderTest {
 
     expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn
       (securityConfiguration).once();
-    expect(topologyFactory.createProvisionClusterRequest(properties, securityConfiguration)).andReturn(topologyRequest).once();
+    expect(topologyFactory.createProvisionClusterRequest(null, properties, securityConfiguration)).andReturn(topologyRequest).once();
     expect(topologyRequest.getBlueprint()).andReturn(null).anyTimes();
     expect(blueprint.getSecurity()).andReturn(blueprintSecurityConfiguration).anyTimes();
     expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes();
@@ -211,7 +211,7 @@ public class ClusterResourceProviderTest {
     expect(request.getProperties()).andReturn(requestProperties).anyTimes();
     expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).anyTimes();
 
-    expect(topologyFactory.createProvisionClusterRequest(properties, securityConfiguration)).andReturn(topologyRequest).once();
+    expect(topologyFactory.createProvisionClusterRequest(null, properties, securityConfiguration)).andReturn(topologyRequest).once();
     expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn
       (securityConfiguration).once();
     expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once();
@@ -235,7 +235,7 @@ public class ClusterResourceProviderTest {
     // set expectations
     expect(request.getProperties()).andReturn(requestProperties).anyTimes();
     // throw exception from topology request factory an assert that the correct exception is thrown from resource provider
-    expect(topologyFactory.createProvisionClusterRequest(properties, null)).andThrow(new InvalidTopologyException
+    expect(topologyFactory.createProvisionClusterRequest(null, properties, null)).andThrow(new InvalidTopologyException
       ("test"));
 
     replayAll();
@@ -503,7 +503,7 @@ public class ClusterResourceProviderTest {
 
     expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null)
         .once();
-    expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once();
+    expect(topologyFactory.createProvisionClusterRequest(null, properties, null)).andReturn(topologyRequest).once();
     expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once();
     expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes();
 
@@ -827,36 +827,4 @@ public class ClusterResourceProviderTest {
     assertNotNull(cap.getValue());
   }
 
-  @Test
-  public void testCreateResource_blueprint_withRepoVersion() throws Exception {
-    Authentication authentication = TestAuthenticationFactory.createAdministrator();
-
-    Set<Map<String, Object>> requestProperties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME);
-    Map<String, Object> properties = requestProperties.iterator().next();
-    properties.put(ProvisionClusterRequest.REPO_VERSION_PROPERTY, "2.1.1");
-
-    Map<String, String> requestInfoProperties = new HashMap<>();
-    requestInfoProperties.put(Request.REQUEST_INFO_BODY_PROPERTY, "{}");
-
-    // set expectations
-    expect(request.getProperties()).andReturn(requestProperties).anyTimes();
-    expect(request.getRequestInfoProperties()).andReturn(requestInfoProperties).anyTimes();
-
-    expect(securityFactory.createSecurityConfigurationFromRequest(EasyMock.anyObject(), anyBoolean())).andReturn(null)
-        .once();
-    expect(topologyFactory.createProvisionClusterRequest(properties, null)).andReturn(topologyRequest).once();
-    expect(topologyManager.provisionCluster(topologyRequest)).andReturn(requestStatusResponse).once();
-    expect(requestStatusResponse.getRequestId()).andReturn(5150L).anyTimes();
-
-    replayAll();
-    SecurityContextHolder.getContext().setAuthentication(authentication);
-
-    RequestStatus requestStatus = provider.createResources(request);
-    assertEquals(5150L, requestStatus.getRequestResource().getPropertyValue(PropertyHelper.getPropertyId("Requests", "id")));
-    assertEquals(Resource.Type.Request, requestStatus.getRequestResource().getType());
-    assertEquals("Accepted", requestStatus.getRequestResource().getPropertyValue(PropertyHelper.getPropertyId("Requests", "status")));
-
-    verifyAll();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/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 01d69a5..0e1ad30 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
@@ -109,7 +109,7 @@ public class ProvisionClusterRequestTest {
     replay(hostResourceProvider);
     Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME);
 
-    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null);
 
     assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName());
     assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType());
@@ -160,7 +160,7 @@ public class ProvisionClusterRequestTest {
     replay(hostResourceProvider);
     Map<String, Object> properties = createBlueprintRequestPropertiesCountOnly(CLUSTER_NAME, BLUEPRINT_NAME);
 
-    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null);
 
     assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName());
     assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType());
@@ -211,7 +211,7 @@ public class ProvisionClusterRequestTest {
   @Test
   public void testMultipleGroups() throws Exception {
     Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME);
-    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null);
 
     assertEquals(CLUSTER_NAME, provisionClusterRequest.getClusterName());
     assertEquals(TopologyRequest.Type.PROVISION, provisionClusterRequest.getType());
@@ -286,7 +286,7 @@ public class ProvisionClusterRequestTest {
     reset(hostResourceProvider);
     replay(hostResourceProvider);
     // should result in an exception
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test
@@ -301,7 +301,7 @@ public class ProvisionClusterRequestTest {
     credentialsSet.add(credentialHashMap);
     properties.put("credentials", credentialsSet);
 
-    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null);
 
     assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getAlias(), "testAlias");
     assertEquals(provisionClusterRequest.getCredentialsMap().get("testAlias").getPrincipal(), "testPrincipal");
@@ -326,7 +326,7 @@ public class ProvisionClusterRequestTest {
     credentialsSet.add(credentialHashMap);
     properties.put("credentials", credentialsSet);
 
-    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest provisionClusterRequest = new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test(expected= InvalidTopologyTemplateException.class)
@@ -338,7 +338,7 @@ public class ProvisionClusterRequestTest {
     reset(hostResourceProvider);
     replay(hostResourceProvider);
     // should result in an exception
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test(expected= InvalidTopologyTemplateException.class)
@@ -350,7 +350,7 @@ public class ProvisionClusterRequestTest {
     reset(hostResourceProvider);
     replay(hostResourceProvider);
     // should result in an exception
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test(expected = InvalidTopologyTemplateException.class)
@@ -370,7 +370,7 @@ public class ProvisionClusterRequestTest {
     reset(hostResourceProvider);
     replay(hostResourceProvider);
     // should result in an exception
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
 
@@ -383,7 +383,7 @@ public class ProvisionClusterRequestTest {
     replay(hostResourceProvider);
 
     // should result in an exception due to invalid property in host predicate
-    new ProvisionClusterRequest(createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null);
+    new ProvisionClusterRequest(null, createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME), null);
   }
 
   @Test(expected = InvalidTopologyTemplateException.class)
@@ -395,7 +395,7 @@ public class ProvisionClusterRequestTest {
     Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME);
     ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_count", "5");
     // should result in an exception due to both host name and host count being specified
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test(expected = InvalidTopologyTemplateException.class)
@@ -407,13 +407,13 @@ public class ProvisionClusterRequestTest {
     Map<String, Object> properties = createBlueprintRequestPropertiesNameOnly(CLUSTER_NAME, BLUEPRINT_NAME);
     ((Map) ((List) properties.get("host_groups")).iterator().next()).put("host_predicate", "Hosts/host_name=myTestHost");
     // should result in an exception due to both host name and host count being specified
-    new ProvisionClusterRequest(properties, null);
+    new ProvisionClusterRequest(null, properties, null);
   }
 
   @Test
   public void testQuickLinksProfile_NoDataInRequest() throws Exception {
     Map<String, Object> properties = createBlueprintRequestProperties(CLUSTER_NAME, BLUEPRINT_NAME);
-    ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null);
     assertNull("No quick links profile is expected", request.getQuickLinksProfileJson());
   }
 
@@ -424,7 +424,7 @@ public class ProvisionClusterRequestTest {
     properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_FILTERS_PROPERTY,
         Sets.newHashSet(QuickLinksProfileBuilderTest.filter(null, null, true)));
 
-    ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null);
     assertEquals("Quick links profile doesn't match expected",
         "{\"filters\":[{\"visible\":true}],\"services\":[]}",
         request.getQuickLinksProfileJson());
@@ -439,7 +439,7 @@ public class ProvisionClusterRequestTest {
     Set<Map<String, Object>> services = Sets.newHashSet(hdfs);
     properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services);
 
-    ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null);
     assertEquals("Quick links profile doesn't match expected",
         "{\"filters\":[],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}",
         request.getQuickLinksProfileJson());
@@ -457,7 +457,7 @@ public class ProvisionClusterRequestTest {
     Set<Map<String, Object>> services = Sets.newHashSet(hdfs);
     properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, services);
 
-    ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null);
     System.out.println(request.getQuickLinksProfileJson());
     assertEquals("Quick links profile doesn't match expected",
         "{\"filters\":[{\"visible\":true}],\"services\":[{\"name\":\"HDFS\",\"components\":[],\"filters\":[{\"visible\":true}]}]}",
@@ -470,7 +470,7 @@ public class ProvisionClusterRequestTest {
 
     properties.put(ProvisionClusterRequest.QUICKLINKS_PROFILE_SERVICES_PROPERTY, "Hello World!");
 
-    ProvisionClusterRequest request = new ProvisionClusterRequest(properties, null);
+    ProvisionClusterRequest request = new ProvisionClusterRequest(null, properties, null);
   }
 
   public static Map<String, Object> createBlueprintRequestProperties(String clusterName, String blueprintName) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithStartOnlyTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithStartOnlyTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithStartOnlyTest.java
index a22cef3..b8336dd 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithStartOnlyTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithStartOnlyTest.java
@@ -297,7 +297,6 @@ public class ClusterDeployWithStartOnlyTest extends EasyMockSupport {
     expect(request.getConfigRecommendationStrategy()).andReturn(ConfigRecommendationStrategy.NEVER_APPLY);
     expect(request.getProvisionAction()).andReturn(ProvisionAction.START_ONLY).anyTimes();
     expect(request.getSecurityConfiguration()).andReturn(null).anyTimes();
-    expect(request.getRepositoryVersion()).andReturn("1").anyTimes();
 
     expect(group1.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes();
     expect(group1.getCardinality()).andReturn("test cardinality").anyTimes();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartOnComponentLevelTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartOnComponentLevelTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartOnComponentLevelTest.java
index ba2118d..8c67d60 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartOnComponentLevelTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartOnComponentLevelTest.java
@@ -293,7 +293,6 @@ public class ClusterInstallWithoutStartOnComponentLevelTest extends EasyMockSupp
     expect(request.getConfigRecommendationStrategy()).andReturn(ConfigRecommendationStrategy.NEVER_APPLY);
     expect(request.getProvisionAction()).andReturn(INSTALL_AND_START).anyTimes();
     expect(request.getSecurityConfiguration()).andReturn(null).anyTimes();
-    expect(request.getRepositoryVersion()).andReturn("1").anyTimes();
 
     expect(group1.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes();
     expect(group1.getCardinality()).andReturn("test cardinality").anyTimes();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ba267a8c/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
index 8d58107..6a5a930 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
@@ -295,7 +295,6 @@ public class ClusterInstallWithoutStartTest extends EasyMockSupport {
     expect(request.getConfigRecommendationStrategy()).andReturn(ConfigRecommendationStrategy.NEVER_APPLY);
     expect(request.getProvisionAction()).andReturn(INSTALL_ONLY).anyTimes();
     expect(request.getSecurityConfiguration()).andReturn(null).anyTimes();
-    expect(request.getRepositoryVersion()).andReturn("1").anyTimes();
 
     expect(group1.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes();
     expect(group1.getCardinality()).andReturn("test cardinality").anyTimes();


[2/2] ambari git commit: AMBARI-22253. Make ProvisionClusterRequestTest work (adoroszlai)

Posted by ad...@apache.org.
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/fd550ca8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fd550ca8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fd550ca8

Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2
Commit: fd550ca8941b76db9dced679b76f8f1db7fad42d
Parents: ba267a8
Author: Doroszlai, Attila <ad...@hortonworks.com>
Authored: Fri Dec 1 19:02:37 2017 +0100
Committer: Doroszlai, Attila <ad...@hortonworks.com>
Committed: Fri Dec 1 19:02:37 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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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 6d0c794..af5b08d 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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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/fd550ca8/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();