You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mp...@apache.org on 2018/09/05 15:31:13 UTC

[ambari] branch trunk updated: AMBARI-24549. Move blueprint provisioning state property to host component level. (#2241)

This is an automated email from the ASF dual-hosted git repository.

mpapirkovskyy pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 4b5aafc  AMBARI-24549. Move blueprint provisioning state property to host component level. (#2241)
4b5aafc is described below

commit 4b5aafcf9cce58f56b28b5758fc0890874e26b50
Author: Myroslav Papirkovskyi <mp...@apache.org>
AuthorDate: Wed Sep 5 18:31:10 2018 +0300

    AMBARI-24549. Move blueprint provisioning state property to host component level. (#2241)
    
    * AMBARI-24549. Move blueprint provisioning state property to host component level. (mpapirkovskyy)
    
    * AMBARI-24549. Move blueprint provisioning state property to host component level. (mpapirkovskyy)
    
    * AMBARI-24549. Move blueprint provisioning state property to host component level. (mpapirkovskyy)
---
 .../main/python/ambari_agent/RecoveryManager.py    |  8 ++--
 .../server/agent/stomp/HostLevelParamsHolder.java  | 24 ++++++++--
 .../agent/stomp/dto/HostLevelParamsCluster.java    | 14 +++++-
 .../controller/AmbariManagementController.java     | 15 ++++++
 .../controller/AmbariManagementControllerImpl.java | 39 ++++++++++++++--
 .../controller/internal/HostResourceProvider.java  |  3 +-
 .../ambari/server/orm/entities/ClusterEntity.java  | 14 ------
 .../entities/HostComponentDesiredStateEntity.java  | 19 ++++++++
 .../org/apache/ambari/server/state/Cluster.java    |  4 --
 .../ambari/server/state/cluster/ClusterImpl.java   | 53 +++++++++++-----------
 .../svccomphost/ServiceComponentHostImpl.java      | 20 ++++++++
 .../ambari/server/topology/AmbariContext.java      |  7 ++-
 .../ambari/server/upgrade/UpgradeCatalog272.java   | 16 ++++++-
 .../src/main/resources/Ambari-DDL-Derby-CREATE.sql |  2 +-
 .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql |  2 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql    |  2 +-
 .../main/resources/Ambari-DDL-Postgres-CREATE.sql  |  2 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql    |  2 +-
 .../main/resources/Ambari-DDL-SQLServer-CREATE.sql |  2 +-
 .../agent/stomp/HostLevelParamsHolderTest.java     | 18 +++++---
 .../internal/HostResourceProviderTest.java         |  3 ++
 .../ambari/server/topology/AmbariContextTest.java  | 11 +++--
 .../server/upgrade/UpgradeCatalog272Test.java      | 38 +++++++++++++++-
 23 files changed, 242 insertions(+), 76 deletions(-)

diff --git a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
index 64ae873..ba6507c 100644
--- a/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
+++ b/ambari-agent/src/main/python/ambari_agent/RecoveryManager.py
@@ -98,7 +98,7 @@ class RecoveryManager:
     self.active_command_count = 0
     self.cluster_id = None
     self.initializer_module = initializer_module
-    self.metadata_cache = initializer_module.metadata_cache
+    self.host_level_params_cache = initializer_module.host_level_params_cache
 
     self.actions = {}
     self.update_config(6, 60, 5, 12, recovery_enabled, auto_start_only, auto_install_start)
@@ -111,9 +111,9 @@ class RecoveryManager:
     with self.__active_command_lock:
       self.active_command_count -= 1
 
-  def is_blueprint_provisioning(self):
+  def is_blueprint_provisioning_for_component(self, component_name):
     try:
-      blueprint_state = self.metadata_cache[self.cluster_id]['clusterLevelParams']['blueprint_provisioning_state']
+      blueprint_state = self.host_level_params_cache[self.cluster_id]['blueprint_provisioning_state'][component_name]
     except KeyError:
       blueprint_state = 'NONE'
 
@@ -650,7 +650,7 @@ class RecoveryManager:
       logger.info("Recovery is paused, tasks waiting in pipeline for this host.")
       return None
 
-    if self.is_blueprint_provisioning():
+    if self.is_blueprint_provisioning_for_component(component):
       logger.info("Recovery is paused, blueprint is being provisioned.")
       return None
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
index b309bbb..4908d56 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java
@@ -34,6 +34,7 @@ import org.apache.ambari.server.events.HostLevelParamsUpdateEvent;
 import org.apache.ambari.server.events.MaintenanceModeEvent;
 import org.apache.ambari.server.events.ServiceComponentRecoveryChangedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Host;
@@ -76,7 +77,8 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
       }
       HostLevelParamsCluster hostLevelParamsCluster = new HostLevelParamsCluster(
           m_ambariManagementController.get().retrieveHostRepositories(cl, host),
-          recoveryConfigHelper.getRecoveryConfig(cl.getClusterName(), host.getHostName()));
+          recoveryConfigHelper.getRecoveryConfig(cl.getClusterName(), host.getHostName()),
+          m_ambariManagementController.get().getBlueprintProvisioningStates(cl.getClusterId(), host.getHostId()));
 
       hostLevelParamsClusters.put(Long.toString(cl.getClusterId()),
           hostLevelParamsCluster);
@@ -85,6 +87,12 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
     return hostLevelParamsUpdateEvent;
   }
 
+  public void updateAllHosts() throws AmbariException {
+    for (Host host : clusters.getHosts()) {
+      updateData(getCurrentData(host.getHostId()));
+    }
+  }
+
   @Override
   protected HostLevelParamsUpdateEvent handleUpdate(HostLevelParamsUpdateEvent current, HostLevelParamsUpdateEvent update) {
     HostLevelParamsUpdateEvent result = null;
@@ -107,6 +115,7 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
           HostLevelParamsCluster currentCluster = current.getHostLevelParamsClusters().get(clusterId);
           RecoveryConfig mergedRecoveryConfig;
           SortedMap<Long, CommandRepository> mergedRepositories;
+          Map<String, BlueprintProvisioningState> mergedBlueprintProvisioningStates;
           SortedMap<String, Long> mergedComponentRepos;
           if (!currentCluster.getRecoveryConfig().equals(updatedCluster.getRecoveryConfig())) {
             mergedRecoveryConfig = updatedCluster.getRecoveryConfig();
@@ -121,6 +130,13 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
           } else {
             mergedRepositories = currentCluster.getHostRepositories().getRepositories();
           }
+          if (!currentCluster.getBlueprintProvisioningState()
+              .equals(updatedCluster.getBlueprintProvisioningState())) {
+            mergedBlueprintProvisioningStates = updatedCluster.getBlueprintProvisioningState();
+            clusterChanged = true;
+          } else {
+            mergedBlueprintProvisioningStates = currentCluster.getBlueprintProvisioningState();
+          }
           if (!currentCluster.getHostRepositories().getComponentRepos()
               .equals(updatedCluster.getHostRepositories().getComponentRepos())) {
             mergedComponentRepos = updatedCluster.getHostRepositories().getComponentRepos();
@@ -131,7 +147,8 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
           if (clusterChanged) {
             HostLevelParamsCluster mergedCluster = new HostLevelParamsCluster(
                 new HostRepositories(mergedRepositories, mergedComponentRepos),
-                mergedRecoveryConfig);
+                mergedRecoveryConfig,
+                mergedBlueprintProvisioningStates);
             mergedClusters.put(clusterId, mergedCluster);
             changed = true;
           } else {
@@ -176,7 +193,8 @@ public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUp
         Long.toString(clusterId),
             new HostLevelParamsCluster(
                     m_ambariManagementController.get().retrieveHostRepositories(cluster, host),
-                    recoveryConfigHelper.getRecoveryConfig(cluster.getClusterName(), host.getHostName())));
+                    recoveryConfigHelper.getRecoveryConfig(cluster.getClusterName(), host.getHostName()),
+                    m_ambariManagementController.get().getBlueprintProvisioningStates(clusterId, host.getHostId())));
     updateData(hostLevelParamsUpdateEvent);
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/HostLevelParamsCluster.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/HostLevelParamsCluster.java
index dfbc6f7..c3b4842 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/HostLevelParamsCluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/HostLevelParamsCluster.java
@@ -18,7 +18,10 @@
 package org.apache.ambari.server.agent.stomp.dto;
 
 
+import java.util.Map;
+
 import org.apache.ambari.server.agent.RecoveryConfig;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -32,9 +35,14 @@ public class HostLevelParamsCluster {
   @JsonProperty("recoveryConfig")
   private RecoveryConfig recoveryConfig;
 
-  public HostLevelParamsCluster(HostRepositories hostRepositories, RecoveryConfig recoveryConfig) {
+  @JsonProperty("blueprint_provisioning_state")
+  private Map<String, BlueprintProvisioningState> blueprintProvisioningState;
+
+  public HostLevelParamsCluster(HostRepositories hostRepositories, RecoveryConfig recoveryConfig,
+                                Map<String, BlueprintProvisioningState> blueprintProvisioningState) {
     this.hostRepositories = hostRepositories;
     this.recoveryConfig = recoveryConfig;
+    this.blueprintProvisioningState = blueprintProvisioningState;
   }
 
   public HostRepositories getHostRepositories() {
@@ -44,4 +52,8 @@ public class HostLevelParamsCluster {
   public RecoveryConfig getRecoveryConfig() {
     return recoveryConfig;
   }
+
+  public Map<String, BlueprintProvisioningState> getBlueprintProvisioningState() {
+    return blueprintProvisioningState;
+  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index bf639bd..57e80f5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -48,6 +48,7 @@ import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.security.ldap.LdapBatchDto;
 import org.apache.ambari.server.security.ldap.LdapSyncDto;
 import org.apache.ambari.server.stageplanner.RoleGraphFactory;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -105,6 +106,18 @@ public interface AmbariManagementController {
       Set<ServiceComponentHostRequest> requests) throws AmbariException, AuthorizationException;
 
   /**
+   * Create the host component defined by the attributes in the given request object.
+   *
+   * @param requests  the request object which defines the host component to be created
+   *
+   * @param isBlueprintProvisioned  means host components will be created during blueprint deploy
+   *
+   * @throws AmbariException thrown if the host component cannot be created
+   */
+  void createHostComponents(
+      Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned) throws AmbariException, AuthorizationException;
+
+  /**
    * Creates a configuration.
    *
    * @param request the request object which defines the configuration.
@@ -937,5 +950,7 @@ public interface AmbariManagementController {
 
   TopologyUpdateEvent getAddedComponentsTopologyEvent(Set<ServiceComponentHostRequest> requests)
       throws AmbariException;
+
+  Map<String, BlueprintProvisioningState> getBlueprintProvisioningStates(Long clusterId, Long hostId) throws AmbariException;
 }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index a5cee17..4927c34 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -24,7 +24,6 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.BLUEPRINT_PROVISIONING_STATE;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLIENTS_TO_UPDATE_CONFIGS;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.CLUSTER_NAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
@@ -146,6 +145,7 @@ import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.dao.ExtensionDAO;
 import org.apache.ambari.server.orm.dao.ExtensionLinkDAO;
+import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.SettingDAO;
@@ -154,6 +154,7 @@ import org.apache.ambari.server.orm.dao.WidgetDAO;
 import org.apache.ambari.server.orm.dao.WidgetLayoutDAO;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ExtensionLinkEntity;
+import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.RepoDefinitionEntity;
 import org.apache.ambari.server.orm.entities.RepoOsEntity;
@@ -183,6 +184,7 @@ import org.apache.ambari.server.stack.ExtensionHelper;
 import org.apache.ambari.server.stack.RepoUtil;
 import org.apache.ambari.server.stageplanner.RoleGraph;
 import org.apache.ambari.server.stageplanner.RoleGraphFactory;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.CommandScriptDefinition;
@@ -374,6 +376,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   @Inject
   private RepositoryVersionHelper repoVersionHelper;
 
+  @Inject
+  private HostComponentDesiredStateDAO hostComponentDesiredStateDAO;
+
   /**
    * The KerberosHelper to help setup for enabling for disabling Kerberos
    */
@@ -549,6 +554,13 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests)
       throws AmbariException, AuthorizationException {
 
+    createHostComponents(requests, false);
+  }
+
+  @Override
+  public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
+      throws AmbariException, AuthorizationException {
+
     if (requests.isEmpty()) {
       LOG.warn("Received an empty requests set");
       return;
@@ -701,11 +713,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     // set restartRequired flag for  monitoring services
     setMonitoringServicesRestartRequired(requests);
     // now doing actual work
-    persistServiceComponentHosts(requests);
+    persistServiceComponentHosts(requests, isBlueprintProvisioned);
     m_topologyHolder.get().updateData(getAddedComponentsTopologyEvent(requests));
   }
 
-  void persistServiceComponentHosts(Set<ServiceComponentHostRequest> requests)
+  void persistServiceComponentHosts(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
     throws AmbariException {
     Multimap<Cluster, ServiceComponentHost> schMap = ArrayListMultimap.create();
     Map<Long, Map<String, List<String>>> serviceComponentNames = new HashMap<>();
@@ -742,6 +754,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         State state = State.valueOf(request.getDesiredState());
         sch.setDesiredState(state);
       }
+      if (isBlueprintProvisioned && !sch.isClientComponent()) {
+        HostComponentDesiredStateEntity desiredStateEntity = sch.getDesiredStateEntity();
+        desiredStateEntity.setBlueprintProvisioningState(BlueprintProvisioningState.IN_PROGRESS);
+        hostComponentDesiredStateDAO.merge(desiredStateEntity);
+      }
 
       schMap.put(cluster, sch);
     }
@@ -5676,6 +5693,21 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return statusCommandParams;
   }
 
+  @Override
+  public Map<String, BlueprintProvisioningState> getBlueprintProvisioningStates(Long clusterId, Long hostId)
+      throws AmbariException {
+    Map<String, BlueprintProvisioningState> blueprintProvisioningStates = new HashMap<>();
+    Host host = clusters.getHostById(hostId);
+    Cluster cl = clusters.getCluster(clusterId);
+    for (ServiceComponentHost sch : cl.getServiceComponentHosts(host.getHostName())) {
+      if (!sch.isClientComponent()) {
+        blueprintProvisioningStates.put(sch.getServiceComponentName(),
+            sch.getDesiredStateEntity().getBlueprintProvisioningState());
+      }
+    }
+    return blueprintProvisioningStates;
+  }
+
   //TODO will be a need to change to multi-instance usage
   public TreeMap<String, String> getTopologyCommandParams(Long clusterId, String serviceName, String componentName, ServiceComponentHost sch) throws AmbariException {
     TreeMap<String, String> commandParams = new TreeMap<>();
@@ -5744,7 +5776,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     clusterLevelParams.putAll(getMetadataClusterLevelConfigsParams(cluster, stackId));
     clusterLevelParams.put(CLUSTER_NAME, cluster.getClusterName());
     clusterLevelParams.put(HOOKS_FOLDER, configs.getProperty(Configuration.HOOKS_FOLDER));
-    clusterLevelParams.put(BLUEPRINT_PROVISIONING_STATE, cluster.getBlueprintProvisioningState().toString());
 
     return clusterLevelParams;
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
index 3045bfa..941297c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
@@ -570,7 +570,8 @@ public class HostResourceProvider extends AbstractControllerResourceProvider {
             new HostLevelParamsCluster(
             getManagementController().retrieveHostRepositories(cl, addedHost),
             recoveryConfigHelper.getRecoveryConfig(cl.getClusterName(),
-                addedHost.getHostName())
+                addedHost.getHostName()),
+            getManagementController().getBlueprintProvisioningStates(cl.getClusterId(), addedHost.getHostId())
         ));
         hostLevelParamsUpdateEvents.add(hostLevelParamsUpdateEvent);
       }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
index fa94d7a..c22449c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
@@ -42,7 +42,6 @@ import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.TableGenerator;
 
-import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.State;
 
@@ -96,11 +95,6 @@ public class ClusterEntity {
   @Column(name = "cluster_info", insertable = true, updatable = true)
   private String clusterInfo = "";
 
-  @Basic
-  @Enumerated(value = EnumType.STRING)
-  @Column(name = "blueprint_provisioning_state", insertable = true, updatable = true)
-  private BlueprintProvisioningState blueprintProvisioningState = BlueprintProvisioningState.NONE;
-
   /**
    * Unidirectional one-to-one association to {@link StackEntity}
    */
@@ -353,12 +347,4 @@ public class ClusterEntity {
   public void setUpgradeEntity(UpgradeEntity upgradeEntity) {
     this.upgradeEntity = upgradeEntity;
   }
-
-  public BlueprintProvisioningState getBlueprintProvisioningState() {
-    return blueprintProvisioningState;
-  }
-
-  public void setBlueprintProvisioningState(BlueprintProvisioningState blueprintProvisioningState) {
-    this.blueprintProvisioningState = blueprintProvisioningState;
-  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
index 4c673f1..3a2506d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
@@ -36,6 +36,7 @@ import javax.persistence.Table;
 import javax.persistence.TableGenerator;
 import javax.persistence.UniqueConstraint;
 
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.State;
@@ -122,6 +123,11 @@ public class HostComponentDesiredStateEntity {
   @Column(name = "restart_required", insertable = true, updatable = true, nullable = false)
   private Integer restartRequired = 0;
 
+  @Basic
+  @Enumerated(value = EnumType.STRING)
+  @Column(name = "blueprint_provisioning_state", insertable = true, updatable = true)
+  private BlueprintProvisioningState blueprintProvisioningState = BlueprintProvisioningState.NONE;
+
   public Long getId() { return id; }
 
   public Long getClusterId() {
@@ -180,6 +186,14 @@ public class HostComponentDesiredStateEntity {
     this.hostId = hostId;
   }
 
+  public BlueprintProvisioningState getBlueprintProvisioningState() {
+    return blueprintProvisioningState;
+  }
+
+  public void setBlueprintProvisioningState(BlueprintProvisioningState blueprintProvisioningState) {
+    this.blueprintProvisioningState = blueprintProvisioningState;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) {
@@ -215,6 +229,10 @@ public class HostComponentDesiredStateEntity {
       return false;
     }
 
+    if (!Objects.equal(blueprintProvisioningState, that.blueprintProvisioningState)) {
+      return false;
+    }
+
     return true;
   }
 
@@ -226,6 +244,7 @@ public class HostComponentDesiredStateEntity {
     result = 31 * result + (componentName != null ? componentName.hashCode() : 0);
     result = 31 * result + (desiredState != null ? desiredState.hashCode() : 0);
     result = 31 * result + (serviceName != null ? serviceName.hashCode() : 0);
+    result = 31 * result + (blueprintProvisioningState != null ? blueprintProvisioningState.hashCode() : 0);
     return result;
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 1b0e4b4..c201310 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -245,10 +245,6 @@ public interface Cluster {
    */
   void setProvisioningState(State provisioningState);
 
-  BlueprintProvisioningState getBlueprintProvisioningState();
-
-  void setBlueprintProvisioningState(BlueprintProvisioningState blueprintProvisioningState);
-
   /**
    * Gets the cluster's security type.
    *
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index eafb863..e46ff45 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -56,7 +56,7 @@ import org.apache.ambari.server.ServiceComponentHostNotFoundException;
 import org.apache.ambari.server.ServiceComponentNotFoundException;
 import org.apache.ambari.server.ServiceNotFoundException;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
-import org.apache.ambari.server.agent.stomp.MetadataHolder;
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariSessionManager;
@@ -70,7 +70,6 @@ import org.apache.ambari.server.controller.internal.DeleteHostComponentStatusMet
 import org.apache.ambari.server.events.AmbariEvent.AmbariEventType;
 import org.apache.ambari.server.events.ClusterConfigChangedEvent;
 import org.apache.ambari.server.events.ClusterEvent;
-import org.apache.ambari.server.events.ClusterProvisionStartedEvent;
 import org.apache.ambari.server.events.ClusterProvisionedEvent;
 import org.apache.ambari.server.events.ConfigsUpdateEvent;
 import org.apache.ambari.server.events.jpa.EntityManagerCacheInvalidationEvent;
@@ -284,7 +283,7 @@ public class ClusterImpl implements Cluster {
   private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
 
   @Inject
-  private MetadataHolder metadataHolder;
+  private HostLevelParamsHolder hostLevelParamsHolder;
 
   /**
    * Data access object used for looking up stacks from the database.
@@ -972,17 +971,23 @@ public class ClusterImpl implements Cluster {
     clusterEntity = clusterDAO.merge(clusterEntity);
   }
 
-  @Override
-  public BlueprintProvisioningState getBlueprintProvisioningState() {
-    ClusterEntity clusterEntity = getClusterEntity();
-    return clusterEntity.getBlueprintProvisioningState();
-  }
-
-  @Override
-  public void setBlueprintProvisioningState(BlueprintProvisioningState blueprintProvisioningState) {
-    ClusterEntity clusterEntity = getClusterEntity();
-    clusterEntity.setBlueprintProvisioningState(blueprintProvisioningState);
-    clusterEntity = clusterDAO.merge(clusterEntity);
+  private boolean setBlueprintProvisioningState(BlueprintProvisioningState blueprintProvisioningState) {
+    boolean updated = false;
+    for (Service s : getServices().values()) {
+      for (ServiceComponent sc : s.getServiceComponents().values()) {
+        if (!sc.isClientComponent()) {
+          for (ServiceComponentHost sch : sc.getServiceComponentHosts().values()) {
+            HostComponentDesiredStateEntity desiredStateEntity = sch.getDesiredStateEntity();
+            if (desiredStateEntity.getBlueprintProvisioningState() != blueprintProvisioningState) {
+              desiredStateEntity.setBlueprintProvisioningState(blueprintProvisioningState);
+              hostComponentDesiredStateDAO.merge(desiredStateEntity);
+              updated = true;
+            }
+          }
+        }
+      }
+    }
+    return updated;
   }
 
   @Override
@@ -2814,19 +2819,15 @@ public class ClusterImpl implements Cluster {
     }
   }
 
-  @Subscribe
-  public void onClusterProvisionStarted(ClusterProvisionStartedEvent event) {
-    if (event.getClusterId() == getClusterId()) {
-      changeBlueprintProvisioningState(BlueprintProvisioningState.IN_PROGRESS);
-    }
-  }
-
   private void changeBlueprintProvisioningState(BlueprintProvisioningState newState) {
-    setBlueprintProvisioningState(newState);
-    try {
-      metadataHolder.updateData(controller.getClusterMetadataOnConfigsUpdate(this));
-    } catch (AmbariException e) {
-      LOG.error("Metadata update failed after setting blueprint provision state to {}", newState, e);
+    boolean updated = setBlueprintProvisioningState(newState);
+    if (updated) {
+      try {
+        //host level params update
+        hostLevelParamsHolder.updateAllHosts();
+      } catch (AmbariException e) {
+        LOG.error("Topology update failed after setting blueprint provision state to {}", newState, e);
+      }
     }
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index f9bf39d..8006e53 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -31,6 +31,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.AlertDefinitionCommand;
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
 import org.apache.ambari.server.agent.stomp.TopologyHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
@@ -61,6 +62,7 @@ import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
@@ -140,6 +142,9 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   @Inject
   private Provider<TopologyHolder> m_topologyHolder;
 
+  @Inject
+  private Provider<HostLevelParamsHolder> m_hostLevelParamsHolder;
+
   /**
    * Used for creating commands to send to the agents when alert definitions are
    * added as the result of a service install.
@@ -1043,6 +1048,14 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
           STOMPUpdatePublisher.publish(new HostComponentsUpdateEvent(Collections.singletonList(
               HostComponentUpdate.createHostComponentStatusUpdate(stateEntity, oldState))));
         }
+        if (event.getType().equals(ServiceComponentHostEventType.HOST_SVCCOMP_START)) {
+          HostComponentDesiredStateEntity desiredStateEntity = getDesiredStateEntity();
+          if (desiredStateEntity.getBlueprintProvisioningState() == BlueprintProvisioningState.IN_PROGRESS) {
+            desiredStateEntity.setBlueprintProvisioningState(BlueprintProvisioningState.FINISHED);
+            hostComponentDesiredStateDAO.merge(desiredStateEntity);
+            m_hostLevelParamsHolder.get().updateData(m_hostLevelParamsHolder.get().getCurrentData(getHost().getHostId()));
+          }
+        }
         // TODO Audit logs
       } catch (InvalidStateTransitionException e) {
         LOG.error("Can't handle ServiceComponentHostEvent event at"
@@ -1053,6 +1066,13 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
             + ", eventType=" + event.getType()
             + ", event=" + event);
         throw e;
+      } catch (AmbariException e) {
+        LOG.error("Can't update topology on hosts on ServiceComponentHostEvent event: "
+            + "serviceComponentName=" + getServiceComponentName()
+            + ", hostName=" + getHostName()
+            + ", currentState=" + oldState
+            + ", eventType=" + event.getType()
+            + ", event=" + event);
       }
     } finally {
       writeLock.unlock();
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 9272e12..6e95c4d 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
@@ -43,6 +43,7 @@ import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.ClusterRequest;
@@ -124,6 +125,9 @@ public class AmbariContext {
   @Inject
   private Provider<ConfigHelper> configHelper;
 
+  @Inject
+  HostLevelParamsHolder hostLevelParamsHolder;
+
   private static AmbariManagementController controller;
   private static ClusterController clusterController;
   //todo: task id's.  Use existing mechanism for getting next task id sequence
@@ -415,10 +419,11 @@ public class AmbariContext {
       RetryHelper.executeWithRetry(new Callable<Object>() {
         @Override
         public Object call() throws Exception {
-          getController().createHostComponents(requests);
+          getController().createHostComponents(requests, true);
           return null;
         }
       });
+      hostLevelParamsHolder.updateData(hostLevelParamsHolder.getCurrentData(host.getHostId()));
     } catch (AmbariException e) {
       LOG.error("Unable to create host component resource for host {}", hostName, e);
       throw new RuntimeException(String.format("Unable to create host component resource for host '%s': %s",
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
index 32b8043..0327acd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog272.java
@@ -27,6 +27,8 @@ import java.sql.SQLException;
 import java.util.Collections;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,6 +48,10 @@ public class UpgradeCatalog272 extends AbstractUpgradeCatalog {
       AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN, LDAP_CONFIGURATION_CORRECT_COLLISION_BEHAVIOR_PROPERTY_NAME, AMBARI_CONFIGURATION_CATEGORY_NAME_COLUMN,
       LDAP_CONFIGURATION.getCategoryName(), AMBARI_CONFIGURATION_PROPERTY_NAME_COLUMN, LDAP_CONFIGURATION_WRONG_COLLISION_BEHAVIOR_PROPERTY_NAME);
 
+  protected static final String HOST_COMPONENT_DESIRED_STATE_TABLE = "hostcomponentdesiredstate";
+  protected static final String CLUSTERS_TABLE = "clusters";
+  protected static final String BLUEPRINT_PROVISIONING_STATE_COLUMN = "blueprint_provisioning_state";
+
   @Inject
   public UpgradeCatalog272(Injector injector) {
     super(injector);
@@ -63,7 +69,7 @@ public class UpgradeCatalog272 extends AbstractUpgradeCatalog {
 
   @Override
   protected void executeDDLUpdates() throws AmbariException, SQLException {
-    // nothing to do
+    moveBlueprintProvisioningState();
   }
 
   @Override
@@ -93,4 +99,12 @@ public class UpgradeCatalog272 extends AbstractUpgradeCatalog {
     addRoleAuthorization(AMBARI_VIEW_STATUS_INFO.getId(), "View status information", Collections.singleton("AMBARI.ADMINISTRATOR:AMBARI"));
     LOG.info("Added new role authorization {}", AMBARI_VIEW_STATUS_INFO.getId());
   }
+
+  protected void moveBlueprintProvisioningState() throws SQLException {
+    dbAccessor.dropColumn(CLUSTERS_TABLE, BLUEPRINT_PROVISIONING_STATE_COLUMN);
+    dbAccessor.addColumn(HOST_COMPONENT_DESIRED_STATE_TABLE,
+        new DBAccessor.DBColumnInfo(BLUEPRINT_PROVISIONING_STATE_COLUMN, String.class, 255,
+            BlueprintProvisioningState.NONE, true));
+  }
+
 }
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 680c8fa..fbb650c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -58,7 +58,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR(255) NOT NULL,
   cluster_name VARCHAR(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
-  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   security_type VARCHAR(32) NOT NULL DEFAULT 'NONE',
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
@@ -226,6 +225,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR(255) NOT NULL,
   admin_state VARCHAR(32),
   maintenance_state VARCHAR(32) NOT NULL,
+  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   restart_required SMALLINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index 143669e..ceb4f08 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -78,7 +78,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR(255) NOT NULL,
   cluster_name VARCHAR(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
-  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   security_type VARCHAR(32) NOT NULL DEFAULT 'NONE',
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
@@ -246,6 +245,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR(100) NOT NULL,
   admin_state VARCHAR(32),
   maintenance_state VARCHAR(32) NOT NULL DEFAULT 'ACTIVE',
+  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   restart_required TINYINT(1) NOT NULL DEFAULT 0,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index 90d6f9b..aee60fb 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -58,7 +58,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR2(255) NULL,
   cluster_name VARCHAR2(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR2(255) DEFAULT 'INIT' NOT NULL,
-  blueprint_provisioning_state VARCHAR2(255) DEFAULT 'NONE',
   security_type VARCHAR2(32) DEFAULT 'NONE' NOT NULL,
   desired_cluster_state VARCHAR2(255) NULL,
   desired_stack_id NUMBER(19) NOT NULL,
@@ -227,6 +226,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR2(255) NOT NULL,
   admin_state VARCHAR2(32) NULL,
   maintenance_state VARCHAR2(32) NOT NULL,
+  blueprint_provisioning_state VARCHAR2(255) DEFAULT 'NONE',
   restart_required NUMBER(1) DEFAULT 0 NOT NULL,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 702e9d3..ea29531 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -58,7 +58,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR(255) NOT NULL,
   cluster_name VARCHAR(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
-  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   security_type VARCHAR(32) NOT NULL DEFAULT 'NONE',
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
@@ -228,6 +227,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR(255) NOT NULL,
   admin_state VARCHAR(32),
   maintenance_state VARCHAR(32) NOT NULL,
+  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   restart_required SMALLINT NOT NULL DEFAULT 0,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index dae27b0..7535642 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -57,7 +57,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR(255) NOT NULL,
   cluster_name VARCHAR(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
-  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   security_type VARCHAR(32) NOT NULL DEFAULT 'NONE',
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id NUMERIC(19) NOT NULL,
@@ -225,6 +224,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR(255) NOT NULL,
   admin_state VARCHAR(32),
   maintenance_state VARCHAR(32) NOT NULL DEFAULT 'ACTIVE',
+  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   restart_required BIT NOT NULL DEFAULT 0,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 0a6fc30..0d151eb 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -71,7 +71,6 @@ CREATE TABLE clusters (
   cluster_info VARCHAR(255) NOT NULL,
   cluster_name VARCHAR(100) NOT NULL UNIQUE,
   provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
-  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   security_type VARCHAR(32) NOT NULL DEFAULT 'NONE',
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
@@ -240,6 +239,7 @@ CREATE TABLE hostcomponentdesiredstate (
   service_name VARCHAR(255) NOT NULL,
   admin_state VARCHAR(32),
   maintenance_state VARCHAR(32) NOT NULL,
+  blueprint_provisioning_state VARCHAR(255) DEFAULT 'NONE',
   restart_required BIT NOT NULL DEFAULT 0,
   CONSTRAINT PK_hostcomponentdesiredstate PRIMARY KEY CLUSTERED (id),
   CONSTRAINT UQ_hcdesiredstate_name UNIQUE (component_name, service_name, host_id, cluster_id),
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolderTest.java
index 4fef7fe..867a9e2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolderTest.java
@@ -41,7 +41,8 @@ public class HostLevelParamsHolderTest {
     HostLevelParamsUpdateEvent current = new HostLevelParamsUpdateEvent(HOST_ID, Collections.emptyMap());
     Map<String, HostLevelParamsCluster> clusters = new HashMap<>();
     HostRepositories hostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster cluster = new HostLevelParamsCluster(hostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster cluster = new HostLevelParamsCluster(hostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     clusters.put("1", cluster);
     HostLevelParamsUpdateEvent update = new HostLevelParamsUpdateEvent(HOST_ID, clusters);
 
@@ -57,7 +58,8 @@ public class HostLevelParamsHolderTest {
   public void testHandleUpdateEmptyUpdate() {
     Map<String, HostLevelParamsCluster> clusters = new HashMap<>();
     HostRepositories hostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster cluster = new HostLevelParamsCluster(hostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster cluster = new HostLevelParamsCluster(hostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     clusters.put("1", cluster);
     HostLevelParamsUpdateEvent current = new HostLevelParamsUpdateEvent(HOST_ID, clusters);
     HostLevelParamsUpdateEvent update = new HostLevelParamsUpdateEvent(HOST_ID, Collections.emptyMap());
@@ -74,13 +76,15 @@ public class HostLevelParamsHolderTest {
   public void testHandleUpdateNoChanges() {
     Map<String, HostLevelParamsCluster> currentClusters = new HashMap<>();
     HostRepositories currentHostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster currentCluster = new HostLevelParamsCluster(currentHostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster currentCluster = new HostLevelParamsCluster(currentHostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     currentClusters.put("1", currentCluster);
     HostLevelParamsUpdateEvent current = new HostLevelParamsUpdateEvent(HOST_ID, currentClusters);
 
     Map<String, HostLevelParamsCluster> updateClusters = new HashMap<>();
     HostRepositories updateHostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster updateCluster = new HostLevelParamsCluster(updateHostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster updateCluster = new HostLevelParamsCluster(updateHostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     updateClusters.put("1", updateCluster);
     HostLevelParamsUpdateEvent update = new HostLevelParamsUpdateEvent(HOST_ID, updateClusters);
 
@@ -96,13 +100,15 @@ public class HostLevelParamsHolderTest {
   public void testHandleUpdateOnChanges() {
     Map<String, HostLevelParamsCluster> currentClusters = new HashMap<>();
     HostRepositories currentHostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster currentCluster = new HostLevelParamsCluster(currentHostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster currentCluster = new HostLevelParamsCluster(currentHostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     currentClusters.put("1", currentCluster);
     HostLevelParamsUpdateEvent current = new HostLevelParamsUpdateEvent(HOST_ID, currentClusters);
 
     Map<String, HostLevelParamsCluster> updateClusters = new HashMap<>();
     HostRepositories updateHostRepositories = new HostRepositories(Collections.emptySortedMap(), Collections.emptySortedMap());
-    HostLevelParamsCluster updateCluster = new HostLevelParamsCluster(updateHostRepositories, new RecoveryConfig(null));
+    HostLevelParamsCluster updateCluster = new HostLevelParamsCluster(updateHostRepositories,
+        new RecoveryConfig(null), Collections.emptyMap());
     updateClusters.put("2", updateCluster);
     HostLevelParamsUpdateEvent update = new HostLevelParamsUpdateEvent(HOST_ID, updateClusters);
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java
index 10aa0f9..7eacb28 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import static org.easymock.EasyMock.anyLong;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.eq;
@@ -158,6 +159,8 @@ public class HostResourceProviderTest extends EasyMockSupport {
     Capture<String> rackChangeAffectedClusterName = EasyMock.newCapture();
     managementController.registerRackChange(capture(rackChangeAffectedClusterName));
     EasyMock.expectLastCall().once();
+    expect(managementController.getBlueprintProvisioningStates(anyLong(), anyLong()))
+        .andReturn(Collections.EMPTY_MAP).anyTimes();
 
 
     Clusters clusters = injector.getInstance(Clusters.class);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
index 5128c65..34348aa 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
@@ -24,6 +24,7 @@ import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
@@ -44,6 +45,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.ambari.server.agent.stomp.HostLevelParamsHolder;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.ClusterRequest;
 import org.apache.ambari.server.controller.ConfigGroupRequest;
@@ -217,10 +219,13 @@ public class AmbariContextTest {
 
     expect(repositoryVersionDAO.findByStack(EasyMock.anyObject(StackId.class))).andReturn(
         singletonList(repositoryVersion)).atLeastOnce();
-    replay(repositoryVersionDAO, repositoryVersion);
+
+    HostLevelParamsHolder hostLevelParamsHolder = createNiceMock(HostLevelParamsHolder.class);
+    replay(repositoryVersionDAO, repositoryVersion, hostLevelParamsHolder);
 
     context.configFactory = configFactory;
     context.repositoryVersionDAO = repositoryVersionDAO;
+    context.hostLevelParamsHolder = hostLevelParamsHolder;
 
     blueprintServices.add("service1");
     blueprintServices.add("service2");
@@ -386,7 +391,7 @@ public class AmbariContextTest {
     expect(cluster.getService("service2")).andReturn(mockService1).once();
     Capture<Set<ServiceComponentHostRequest>> requestsCapture = EasyMock.newCapture();
 
-    controller.createHostComponents(capture(requestsCapture));
+    controller.createHostComponents(capture(requestsCapture), eq(true));
     expectLastCall().once();
 
     replayAll();
@@ -416,7 +421,7 @@ public class AmbariContextTest {
     expect(cluster.getService("service1")).andReturn(mockService1).times(2);
     Capture<Set<ServiceComponentHostRequest>> requestsCapture = EasyMock.newCapture();
 
-    controller.createHostComponents(capture(requestsCapture));
+    controller.createHostComponents(capture(requestsCapture), eq(true));
     expectLastCall().once();
 
     replayAll();
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
index 0c7fb02..a45abf0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog272Test.java
@@ -18,10 +18,16 @@
 package org.apache.ambari.server.upgrade;
 
 import static org.apache.ambari.server.upgrade.UpgradeCatalog270.AMBARI_CONFIGURATION_TABLE;
+import static org.apache.ambari.server.upgrade.UpgradeCatalog272.BLUEPRINT_PROVISIONING_STATE_COLUMN;
+import static org.apache.ambari.server.upgrade.UpgradeCatalog272.CLUSTERS_TABLE;
+import static org.apache.ambari.server.upgrade.UpgradeCatalog272.HOST_COMPONENT_DESIRED_STATE_TABLE;
 import static org.apache.ambari.server.upgrade.UpgradeCatalog272.RENAME_COLLISION_BEHAVIOR_PROPERTY_SQL;
+import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.newCapture;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
@@ -29,6 +35,9 @@ import static org.junit.Assert.assertEquals;
 import java.lang.reflect.Method;
 
 import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.state.BlueprintProvisioningState;
+import org.easymock.Capture;
+import org.easymock.CaptureType;
 import org.easymock.EasyMockSupport;
 import org.junit.Before;
 import org.junit.Test;
@@ -68,6 +77,31 @@ public class UpgradeCatalog272Test {
   }
 
   @Test
+  public void testExecuteDDLUpdates() throws Exception {
+    dbAccessor.dropColumn(eq(CLUSTERS_TABLE), eq(BLUEPRINT_PROVISIONING_STATE_COLUMN));
+    expectLastCall().once();
+
+    Capture<DBAccessor.DBColumnInfo> blueprintProvisioningStateColumnCapture = newCapture(CaptureType.ALL);
+    dbAccessor.addColumn(eq(HOST_COMPONENT_DESIRED_STATE_TABLE), capture(blueprintProvisioningStateColumnCapture));
+    expectLastCall().once();
+
+    replay(dbAccessor, injector);
+
+    UpgradeCatalog272 upgradeCatalog272 = new UpgradeCatalog272(injector);
+    upgradeCatalog272.dbAccessor = dbAccessor;
+    upgradeCatalog272.executeDDLUpdates();
+
+    DBAccessor.DBColumnInfo capturedBlueprintProvisioningStateColumn =
+        blueprintProvisioningStateColumnCapture.getValue();
+    assertEquals(BLUEPRINT_PROVISIONING_STATE_COLUMN,
+        capturedBlueprintProvisioningStateColumn.getName());
+    assertEquals(BlueprintProvisioningState.NONE, capturedBlueprintProvisioningStateColumn.getDefaultValue());
+    assertEquals(String.class, capturedBlueprintProvisioningStateColumn.getType());
+
+    verify(dbAccessor);
+  }
+
+  @Test
   public void shouldRenameCollisionBehaviorLdapCategoryPropertyNameIfTableWithDataExists() throws Exception {
     final int expectedResult = 3;
     expect(dbAccessor.tableExists(AMBARI_CONFIGURATION_TABLE)).andReturn(true).once();
@@ -89,7 +123,7 @@ public class UpgradeCatalog272Test {
     assertEquals(expectedResult, upgradeCatalog272.renameLdapSynchCollisionBehaviorValue());
     verify(dbAccessor);
   }
-  
-  
+
+
 
 }