You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2015/04/27 07:53:05 UTC

[11/13] ambari git commit: AMBARI-10750. Initial merge of advanced api provisioning work.

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
index 03acd40..aab5395 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
@@ -30,7 +30,6 @@ import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.DuplicateResourceException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -43,16 +42,16 @@ import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.BlueprintDAO;
-import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
 import org.apache.ambari.server.orm.entities.BlueprintConfiguration;
 import org.apache.ambari.server.orm.entities.BlueprintEntity;
 import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
-import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
 import org.apache.ambari.server.orm.entities.HostGroupEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.stack.NoSuchStackException;
+import org.apache.ambari.server.topology.Blueprint;
+import org.apache.ambari.server.topology.BlueprintFactory;
+import org.apache.ambari.server.topology.InvalidTopologyException;
 
 import com.google.gson.Gson;
 
@@ -60,32 +59,32 @@ import com.google.gson.Gson;
 /**
  * Resource Provider for Blueprint resources.
  */
-public class BlueprintResourceProvider extends BaseBlueprintProcessor {
+public class BlueprintResourceProvider extends AbstractControllerResourceProvider {
 
   // ----- Property ID constants ---------------------------------------------
 
   // Blueprints
-  protected static final String BLUEPRINT_NAME_PROPERTY_ID =
+  public static final String BLUEPRINT_NAME_PROPERTY_ID =
       PropertyHelper.getPropertyId("Blueprints", "blueprint_name");
-  protected static final String STACK_NAME_PROPERTY_ID =
+  public static final String STACK_NAME_PROPERTY_ID =
       PropertyHelper.getPropertyId("Blueprints", "stack_name");
-  protected static final String STACK_VERSION_PROPERTY_ID =
+  public static final String STACK_VERSION_PROPERTY_ID =
       PropertyHelper.getPropertyId("Blueprints", "stack_version");
 
   // Host Groups
-  protected static final String HOST_GROUP_PROPERTY_ID = "host_groups";
-  protected static final String HOST_GROUP_NAME_PROPERTY_ID = "name";
-  protected static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality";
+  public static final String HOST_GROUP_PROPERTY_ID = "host_groups";
+  public static final String HOST_GROUP_NAME_PROPERTY_ID = "name";
+  public static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality";
 
   // Host Group Components
-  protected static final String COMPONENT_PROPERTY_ID ="components";
-  protected static final String COMPONENT_NAME_PROPERTY_ID ="name";
+  public static final String COMPONENT_PROPERTY_ID ="components";
+  public static final String COMPONENT_NAME_PROPERTY_ID ="name";
 
   // Configurations
-  protected static final String CONFIGURATION_PROPERTY_ID = "configurations";
-  protected static final String PROPERTIES_PROPERTY_ID = "properties";
-  protected static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes";
-  protected static final String SCHEMA_IS_NOT_SUPPORTED_MESSAGE =
+  public static final String CONFIGURATION_PROPERTY_ID = "configurations";
+  public static final String PROPERTIES_PROPERTY_ID = "properties";
+  public static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes";
+  public static final String SCHEMA_IS_NOT_SUPPORTED_MESSAGE =
       "Configuration format provided in Blueprint is not supported";
 
   // Primary Key Fields
@@ -94,6 +93,16 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
           BLUEPRINT_NAME_PROPERTY_ID}));
 
   /**
+   * Used to create Blueprint instances
+   */
+  private static BlueprintFactory blueprintFactory;
+
+  /**
+   * Blueprint Data Access Object
+   */
+  private static BlueprintDAO blueprintDAO;
+
+  /**
    * Used to serialize to/from json.
    */
   private static Gson jsonSerializer;
@@ -118,19 +127,14 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   /**
    * Static initialization.
    *
-   * @param dao
-   *          blueprint data access object
-   * @param gson
-   *          json serializer
-   * @param metaInfo
-   *          stack related information
+   * @param factory   blueprint factory
+   * @param dao       blueprint data access object
+   * @param gson      json serializer
    */
-  public static void init(BlueprintDAO dao, StackDAO stacks, Gson gson,
-      AmbariMetaInfo metaInfo) {
+  public static void init(BlueprintFactory factory, BlueprintDAO dao, Gson gson) {
+    blueprintFactory = factory;
     blueprintDAO = dao;
-    stackDAO = stacks;
     jsonSerializer = gson;
-    stackInfo = metaInfo;
   }
 
   // ----- ResourceProvider ------------------------------------------------
@@ -154,6 +158,7 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   }
 
   @Override
+  //todo: continue to use dao/entity directly or use blueprint factory?
   public Set<Resource> getResources(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException,
              NoSuchResourceException, NoSuchParentResourceException {
@@ -278,172 +283,6 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
   }
 
   /**
-   * Convert a map of properties to a blueprint entity.
-   *
-   * @param properties  property map
-   * @return new blueprint entity
-   */
-  @SuppressWarnings("unchecked")
-  protected BlueprintEntity toBlueprintEntity(Map<String, Object> properties) {
-    String name = (String) properties.get(BLUEPRINT_NAME_PROPERTY_ID);
-    if (name == null || name.isEmpty()) {
-      throw new IllegalArgumentException("Blueprint name must be provided");
-    }
-
-    String stackName = (String) properties.get(STACK_NAME_PROPERTY_ID);
-    String stackVersion = (String) properties.get(STACK_VERSION_PROPERTY_ID);
-    StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
-
-    BlueprintEntity blueprint = new BlueprintEntity();
-    blueprint.setBlueprintName(name);
-    blueprint.setStack(stackEntity);
-
-    createHostGroupEntities(blueprint,
-        (HashSet<HashMap<String, Object>>) properties.get(HOST_GROUP_PROPERTY_ID));
-
-    createBlueprintConfigEntities((Collection<Map<String, String>>)
-        properties.get(CONFIGURATION_PROPERTY_ID), blueprint);
-
-    return blueprint;
-  }
-
-  /**
-   * Create host group entities and add to the parent blueprint entity.
-   *
-   * @param blueprint      parent blueprint entity
-   * @param setHostGroups  set of host group property maps
-   */
-  @SuppressWarnings("unchecked")
-  private void createHostGroupEntities(BlueprintEntity blueprint,
-                                       HashSet<HashMap<String, Object>> setHostGroups) {
-
-    if (setHostGroups == null || setHostGroups.isEmpty()) {
-      throw new IllegalArgumentException("At least one host group must be specified in a blueprint");
-    }
-
-    Collection<HostGroupEntity> entities = new ArrayList<HostGroupEntity>();
-
-    StackEntity stackEntity = blueprint.getStack();
-
-    Collection<String> stackComponentNames = getAllStackComponents(
-        stackEntity.getStackName(), stackEntity.getStackVersion());
-
-    for (HashMap<String, Object> hostGroupProperties : setHostGroups) {
-      HostGroupEntity hostGroup = new HostGroupEntity();
-      entities.add(hostGroup);
-
-      String hostGroupName = (String) hostGroupProperties.get(HOST_GROUP_NAME_PROPERTY_ID);
-      if (hostGroupName == null || hostGroupName.isEmpty()) {
-        throw new IllegalArgumentException("Every host group must include a non-null 'name' property");
-      }
-
-      hostGroup.setName(hostGroupName);
-      hostGroup.setBlueprintEntity(blueprint);
-      hostGroup.setBlueprintName(blueprint.getBlueprintName());
-      hostGroup.setCardinality((String) hostGroupProperties.get(HOST_GROUP_CARDINALITY_PROPERTY_ID));
-
-      createHostGroupConfigEntities((Collection<Map<String,
-          String>>) hostGroupProperties.get(CONFIGURATION_PROPERTY_ID), hostGroup);
-
-      createComponentEntities(hostGroup, (HashSet<HashMap<String, String>>)
-          hostGroupProperties.get(COMPONENT_PROPERTY_ID), stackComponentNames);
-    }
-    blueprint.setHostGroups(entities);
-  }
-
-  /**
-   * Create component entities and add to parent host group.
-   *
-   * @param group           parent host group
-   * @param setComponents   set of component property maps
-   * @param componentNames  set of all component names for the associated stack
-   */
-  @SuppressWarnings("unchecked")
-  private void createComponentEntities(HostGroupEntity group, HashSet<HashMap<String, String>> setComponents,
-                                       Collection<String> componentNames) {
-
-    Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
-    String groupName = group.getName();
-    group.setComponents(components);
-
-    if (setComponents == null || setComponents.isEmpty()) {
-      throw new IllegalArgumentException("Host group '" + groupName + "' must contain at least one component");
-    }
-
-    for (HashMap<String, String> componentProperties : setComponents) {
-      HostGroupComponentEntity component = new HostGroupComponentEntity();
-      components.add(component);
-
-      String componentName = componentProperties.get(COMPONENT_NAME_PROPERTY_ID);
-      if (componentName == null || componentName.isEmpty()) {
-        throw new IllegalArgumentException("Host group '" + groupName +
-            "' contains a component with no 'name' property");
-      }
-
-      if (! componentNames.contains(componentName)) {
-        throw new IllegalArgumentException("The component '" + componentName + "' in host group '" +
-            groupName + "' is not valid for the specified stack");
-      }
-
-      component.setName(componentName);
-      component.setBlueprintName(group.getBlueprintName());
-      component.setHostGroupEntity(group);
-      component.setHostGroupName(group.getName());
-    }
-    group.setComponents(components);
-  }
-
-  /**
-   * Obtain all component names for the specified stack.
-   *
-   * @param stackName     stack name
-   * @param stackVersion  stack version
-   *
-   * @return collection of component names for the specified stack
-   * @throws IllegalArgumentException if the specified stack doesn't exist
-   */
-  private Collection<String> getAllStackComponents(String stackName, String stackVersion) {
-    Collection<String> componentNames = new HashSet<String>();
-    componentNames.add("AMBARI_SERVER");
-    Collection<ComponentInfo> components;
-    try {
-      components = getComponents(stackName, stackVersion);
-    } catch (AmbariException e) {
-      throw new IllegalArgumentException("The specified stack doesn't exist.  Name='" +
-          stackName + "', Version='" + stackVersion + "'");
-    }
-    if (components != null) {
-      for (ComponentInfo component : components) {
-        componentNames.add(component.getName());
-      }
-    }
-    return componentNames;
-  }
-
-  /**
-   * Get all the components for the specified stack.
-   *
-   * @param stackName  stack name
-   * @param version    stack version
-   *
-   * @return all components for the specified stack
-   * @throws AmbariException if the stack doesn't exist
-   */
-  private Collection<ComponentInfo> getComponents(String stackName, String version) throws AmbariException {
-    Collection<ComponentInfo> components = new HashSet<ComponentInfo>();
-    Map<String, ServiceInfo> services = stackInfo.getServices(stackName, version);
-
-    for (ServiceInfo service : services.values()) {
-      List<ComponentInfo> serviceComponents = stackInfo.getComponentsByService(
-          stackName, version, service.getName());
-      for (ComponentInfo component : serviceComponents) {
-        components.add(component);
-      }
-    }
-    return components;
-  }
-
-  /**
    * Populate a list of configuration property maps from a collection of configuration entities.
    *
    * @param configurations  collection of configuration entities
@@ -495,28 +334,6 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
     blueprint.setConfigurations(configurations);
   }
 
-  /**
-   * Populate host group configurations.
-   *
-   * @param propertyMaps  collection of configuration property maps
-   * @param hostGroup     host group entity to set configurations on
-   */
-  private void createHostGroupConfigEntities(Collection<Map<String, String>> propertyMaps,
-                                             HostGroupEntity hostGroup) {
-
-    Collection<HostGroupConfigEntity> configurations = new ArrayList<HostGroupConfigEntity>();
-    if (propertyMaps != null) {
-      for (Map<String, String> configuration : propertyMaps) {
-        HostGroupConfigEntity configEntity = new HostGroupConfigEntity();
-        configEntity.setHostGroupEntity(hostGroup);
-        configEntity.setHostGroupName(hostGroup.getName());
-        configEntity.setBlueprintName(hostGroup.getBlueprintName());
-        populateConfigurationEntity(configuration, configEntity);
-        configurations.add(configEntity);
-      }
-    }
-    hostGroup.setConfigurations(configurations);
-  }
 
   /**
    * Populate a configuration entity from properties.
@@ -560,31 +377,39 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
     return new Command<Void>() {
       @Override
       public Void invoke() throws AmbariException {
-        BlueprintEntity blueprint = toBlueprintEntity(properties);
+        Blueprint blueprint;
+        try {
+          blueprint = blueprintFactory.createBlueprint(properties);
+        } catch (NoSuchStackException e) {
+          throw new IllegalArgumentException("Specified stack doesn't exist: " + e, e);
+        }
 
-        if (blueprintDAO.findByName(blueprint.getBlueprintName()) != null) {
+        if (blueprintDAO.findByName(blueprint.getName()) != null) {
           throw new DuplicateResourceException(
               "Attempted to create a Blueprint which already exists, blueprint_name=" +
-              blueprint.getBlueprintName());
+              blueprint.getName());
         }
-        Map<String, Map<String, Collection<String>>> missingProperties = blueprint.validateConfigurations(
-            stackInfo, false);
 
-        if (! missingProperties.isEmpty()) {
-          throw new IllegalArgumentException("Required configurations are missing from the specified host groups: " +
-                                             missingProperties);
+        try {
+          blueprint.validateRequiredProperties();
+        } catch (InvalidTopologyException e) {
+          throw new IllegalArgumentException("Blueprint configuration validation failed: " + e.getMessage(), e);
         }
 
         String validateTopology =  requestInfoProps.get("validate_topology");
         if (validateTopology == null || ! validateTopology.equalsIgnoreCase("false")) {
-          validateTopology(blueprint);
+          try {
+            blueprint.validateTopology();
+          } catch (InvalidTopologyException e) {
+            throw new IllegalArgumentException(e.getMessage());
+          }
         }
 
         if (LOG.isDebugEnabled()) {
-          LOG.debug("Creating Blueprint, name=" + blueprint.getBlueprintName());
+          LOG.debug("Creating Blueprint, name=" + blueprint.getName());
         }
         try {
-          blueprintDAO.create(blueprint);
+          blueprintDAO.create(blueprint.toEntity());
         } catch (Exception e) {
           throw new RuntimeException(e);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
deleted file mode 100644
index 74e594f..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.controller.internal;
-
-/**
- * Component cardinality representation.
- */
-class Cardinality {
-  String cardinality;
-  int min = 0;
-  int max = Integer.MAX_VALUE;
-  int exact = -1;
-  boolean isAll = false;
-
-  public Cardinality(String cardinality) {
-    this.cardinality = cardinality;
-    if (cardinality != null && ! cardinality.isEmpty()) {
-      if (cardinality.contains("+")) {
-        min = Integer.valueOf(cardinality.split("\\+")[0]);
-      } else if (cardinality.contains("-")) {
-        String[] toks = cardinality.split("-");
-        min = Integer.parseInt(toks[0]);
-        max = Integer.parseInt(toks[1]);
-      } else if (cardinality.equals("ALL")) {
-        isAll = true;
-      } else {
-        exact = Integer.parseInt(cardinality);
-      }
-    }
-  }
-
-  /**
-   * Determine if component is required for all host groups.
-   *
-   * @return true if cardinality is 'ALL', false otherwise
-   */
-  public boolean isAll() {
-    return isAll;
-  }
-
-  /**
-   * Determine if the given count satisfies the required cardinality.
-   *
-   * @param count  number of host groups containing component
-   *
-   * @return true id count satisfies the required cardinality, false otherwise
-   */
-  public boolean isValidCount(int count) {
-    if (isAll) {
-      return false;
-    } else if (exact != -1) {
-      return count == exact;
-    } else return count >= min && count <= max;
-  }
-
-  /**
-   * Determine if the cardinality count supports auto-deployment.
-   * This determination is independent of whether the component is configured
-   * to be auto-deployed.  This only indicates whether auto-deployment is
-   * supported for the current cardinality.
-   *
-   * At this time, only cardinalities of ALL or where a count of 1 is valid are
-   * supported.
-   *
-   * @return true if cardinality supports auto-deployment
-   */
-  public boolean supportsAutoDeploy() {
-    return isValidCount(1) || isAll;
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index 2c43e1a..2db2d28 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -270,7 +270,7 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
       Map<String, Set<String>> clusterHostInfo = null;
       ServiceInfo serviceInfo = null;
       String osFamily = null;
-      clusterHostInfo = StageUtils.getClusterHostInfo(managementController.getClusters().getHostsForCluster(cluster.getClusterName()), cluster);
+      clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
       serviceInfo = managementController.getAmbariMetaInfo().getService(stackId.getStackName(),
               stackId.getStackVersion(), serviceName);
       clusterHostInfo = substituteHostIndexes(clusterHostInfo);

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/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 0b5bb8e..812aa5d 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
@@ -18,15 +18,22 @@
 package org.apache.ambari.server.controller.internal;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.ClusterRequest;
 import org.apache.ambari.server.controller.ClusterResponse;
-import org.apache.ambari.server.controller.ConfigGroupRequest;
 import org.apache.ambari.server.controller.ConfigurationRequest;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ServiceConfigVersionRequest;
 import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
@@ -34,50 +41,32 @@ import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
-import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.orm.dao.BlueprintDAO;
-import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
-import org.apache.ambari.server.orm.entities.BlueprintEntity;
-import org.apache.ambari.server.orm.entities.HostGroupEntity;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.ConfigImpl;
 import org.apache.ambari.server.state.SecurityType;
-import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.topology.*;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * Resource provider for cluster resources.
  */
-public class ClusterResourceProvider extends BaseBlueprintProcessor {
+public class ClusterResourceProvider extends AbstractControllerResourceProvider {
 
   // ----- Property ID constants ---------------------------------------------
 
   // Clusters
   public static final String CLUSTER_ID_PROPERTY_ID      = PropertyHelper.getPropertyId("Clusters", "cluster_id");
   public static final String CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Clusters", "cluster_name");
-  protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
-  protected static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
-  protected static final String CLUSTER_SECURITY_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "security_type");
-  protected static final String CLUSTER_DESIRED_CONFIGS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_configs");
-  protected static final String CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_service_config_versions");
-  protected static final String CLUSTER_TOTAL_HOSTS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "total_hosts");
-  protected static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
-  protected static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
-  protected static final String SESSION_ATTRIBUTES_PROPERTY_ID = "session_attributes";
+  public static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
+  public static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
+  public static final String CLUSTER_SECURITY_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "security_type");
+  public static final String CLUSTER_DESIRED_CONFIGS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_configs");
+  public static final String CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_service_config_versions");
+  public static final String CLUSTER_TOTAL_HOSTS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "total_hosts");
+  public static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
+  public static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
+  public static final String SESSION_ATTRIBUTES_PROPERTY_ID = "session_attributes";
 
   /**
    * The session attributes property prefix.
@@ -90,6 +79,16 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
   public static final String GET_IGNORE_PERMISSIONS_PROPERTY_ID = "get_resource/ignore_permissions";
 
   /**
+   * topology manager instance
+   */
+  private static TopologyManager topologyManager;
+
+  /**
+   * factory for creating topology requests which are used to provision a cluster via a blueprint
+   */
+  private static TopologyRequestFactory topologyRequestFactory;
+
+  /**
    * The cluster primary key properties.
    */
   private static Set<String> pkPropertyIds =
@@ -107,6 +106,8 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
    * The property ids for a cluster resource.
    */
   private static Set<String> propertyIds = new HashSet<String>();
+
+
   static {
     propertyIds.add(CLUSTER_ID_PROPERTY_ID);
     propertyIds.add(CLUSTER_NAME_PROPERTY_ID);
@@ -121,16 +122,6 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
     propertyIds.add(SESSION_ATTRIBUTES_PROPERTY_ID);
   }
 
-  /**
-   * Maps configuration type (string) to associated properties
-   */
-  private Map<String, Map<String, String>> mapClusterConfigurations =
-      new HashMap<String, Map<String, String>>();
-  /**
-   * Maps configuration type (string) to property attributes, and their values
-   */
-  private Map<String, Map<String, Map<String, String>>> mapClusterAttributes =
-      new HashMap<String, Map<String, Map<String, String>>>();
 
   // ----- Constructors ----------------------------------------------------
 
@@ -336,21 +327,13 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
   /**
    * Inject the blueprint data access object which is used to obtain blueprint entities.
    *
-   * @param dao  blueprint data access object
+   * @param manager         topology manager
+   * @param requestFactory  request factory
    */
-  public static void init(BlueprintDAO dao, AmbariMetaInfo metaInfo, ConfigHelper ch) {
-    blueprintDAO = dao;
-    stackInfo    = metaInfo;
-    configHelper = ch;
-  }
-
-
-  /**
-   * Package-level access for cluster config
-   * @return cluster config map
-   */
-  Map<String, Map<String, String>> getClusterConfigurations() {
-    return mapClusterConfigurations;
+  //todo: proper static injection mechanism
+  public static void init(TopologyManager manager, TopologyRequestFactory requestFactory) {
+    topologyManager = manager;
+    topologyRequestFactory = requestFactory;
   }
 
 
@@ -477,439 +460,24 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
       throws ResourceAlreadyExistsException, SystemException, UnsupportedPropertyException,
       NoSuchParentResourceException {
 
-    String blueprintName = (String) properties.get(BLUEPRINT_PROPERTY_ID);
-
     LOG.info("Creating Cluster '" + properties.get(CLUSTER_NAME_PROPERTY_ID) +
-        "' based on blueprint '" + blueprintName + "'.");
-
-    //todo: build up a proper topology object
-    BlueprintEntity blueprint = getExistingBlueprint(blueprintName);
-    Stack stack = parseStack(blueprint);
-
-    Map<String, HostGroupImpl> blueprintHostGroups = parseBlueprintHostGroups(blueprint, stack);
-    applyRequestInfoToHostGroups(properties, blueprintHostGroups);
-    Collection<Map<String, String>> configOverrides = (Collection<Map<String, String>>)properties.get("configurations");
-
-    String message = null;
-    for (BlueprintConfigEntity blueprintConfig: blueprint.getConfigurations()){
-      if(blueprintConfig.getType().equals("global")){
-        message = "WARNING: Global configurations are deprecated, please use *-env";
-        break;
-      }
-    }
-
-    processConfigurations(processBlueprintConfigurations(blueprint, configOverrides),
-        processBlueprintAttributes(blueprint), stack, blueprintHostGroups);
-    validatePasswordProperties(blueprint, blueprintHostGroups, (String) properties.get("default_password"));
-
-    String clusterName = (String) properties.get(CLUSTER_NAME_PROPERTY_ID);
-    createClusterResource(buildClusterResourceProperties(stack, clusterName));
-    setConfigurationsOnCluster(clusterName, stack, blueprintHostGroups);
-
-    Set<String> services = getServicesToDeploy(stack, blueprintHostGroups);
-
-    createServiceAndComponentResources(blueprintHostGroups, clusterName, services);
-    createHostAndComponentResources(blueprintHostGroups, clusterName);
-
-    registerConfigGroups(clusterName, blueprintHostGroups, stack);
-
-    persistInstallStateForUI(clusterName);
-
-    RequestStatusResponse request = ((ServiceResourceProvider) getResourceProvider(Resource.Type.Service)).
-        installAndStart(clusterName);
-
-    request.setMessage(message);
-
-    return request;
-  }
-
-  /**
-   * Validate that all required password properties have been set or that 'default_password' is specified.
-   *
-   * @param blueprint        associated blueprint entity
-   * @param hostGroups       host groups in blueprint
-   * @param defaultPassword  specified default password, may be null
-   *
-   * @throws IllegalArgumentException if required password properties are missing and no
-   *                                  default is specified via 'default_password'
-   */
-  private void validatePasswordProperties(BlueprintEntity blueprint, Map<String, HostGroupImpl> hostGroups,
-                                          String defaultPassword) {
-
-    Map<String, Map<String, Collection<String>>> missingPasswords = blueprint.validateConfigurations(
-        stackInfo, true);
-
-    Iterator<Map.Entry<String, Map<String, Collection<String>>>> iter;
-    for(iter = missingPasswords.entrySet().iterator(); iter.hasNext(); ) {
-      Map.Entry<String, Map<String, Collection<String>>> entry = iter.next();
-      Map<String, Collection<String>> missingProps = entry.getValue();
-      Iterator<Map.Entry<String, Collection<String>>> hostGroupIter;
-
-      for (hostGroupIter = missingProps.entrySet().iterator(); hostGroupIter.hasNext(); ) {
-        Map.Entry<String, Collection<String>> hgEntry = hostGroupIter.next();
-        String configType = hgEntry.getKey();
-        Collection<String> propertySet = hgEntry.getValue();
-
-        for (Iterator<String> propIter = propertySet.iterator(); propIter.hasNext(); ) {
-          String property = propIter.next();
-          if (isPropertyInConfiguration(mapClusterConfigurations.get(configType), property)){
-              propIter.remove();
-          } else {
-            HostGroupImpl hg = hostGroups.get(entry.getKey());
-            if (hg != null && isPropertyInConfiguration(hg.getConfigurationProperties().get(configType), property)) {
-              propIter.remove();
-            }  else if (setDefaultPassword(defaultPassword, configType, property)) {
-              propIter.remove();
-            }
-          }
-        }
-        if (propertySet.isEmpty()) {
-          hostGroupIter.remove();
-        }
-      }
-      if (entry.getValue().isEmpty()) {
-        iter.remove();
-      }
-    }
-
-    if (! missingPasswords.isEmpty()) {
-      throw new IllegalArgumentException("Missing required password properties.  Specify a value for these " +
-          "properties in the cluster or host group configurations or include 'default_password' field in request. " +
-          missingPasswords);
-    }
-  }
-
-  /**
-   * Attempt to set the default password in cluster configuration for missing password property.
-   *
-   * @param defaultPassword  default password specified in request, may be null
-   * @param configType       configuration type
-   * @param property         password property name
-   *
-   * @return true if password was set, otherwise false.  Currently the password will always be set
-   *         unless it is null
-   */
-  private boolean setDefaultPassword(String defaultPassword, String configType, String property) {
-    boolean setDefaultPassword = false;
-    Map<String, String> typeProps = mapClusterConfigurations.get(configType);
-    if (defaultPassword != null && ! defaultPassword.trim().isEmpty()) {
-      // set default password in cluster config
-      if (typeProps == null) {
-        typeProps = new HashMap<String, String>();
-        mapClusterConfigurations.put(configType, typeProps);
-      }
-      typeProps.put(property, defaultPassword);
-      setDefaultPassword = true;
-    }
-    return setDefaultPassword;
-  }
-
-  /**
-   * Determine if a specific property is in a configuration.
-   *
-   * @param props     property map to check
-   * @param property  property to check for
-   *
-   * @return true if the property is contained in the configuration, otherwise false
-   */
-  private boolean isPropertyInConfiguration(Map<String, String> props, String property) {
-    boolean foundProperty = false;
-    if (props != null) {
-      String val = props.get(property);
-      foundProperty = (val != null && ! val.trim().isEmpty());
-    }
-    return foundProperty;
-  }
-
-  /**
-   * Create service and component resources.
-   *
-   * @param blueprintHostGroups  host groups contained in blueprint
-   * @param clusterName          cluster name
-   * @param services             services to be deployed
-   *
-   * @throws SystemException                an unexpected exception occurred
-   * @throws UnsupportedPropertyException   an unsupported property was specified in the request
-   * @throws ResourceAlreadyExistsException attempted to create a service or component that already exists
-   * @throws NoSuchParentResourceException  a required parent resource is missing
-   */
-  private void createServiceAndComponentResources(Map<String, HostGroupImpl> blueprintHostGroups,
-                                                  String clusterName, Set<String> services)
-                                                  throws SystemException,
-                                                         UnsupportedPropertyException,
-                                                         ResourceAlreadyExistsException,
-                                                         NoSuchParentResourceException {
-
-    Set<Map<String, Object>> setServiceRequestProps = new HashSet<Map<String, Object>>();
-    for (String service : services) {
-      Map<String, Object> serviceProperties = new HashMap<String, Object>();
-      serviceProperties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, clusterName);
-      serviceProperties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, service);
-      setServiceRequestProps.add(serviceProperties);
-    }
-
-    Request serviceRequest = new RequestImpl(null, setServiceRequestProps, null, null);
-    getResourceProvider(Resource.Type.Service).createResources(serviceRequest);
-    createComponentResources(blueprintHostGroups, clusterName, services);
-  }
-
-  /**
-   * Build the cluster properties necessary for creating a cluster resource.
-   *
-   * @param stack        associated stack
-   * @param clusterName  cluster name
-   * @return map of cluster properties used to create a cluster resource
-   */
-  private Map<String, Object> buildClusterResourceProperties(Stack stack, String clusterName) {
-    Map<String, Object> clusterProperties = new HashMap<String, Object>();
-    clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
-    clusterProperties.put(CLUSTER_VERSION_PROPERTY_ID, stack.getName() + "-" + stack.getVersion());
-    return clusterProperties;
-  }
-
-  /**
-   * Create component resources.
-   *
-   * @param blueprintHostGroups  host groups specified in blueprint
-   * @param clusterName          cluster name
-   * @param services             services to be deployed
-   *
-   * @throws SystemException                an unexpected exception occurred
-   * @throws UnsupportedPropertyException   an invalid property was specified
-   * @throws ResourceAlreadyExistsException attempt to create a component which already exists
-   * @throws NoSuchParentResourceException  a required parent resource is missing
-   */
-  private void createComponentResources(Map<String, HostGroupImpl> blueprintHostGroups,
-                                        String clusterName, Set<String> services)
-                                        throws SystemException,
-                                               UnsupportedPropertyException,
-                                               ResourceAlreadyExistsException,
-                                               NoSuchParentResourceException {
-    for (String service : services) {
-      Set<String> components = new HashSet<String>();
-      for (HostGroupImpl hostGroup : blueprintHostGroups.values()) {
-        Collection<String> serviceComponents = hostGroup.getComponents(service);
-        if (serviceComponents != null && !serviceComponents.isEmpty()) {
-          components.addAll(serviceComponents);
-        }
-      }
-
-      Set<Map<String, Object>> setComponentRequestProps = new HashSet<Map<String, Object>>();
-      for (String component : components) {
-        Map<String, Object> componentProperties = new HashMap<String, Object>();
-        componentProperties.put("ServiceComponentInfo/cluster_name", clusterName);
-        componentProperties.put("ServiceComponentInfo/service_name", service);
-        componentProperties.put("ServiceComponentInfo/component_name", component);
-        setComponentRequestProps.add(componentProperties);
-      }
-      Request componentRequest = new RequestImpl(null, setComponentRequestProps, null, null);
-      ResourceProvider componentProvider = getResourceProvider(Resource.Type.Component);
-      componentProvider.createResources(componentRequest);
-    }
-  }
-
-  /**
-   * Set all configurations on the cluster resource.
-   *
-   * @param clusterName  cluster name
-   * @param stack Stack definition object used for this cluster
-   * @param blueprintHostGroups host groups defined in the Blueprint for this cluster
-   *
-   * @throws SystemException an unexpected exception occurred
-   */
-  void setConfigurationsOnCluster(String clusterName, Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) throws SystemException {
-    List<BlueprintServiceConfigRequest> listofConfigRequests =
-      new LinkedList<BlueprintServiceConfigRequest>();
-
-    // create a list of config requests on a per-service basis, in order
-    // to properly support the new service configuration versioning mechanism
-    // in Ambari
-    for (String service : getServicesToDeploy(stack, blueprintHostGroups)) {
-      BlueprintServiceConfigRequest blueprintConfigRequest =
-        new BlueprintServiceConfigRequest(service);
-
-      for (String serviceConfigType : stack.getConfigurationTypes(service)) {
-        Set<String> excludedConfigTypes = stack.getExcludedConfigurationTypes(service);
-        if (excludedConfigTypes == null) {
-          // if the service does not have excluded config types
-          // associated, then treat this as an empty set
-          excludedConfigTypes = Collections.emptySet();
-        }
-
-        // only include config types that are not excluded, re-introducing fix from AMBARI-8009
-        if (!excludedConfigTypes.contains(serviceConfigType)) {
-          // skip handling of cluster-env here
-          if (!serviceConfigType.equals("cluster-env")) {
-            if (mapClusterConfigurations.containsKey(serviceConfigType)) {
-              blueprintConfigRequest.addConfigElement(serviceConfigType,
-                mapClusterConfigurations.get(serviceConfigType),
-                mapClusterAttributes.get(serviceConfigType));
-            }
-          }
-        }
-      }
-
-      listofConfigRequests.add(blueprintConfigRequest);
-    }
-
-    // since the stack returns "cluster-env" with each service's config
-    // this code needs to ensure that only one ClusterRequest occurs for
-    // the global cluster-env configuration
-    BlueprintServiceConfigRequest globalConfigRequest =
-      new BlueprintServiceConfigRequest("GLOBAL-CONFIG");
-    globalConfigRequest.addConfigElement("cluster-env",
-      mapClusterConfigurations.get("cluster-env"),
-      mapClusterAttributes.get("cluster-env"));
-    listofConfigRequests.add(globalConfigRequest);
+        "' based on blueprint '" + String.valueOf(properties.get(BLUEPRINT_PROPERTY_ID)) + "'.");
 
+    TopologyRequest createClusterRequest;
     try {
-      //todo: properly handle non system exceptions
-      setConfigurationsOnCluster(clusterName, listofConfigRequests);
-    } catch (AmbariException e) {
-      throw new SystemException("Unable to set configurations on cluster.", e);
-    }
-
-  }
-
-
-  /**
-   * Creates a ClusterRequest for each service that
-   *   includes any associated config types and configuration. The Blueprints
-   *   implementation will now create one ClusterRequest per service, in order
-   *   to comply with the ServiceConfigVersioning framework in Ambari.
-   *
-   * This method will also send these requests to the management controller.
-   *
-   * @param clusterName name of cluster
-   * @param listOfBlueprintConfigRequests a list of requests to send to the AmbariManagementController.
-   *
-   * @throws AmbariException upon any error that occurs during updateClusters
-   */
-  private void setConfigurationsOnCluster(String clusterName, List<BlueprintServiceConfigRequest> listOfBlueprintConfigRequests) throws AmbariException {
-    // iterate over services to deploy
-    for (BlueprintServiceConfigRequest blueprintConfigRequest : listOfBlueprintConfigRequests) {
-      ClusterRequest clusterRequest = null;
-      // iterate over the config types associated with this service
-      List<ConfigurationRequest> requestsPerService = new LinkedList<ConfigurationRequest>();
-      for (BlueprintServiceConfigElement blueprintElement : blueprintConfigRequest.getConfigElements()) {
-        Map<String, Object> clusterProperties = new HashMap<String, Object>();
-        clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
-        clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/type", blueprintElement.getTypeName());
-        clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/tag", "1");
-        for (Map.Entry<String, String> entry : blueprintElement.getConfiguration().entrySet()) {
-          clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID +
-            "/properties/" + entry.getKey(), entry.getValue());
-        }
-        if (blueprintElement.getAttributes() != null) {
-          for (Map.Entry<String, Map<String, String>> attribute : blueprintElement.getAttributes().entrySet()) {
-            String attributeName = attribute.getKey();
-            for (Map.Entry<String, String> attributeOccurrence : attribute.getValue().entrySet()) {
-              clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/properties_attributes/"
-                + attributeName + "/" + attributeOccurrence.getKey(), attributeOccurrence.getValue());
-            }
-          }
-        }
-
-        // only create one cluster request per service, which includes
-        // all the configuration types for that service
-        if (clusterRequest == null) {
-          SecurityType securityType;
-          String requestedSecurityType = (String) clusterProperties.get(CLUSTER_SECURITY_TYPE_PROPERTY_ID);
-          if(requestedSecurityType == null)
-            securityType = null;
-          else {
-            try {
-              securityType = SecurityType.valueOf(requestedSecurityType.toUpperCase());
-            } catch (IllegalArgumentException e) {
-              throw new IllegalArgumentException(String.format("Cannot set cluster security type to invalid value: %s", requestedSecurityType));
-            }
-          }
-
-          clusterRequest = new ClusterRequest(
-            (Long) clusterProperties.get(CLUSTER_ID_PROPERTY_ID),
-            (String) clusterProperties.get(CLUSTER_NAME_PROPERTY_ID),
-            (String) clusterProperties.get(CLUSTER_PROVISIONING_STATE_PROPERTY_ID),
-            securityType,
-            (String) clusterProperties.get(CLUSTER_VERSION_PROPERTY_ID),
-            null);
-        }
-
-        List<ConfigurationRequest> listOfRequests =
-          getConfigurationRequests("Clusters", clusterProperties);
-        requestsPerService.addAll(listOfRequests);
-      }
-
-      // set total list of config requests, including all config types
-      // for this service
-      if (clusterRequest != null) {
-        clusterRequest.setDesiredConfig(requestsPerService);
-
-        LOG.info("About to send cluster config update request for service = " + blueprintConfigRequest.getServiceName());
-
-        // send the request update for this service as a whole
-        getManagementController().updateClusters(
-          Collections.singleton(clusterRequest), null);
-      } else {
-        LOG.error("ClusterRequest should not be null for service = " + blueprintConfigRequest.getServiceName());
-      }
-
-    }
-  }
-
-  /**
-   * Apply the information contained in the cluster request body such as host an configuration properties to
-   * the associated blueprint.
-   *
-   * @param properties           request properties
-   * @param blueprintHostGroups  blueprint host groups
-   *
-   * @throws IllegalArgumentException a host_group in the request doesn't match a host-group in the blueprint
-   */
-  @SuppressWarnings("unchecked")
-  private void applyRequestInfoToHostGroups(Map<String, Object> properties,
-                                            Map<String, HostGroupImpl> blueprintHostGroups)
-                                            throws IllegalArgumentException {
-
-    @SuppressWarnings("unchecked")
-    Collection<Map<String, Object>> hostGroups =
-        (Collection<Map<String, Object>>) properties.get("host_groups");
-
-    if (hostGroups == null || hostGroups.isEmpty()) {
-      throw new IllegalArgumentException("'host_groups' element must be included in cluster create body");
+      createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties);
+    } catch (InvalidTopologyTemplateException e) {
+      throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e);
     }
 
-    // iterate over host groups provided in request body
-    for (Map<String, Object> hostGroupProperties : hostGroups) {
-      String name = (String) hostGroupProperties.get("name");
-      if (name == null || name.isEmpty()) {
-        throw new IllegalArgumentException("Every host_group must include a non-null 'name' property");
-      }
-      HostGroupImpl hostGroup = blueprintHostGroups.get(name);
-
-      if (hostGroup == null) {
-        throw new IllegalArgumentException("Invalid host_group specified: " + name +
-          ".  All request host groups must have a corresponding host group in the specified blueprint");
-      }
-
-      Collection hosts = (Collection) hostGroupProperties.get("hosts");
-      if (hosts == null || hosts.isEmpty()) {
-        throw new IllegalArgumentException("Host group '" + name + "' must contain a 'hosts' element");
-      }
-      for (Object oHost : hosts) {
-        Map<String, String> mapHostProperties = (Map<String, String>) oHost;
-        //add host information to host group
-        String fqdn = mapHostProperties.get("fqdn");
-        if (fqdn == null || fqdn.isEmpty()) {
-          throw new IllegalArgumentException("Host group '" + name + "' hosts element must include at least one fqdn");
-        }
-        hostGroup.addHostInfo(fqdn);
-      }
-      Map<String, Map<String, String>> existingConfigurations = hostGroup.getConfigurationProperties();
-      overrideExistingProperties(existingConfigurations, (Collection<Map<String, String>>)
-          hostGroupProperties.get("configurations"));
-
+    try {
+      return topologyManager.provisionCluster(createClusterRequest);
+    } catch (InvalidTopologyException e) {
+      throw new IllegalArgumentException("Topology validation failed: " + e, e);
+    }  catch (AmbariException e) {
+      e.printStackTrace();
+      throw new SystemException("Unknown exception when asking TopologyManager to provision cluster", e);
     }
-    validateHostMappings(blueprintHostGroups);
   }
 
   /**
@@ -934,317 +502,6 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
   }
 
   /**
-   * Persist cluster state for the ambari UI.  Setting this state informs that UI that a cluster has been
-   * installed and started and that the monitoring screen for the cluster should be displayed to the user.
-   *
-   * @param clusterName  name of cluster
-   *
-   * @throws SystemException if unable to update the cluster with the UI installed flag
-   */
-  private void persistInstallStateForUI(String clusterName) throws SystemException {
-    Map<String, Object> clusterProperties = new HashMap<String, Object>();
-    clusterProperties.put(CLUSTER_PROVISIONING_STATE_PROPERTY_ID, "INSTALLED");
-    clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
-
-    try {
-      getManagementController().updateClusters(
-          Collections.singleton(getRequest(clusterProperties)), null);
-    } catch (AmbariException e) {
-      throw new SystemException("Unable to finalize state of cluster for UI.");
-    }
-  }
-
-  /**
-   * Process cluster configurations.  This includes obtaining the default configuration properties
-   * from the stack,overlaying configuration properties specified in the blueprint and cluster
-   * create request and updating properties with topology specific information.
-   *
-   * @param stack                associated stack
-   * @param blueprintHostGroups  host groups contained in the blueprint
-   */
-  private void processConfigurations(Map<String, Map<String, String>> blueprintConfigurations,
-                                     Map<String, Map<String, Map<String, String>>> blueprintAttributes,
-                                     Stack stack, Map<String, HostGroupImpl> blueprintHostGroups)  {
-
-
-    for (String service : getServicesToDeploy(stack, blueprintHostGroups)) {
-      for (String type : stack.getConfigurationTypes(service)) {
-        Map<String, String> typeProps = mapClusterConfigurations.get(type);
-        if (typeProps == null) {
-          typeProps = new HashMap<String, String>();
-          mapClusterConfigurations.put(type, typeProps);
-        }
-        typeProps.putAll(stack.getConfigurationProperties(service, type));
-        Map<String, Map<String, String>> stackTypeAttributes = stack.getConfigurationAttributes(service, type);
-        if (!stackTypeAttributes.isEmpty()) {
-          if (!mapClusterAttributes.containsKey(type)) {
-            mapClusterAttributes.put(type, new HashMap<String, Map<String, String>>());
-          }
-          Map<String, Map<String, String>> typeAttrs = mapClusterAttributes.get(type);
-          for (Map.Entry<String, Map<String, String>> attribute : stackTypeAttributes.entrySet()) {
-            String attributeName = attribute.getKey();
-            Map<String, String> attributes = typeAttrs.get(attributeName);
-            if (attributes == null) {
-                attributes = new HashMap<String, String>();
-                typeAttrs.put(attributeName, attributes);
-            }
-            attributes.putAll(attribute.getValue());
-          }
-        }
-      }
-    }
-    processBlueprintClusterConfigurations(blueprintConfigurations);
-    processBlueprintClusterConfigAttributes(blueprintAttributes);
-
-    BlueprintConfigurationProcessor configurationProcessor = new BlueprintConfigurationProcessor(mapClusterConfigurations);
-    configurationProcessor.doUpdateForClusterCreate(blueprintHostGroups, stack);
-    setMissingConfigurations(blueprintHostGroups);
-  }
-
-  /**
-   * Since global configs are deprecated since 1.7.0, but still supported.
-   * We should automatically map any globals used, to *-env dictionaries.
-   *
-   * @param blueprintConfigurations  map of blueprint configurations keyed by type
-   */
-  private void handleGlobalsBackwardsCompability(Stack stack,
-      Map<String, Map<String, String>> blueprintConfigurations, String clusterName) {
-    StackId stackId = new StackId(stack.getName(), stack.getVersion());
-    configHelper.moveDeprecatedGlobals(stackId, blueprintConfigurations, clusterName);
-  }
-
-  /**
-   * Process cluster scoped configurations provided in blueprint.
-   *
-   * @param blueprintConfigurations  map of blueprint configurations keyed by type
-   */
-  private void processBlueprintClusterConfigurations(Map<String, Map<String, String>> blueprintConfigurations) {
-    for (Map.Entry<String, Map<String, String>> entry : blueprintConfigurations.entrySet()) {
-      Map<String, String> properties = entry.getValue();
-      if (properties != null && !properties.isEmpty()) {
-        String type = entry.getKey();
-        Map<String, String> typeProps = mapClusterConfigurations.get(type);
-        if (typeProps == null) {
-          typeProps = new HashMap<String, String>();
-          mapClusterConfigurations.put(type, typeProps);
-        }
-        // override default properties
-        typeProps.putAll(properties);
-      }
-    }
-  }
-
-  /**
-   * Process cluster scoped configuration attributes provided in blueprint.
-   *
-   * @param blueprintAttributes  map of configuration type to configuration attributes and their values
-   */
-  private void processBlueprintClusterConfigAttributes(Map<String, Map<String, Map<String, String>>> blueprintAttributes) {
-    for (Map.Entry<String, Map<String, Map<String, String>>> entry : blueprintAttributes.entrySet()) {
-      Map<String, Map<String, String>> attributes = entry.getValue();
-      if (attributes != null && !attributes.isEmpty()) {
-        String type = entry.getKey();
-        if (!mapClusterAttributes.containsKey(type)) {
-          mapClusterAttributes.put(type, new HashMap<String, Map<String, String>>());
-        }
-        Map<String, Map<String, String>> typeAttrs = mapClusterAttributes.get(type);
-        for (Map.Entry<String, Map<String, String>> attribute : attributes.entrySet()) {
-          String attributeName = attribute.getKey();
-          if (!typeAttrs.containsKey(attributeName)) {
-            typeAttrs.put(attributeName, new HashMap<String, String>());
-          }
-          typeAttrs.get(attributeName).putAll(attribute.getValue());
-        }
-      }
-    }
-  }
-
-  /**
-   * Explicitly set any properties that are required but not currently provided in the stack definition.
-   */
-  void setMissingConfigurations(Map<String, HostGroupImpl> blueprintHostGroups) {
-    // AMBARI-5206
-    final Map<String , String> userProps = new HashMap<String , String>();
-
-    // only add user properties to the map for
-    // services actually included in the blueprint definition
-    if (isServiceIncluded("OOZIE", blueprintHostGroups)) {
-      userProps.put("oozie_user", "oozie-env");
-    }
-
-    if (isServiceIncluded("HIVE", blueprintHostGroups)) {
-      userProps.put("hive_user", "hive-env");
-      userProps.put("hcat_user", "hive-env");
-    }
-
-    if (isServiceIncluded("HBASE", blueprintHostGroups)) {
-      userProps.put("hbase_user", "hbase-env");
-    }
-
-    if (isServiceIncluded("FALCON", blueprintHostGroups)) {
-      userProps.put("falcon_user", "falcon-env");
-    }
-
-
-    String proxyUserHosts  = "hadoop.proxyuser.%s.hosts";
-    String proxyUserGroups = "hadoop.proxyuser.%s.groups";
-
-    for (String property : userProps.keySet()) {
-      String configType = userProps.get(property);
-      Map<String, String> configs = mapClusterConfigurations.get(configType);
-      if (configs != null) {
-        String user = configs.get(property);
-        if (user != null && !user.isEmpty()) {
-          ensureProperty("core-site", String.format(proxyUserHosts, user), "*");
-          ensureProperty("core-site", String.format(proxyUserGroups, user), "users");
-        }
-      } else {
-        LOG.debug("setMissingConfigurations: no user configuration found for type = " + configType + ".  This may be caused by an error in the blueprint configuration.");
-      }
-
-    }
-  }
-
-
-  /**
-   * Determines if any components in the specified service are
-   *   included in the current blueprint's host group definitions.
-   *
-   * @param serviceName the Hadoop service name to query on
-   * @param blueprintHostGroups the map of Host Groups in the current blueprint
-   * @return true if the named service is included in the blueprint
-   *         false if the named service it not included in the blueprint
-   */
-  protected boolean isServiceIncluded(String serviceName, Map<String, HostGroupImpl> blueprintHostGroups) {
-    for (String hostGroupName : blueprintHostGroups.keySet()) {
-      HostGroupImpl hostGroup = blueprintHostGroups.get(hostGroupName);
-      if (hostGroup.getServices().contains(serviceName)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * Ensure that the specified property exists.
-   * If not, set a default value.
-   *
-   * @param type          config type
-   * @param property      property name
-   * @param defaultValue  default value
-   */
-  private void ensureProperty(String type, String property, String defaultValue) {
-    Map<String, String> properties = mapClusterConfigurations.get(type);
-    if (properties == null) {
-      properties = new HashMap<String, String>();
-      mapClusterConfigurations.put(type, properties);
-    }
-
-    if (! properties.containsKey(property)) {
-      properties.put(property, defaultValue);
-    }
-  }
-
-  /**
-   * Get set of services which are to be deployed.
-   *
-   * @param stack                stack information
-   * @param blueprintHostGroups  host groups contained in blueprint
-   *
-   * @return set of service names which will be deployed
-   */
-  private Set<String> getServicesToDeploy(Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) {
-    Set<String> services = new HashSet<String>();
-    for (HostGroupImpl group : blueprintHostGroups.values()) {
-      if (! group.getHostInfo().isEmpty()) {
-        services.addAll(stack.getServicesForComponents(group.getComponents()));
-      }
-    }
-    //remove entry associated with Ambari Server since this isn't recognized by Ambari
-    services.remove(null);
-
-    return services;
-  }
-
-  /**
-   * Register config groups for host group scoped configuration.
-   * For each host group with configuration specified in the blueprint, a config group is created
-   * and the hosts associated with the host group are assigned to the config group.
-   *
-   * @param clusterName  name of cluster
-   * @param hostGroups   map of host group name to host group
-   * @param stack        associated stack information
-   *
-   * @throws ResourceAlreadyExistsException attempt to create a config group that already exists
-   * @throws SystemException                an unexpected exception occurs
-   * @throws UnsupportedPropertyException   an invalid property is provided when creating a config group
-   * @throws NoSuchParentResourceException  attempt to create a config group for a non-existing cluster
-   */
-  private void registerConfigGroups(String clusterName, Map<String, HostGroupImpl> hostGroups, Stack stack) throws
-      ResourceAlreadyExistsException, SystemException,
-      UnsupportedPropertyException, NoSuchParentResourceException {
-
-    for (HostGroupImpl group : hostGroups.values()) {
-      HostGroupEntity entity = group.getEntity();
-      Map<String, Map<String, Config>> groupConfigs = new HashMap<String, Map<String, Config>>();
-      
-      handleGlobalsBackwardsCompability(stack, group.getConfigurationProperties(), clusterName);
-      for (Map.Entry<String, Map<String, String>> entry: group.getConfigurationProperties().entrySet()) {
-        String type = entry.getKey();
-        String service = stack.getServiceForConfigType(type);
-        Config config = new ConfigImpl(type);
-        config.setTag(entity.getName());
-        config.setProperties(entry.getValue());
-        Map<String, Config> serviceConfigs = groupConfigs.get(service);
-        if (serviceConfigs == null) {
-          serviceConfigs = new HashMap<String, Config>();
-          groupConfigs.put(service, serviceConfigs);
-        }
-        serviceConfigs.put(type, config);
-      }
-
-      for (Map.Entry<String, Map<String, Config>> entry : groupConfigs.entrySet()) {
-        String service = entry.getKey();
-        Map<String, Config> serviceConfigs = entry.getValue();
-        String hostGroupName = getConfigurationGroupName(entity.getBlueprintName(), entity.getName());
-        ConfigGroupRequest request = new ConfigGroupRequest(
-            null, clusterName, hostGroupName, service, "Host Group Configuration",
-            new HashSet<String>(group.getHostInfo()), serviceConfigs);
-
-        ((ConfigGroupResourceProvider) getResourceProvider(Resource.Type.ConfigGroup)).
-            createResources(Collections.singleton(request));
-      }
-    }
-  }
-
-  /**
-   * Validate that a host is only mapped to a single host group.
-   *
-   * @param hostGroups map of host group name to host group
-   */
-  private void validateHostMappings(Map<String, HostGroupImpl> hostGroups) {
-    Collection<String> mappedHosts = new HashSet<String>();
-    Collection<String> flaggedHosts = new HashSet<String>();
-
-    for (HostGroupImpl hostgroup : hostGroups.values()) {
-      for (String host : hostgroup.getHostInfo()) {
-        if (mappedHosts.contains(host)) {
-          flaggedHosts.add(host);
-        } else {
-          mappedHosts.add(host);
-        }
-      }
-    }
-
-    if (! flaggedHosts.isEmpty())  {
-      throw new IllegalArgumentException("A host may only be mapped to a single host group at this time." +
-                                         "  The following hosts are mapped to more than one host group: " +
-                                         flaggedHosts);
-    }
-  }
-
-  /**
    * Determine whether or not the cluster resource identified
    * by the given cluster name should be included based on the
    * permissions granted to the current user.
@@ -1258,69 +515,5 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
     return getManagementController().getClusters().checkPermission(clusterName, readOnly);
   }
 
-
-  /**
-   * Internal class meant to represent the collection of configuration
-   * items and configuration attributes that are associated with a given service.
-   *
-   * This class is used to support proper configuration versioning when
-   * Ambari Blueprints is used to deploy a cluster.
-   */
-  private static class BlueprintServiceConfigRequest {
-
-    private final String serviceName;
-
-    private List<BlueprintServiceConfigElement> configElements =
-      new LinkedList<BlueprintServiceConfigElement>();
-
-    BlueprintServiceConfigRequest(String serviceName) {
-      this.serviceName = serviceName;
-    }
-
-    void addConfigElement(String typeName, Map<String, String> configuration, Map<String, Map<String, String>> attributes) {
-      configElements.add(new BlueprintServiceConfigElement(typeName, configuration, attributes));
-    }
-
-    public String getServiceName() {
-      return serviceName;
-    }
-
-    List<BlueprintServiceConfigElement> getConfigElements() {
-      return configElements;
-    }
-
-  }
-
-  /**
-   * Internal class that represents the configuration
-   *  and attributes for a given configuration type.
-   */
-  private static class BlueprintServiceConfigElement {
-    private final String typeName;
-
-    private final Map<String, String> configuration;
-
-    private final Map<String, Map<String, String>> attributes;
-
-    BlueprintServiceConfigElement(String typeName, Map<String, String> configuration, Map<String, Map<String, String>> attributes) {
-      this.typeName = typeName;
-      this.configuration = configuration;
-      this.attributes = attributes;
-    }
-
-    public String getTypeName() {
-      return typeName;
-    }
-
-    public Map<String, String> getConfiguration() {
-      return configuration;
-    }
-
-    public Map<String, Map<String, String>> getAttributes() {
-      return attributes;
-    }
-
-  }
-
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
index dea90f6..147ab8e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
@@ -32,7 +32,6 @@ import org.apache.ambari.server.DuplicateResourceException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.ServiceNotFoundException;
-import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
@@ -51,7 +50,6 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentFactory;
@@ -211,7 +209,6 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
       for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
         requests.add(getRequest(propertyMap));
       }
-    final Predicate finalPredicate = predicate;
     RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
       @Override
       public RequestStatusResponse invoke() throws AmbariException {
@@ -251,7 +248,7 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
   }
 
   // Create the components for the given requests.
-  protected synchronized void createComponents(
+  public synchronized void createComponents(
       Set<ServiceComponentRequest> requests) throws AmbariException {
 
     if (requests.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
new file mode 100644
index 0000000..48b54a3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distribut
+ * ed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Collection;
+
+/**
+ * Indicates that there is a problem with the cluster topology configuration.
+ */
+public class ConfigurationTopologyException extends Exception {
+  public ConfigurationTopologyException(Collection<String> properties) {
+    super(String.format("Unable to resolve host names for the following configuration properties %s", properties));
+  }
+
+  public ConfigurationTopologyException(String s) {
+    super(s);
+  }
+
+  public ConfigurationTopologyException(String s, Throwable throwable) {
+    super(s, throwable);
+  }
+}