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/4e45eb09
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4e45eb09
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4e45eb09

Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2
Commit: 4e45eb09d97d14100a372a573d2e92332e68c9cb
Parents: 387a6ac
Author: Doroszlai, Attila <adorosz...@hortonworks.com>
Authored: Fri Dec 1 06:59:08 2017 +0100
Committer: Doroszlai, Attila <adorosz...@hortonworks.com>
Committed: Fri Dec 8 20:24:25 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/4e45eb09/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 cc0cea3..82f0ddf 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,10 +56,14 @@ 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.Authentication;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.gson.Gson;
 
 
@@ -131,46 +135,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 ----------------------------------------------------
 
@@ -180,7 +178,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));
@@ -192,7 +192,7 @@ public class ClusterResourceProvider extends 
AbstractControllerResourceProvider
 
   @Override
   protected Set<String> getPKPropertyIds() {
-    return pkPropertyIds;
+    return PK_PROPERTY_IDS;
   }
 
   /**
@@ -210,8 +210,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");
   }
 
@@ -230,10 +228,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()) {
@@ -530,14 +525,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/4e45eb09/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/4e45eb09/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/4e45eb09/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 432908b..a12f61b 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
@@ -59,7 +59,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;
@@ -251,9 +250,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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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 1374a42..8b370ec 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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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/4e45eb09/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();

Reply via email to