Repository: ambari
Updated Branches:
  refs/heads/trunk 501785fa5 -> 058dc168e


http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostResourceProvider.java
----------------------------------------------------------------------
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 c53eb78..d868320 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
@@ -38,6 +38,7 @@ import 
org.apache.ambari.server.controller.ConfigurationRequest;
 import org.apache.ambari.server.controller.HostRequest;
 import org.apache.ambari.server.controller.HostResponse;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
@@ -48,6 +49,7 @@ import 
org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 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.entities.BlueprintEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -55,19 +57,19 @@ import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
-import com.google.inject.persist.Transactional;
 
 
 /**
  * Resource provider for host resources.
  */
-public class HostResourceProvider extends AbstractControllerResourceProvider {
+public class HostResourceProvider extends BaseBlueprintProcessor {
 
   // ----- Property ID constants ---------------------------------------------
 
@@ -114,6 +116,13 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   protected static final String HOST_DESIRED_CONFIGS_PROPERTY_ID = 
       PropertyHelper.getPropertyId("Hosts", "desired_configs");
 
+  protected static final String BLUEPRINT_PROPERTY_ID =
+      PropertyHelper.getPropertyId(null, "blueprint");
+  protected static final String HOSTGROUP_PROPERTY_ID =
+      PropertyHelper.getPropertyId(null, "host_group");
+  protected static final String HOST_NAME_NO_CATEGORY_PROPERTY_ID =
+      PropertyHelper.getPropertyId(null, "host_name");
+
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
           HOST_NAME_PROPERTY_ID}));
@@ -140,31 +149,31 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   // ----- ResourceProvider ------------------------------------------------
 
   @Override
-  public RequestStatus createResources(Request request)
+  public RequestStatus createResources(final Request request)
       throws SystemException,
           UnsupportedPropertyException,
           ResourceAlreadyExistsException,
           NoSuchParentResourceException {
 
-    final Set<HostRequest> requests = new HashSet<HostRequest>();
-    for (Map<String, Object> propertyMap : request.getProperties()) {
-      requests.add(getRequest(propertyMap));
+    RequestStatusResponse createResponse = null;
+    if (isHostGroupRequest(request)) {
+      createResponse = addHostsUsingHostgroup(request);
+    } else {
+      createResources(new Command<Void>() {
+        @Override
+        public Void invoke() throws AmbariException {
+          createHosts(request);
+          return null;
+        }
+      });
     }
-    createResources(new Command<Void>() {
-      @Override
-      public Void invoke() throws AmbariException {
-        createHosts(requests);
-        return null;
-      }
-    });
 
     notifyCreate(Resource.Type.Host, request);
 
-    return getRequestStatus(null);
+    return getRequestStatus(createResponse);
   }
 
   @Override
-  @Transactional
   public Set<Resource> getResources(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException, 
NoSuchResourceException, NoSuchParentResourceException {
 
@@ -256,7 +265,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
     modifyResources(new Command<Void>() {
       @Override
       public Void invoke() throws AmbariException {
-        updateHosts(requests, request.getRequestInfoProperties());
+        updateHosts(requests);
         return null;
       }
     });
@@ -292,6 +301,10 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   public Set<String> checkPropertyIds(Set<String> propertyIds) {
     Set<String> baseUnsupported = super.checkPropertyIds(propertyIds);
 
+    baseUnsupported.remove(BLUEPRINT_PROPERTY_ID);
+    baseUnsupported.remove(HOSTGROUP_PROPERTY_ID);
+    baseUnsupported.remove(HOST_NAME_NO_CATEGORY_PROPERTY_ID);
+
     return checkConfigPropertyIds(baseUnsupported, "Hosts");
   }
 
@@ -307,6 +320,25 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   // ----- utility methods ---------------------------------------------------
 
   /**
+   * Determine if a request is a high level "add hosts" call or a simple lower 
level request
+   * to add a host resources.
+   *
+   * @param request  current request
+   * @return true if this is a high level "add hosts" request;
+   *         false if it is a simple create host resources request
+   */
+  private boolean isHostGroupRequest(Request request) {
+    boolean isHostGroupRequest = false;
+    Set<Map<String, Object>> properties = request.getProperties();
+    if (properties != null && ! properties.isEmpty()) {
+      //todo: for now, either all or none of the hosts need to specify a hg.  
Unable to mix.
+      String hgName = (String) 
properties.iterator().next().get(HOSTGROUP_PROPERTY_ID);
+      isHostGroupRequest = hgName != null && ! hgName.isEmpty();
+    }
+    return isHostGroupRequest;
+  }
+
+  /**
    * Get a host request object from a map of property values.
    *
    * @param properties  the predicate
@@ -320,11 +352,13 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
     }
 
     HostRequest hostRequest = new HostRequest(
-        (String) properties.get(HOST_NAME_PROPERTY_ID),
+        getHostNameFromProperties(properties),
         (String) properties.get(HOST_CLUSTER_NAME_PROPERTY_ID),
         null);
     hostRequest.setPublicHostName((String) 
properties.get(HOST_PUBLIC_NAME_PROPERTY_ID));
     hostRequest.setRackInfo((String) 
properties.get(HOST_RACK_INFO_PROPERTY_ID));
+    hostRequest.setBlueprintName((String) 
properties.get(BLUEPRINT_PROPERTY_ID));
+    hostRequest.setHostGroupName((String) 
properties.get(HOSTGROUP_PROPERTY_ID));
     
     Object o = properties.get(HOST_MAINTENANCE_STATE_PROPERTY_ID);
     if (null != o) {
@@ -342,14 +376,15 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
   /**
    * Accepts a request with registered hosts and if the request contains a 
cluster name then will map all of the
    * hosts onto that cluster.
-   * @param requests Request that must contain registered hosts, and 
optionally a cluster.
+   * @param request Request that must contain registered hosts, and optionally 
a cluster.
    * @throws AmbariException
    */
-  protected synchronized void createHosts(Set<HostRequest> requests)
+  protected synchronized void createHosts(Request request)
       throws AmbariException {
 
-    if (requests.isEmpty()) {
-      LOG.warn("Received an empty requests set");
+    Set<Map<String, Object>> propertySet = request.getProperties();
+    if (propertySet == null || propertySet.isEmpty()) {
+      LOG.warn("Received a create host request with no associated property 
sets");
       return;
     }
 
@@ -359,43 +394,14 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
     Set<String> duplicates = new HashSet<String>();
     Set<String> unknowns = new HashSet<String>();
     Set<String> allHosts = new HashSet<String>();
-    for (HostRequest request : requests) {
-      if (request.getHostname() == null
-          || request.getHostname().isEmpty()) {
-        throw new IllegalArgumentException("Invalid arguments, hostname"
-            + " cannot be null");
-      }
-
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Received a createHost request"
-            + ", hostname=" + request.getHostname()
-            + ", request=" + request);
-      }
 
-      if (allHosts.contains(request.getHostname())) {
-        // throw dup error later
-        duplicates.add(request.getHostname());
-        continue;
-      }
-      allHosts.add(request.getHostname());
 
-      try {
-        // ensure host is registered
-        clusters.getHost(request.getHostname());
-      }
-      catch (HostNotFoundException e) {
-        unknowns.add(request.getHostname());
-        continue;
-      }
-
-      if (request.getClusterName() != null) {
-        try {
-          // validate that cluster_name is valid
-          clusters.getCluster(request.getClusterName());
-        } catch (ClusterNotFoundException e) {
-          throw new ParentObjectNotFoundException("Attempted to add a host to 
a cluster which doesn't exist: "
-              + " clusterName=" + request.getClusterName());
-        }
+    Set<HostRequest> hostRequests = new HashSet<HostRequest>();
+    for (Map<String, Object> propertyMap : propertySet) {
+      HostRequest hostRequest = getRequest(propertyMap);
+      hostRequests.add(hostRequest);
+      if (! propertyMap.containsKey(HOSTGROUP_PROPERTY_ID)) {
+        createHostResource(clusters, duplicates, unknowns, allHosts, 
hostRequest);
       }
     }
 
@@ -431,22 +437,183 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
 
     Map<String, Set<String>> hostClustersMap = new HashMap<String, 
Set<String>>();
     Map<String, Map<String, String>> hostAttributes = new HashMap<String, 
Map<String, String>>();
-    for (HostRequest request : requests) {
-      if (request.getHostname() != null && !request.getHostname().isEmpty() && 
request.getClusterName() != null && !request.getClusterName().isEmpty()) {
+
+    for (HostRequest hostRequest : hostRequests) {
+      if (hostRequest.getHostname() != null &&
+          !hostRequest.getHostname().isEmpty() &&
+          hostRequest.getClusterName() != null &&
+          !hostRequest.getClusterName().isEmpty()){
+
         Set<String> clusterSet = new HashSet<String>();
-        clusterSet.add(request.getClusterName());
-        hostClustersMap.put(request.getHostname(), clusterSet);
-        if (request.getHostAttributes() != null) {
-          hostAttributes.put(request.getHostname(), 
request.getHostAttributes());
+        clusterSet.add(hostRequest.getClusterName());
+        hostClustersMap.put(hostRequest.getHostname(), clusterSet);
+        if (hostRequest.getHostAttributes() != null) {
+          hostAttributes.put(hostRequest.getHostname(), 
hostRequest.getHostAttributes());
         }
       }
     }
     clusters.updateHostWithClusterAndAttributes(hostClustersMap, 
hostAttributes);
   }
 
-
-  protected Set<HostResponse> getHosts(Set<HostRequest> requests)
+  private void createHostResource(Clusters clusters, Set<String> duplicates,
+                                  Set<String> unknowns, Set<String> allHosts,
+                                  HostRequest request)
       throws AmbariException {
+
+
+    if (request.getHostname() == null
+        || request.getHostname().isEmpty()) {
+      throw new IllegalArgumentException("Invalid arguments, hostname"
+          + " cannot be null");
+    }
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Received a createHost request"
+          + ", hostname=" + request.getHostname()
+          + ", request=" + request);
+    }
+
+    if (allHosts.contains(request.getHostname())) {
+      // throw dup error later
+      duplicates.add(request.getHostname());
+      return;
+    }
+    allHosts.add(request.getHostname());
+
+    try {
+      // ensure host is registered
+      clusters.getHost(request.getHostname());
+    }
+    catch (HostNotFoundException e) {
+      unknowns.add(request.getHostname());
+      return;
+    }
+
+    if (request.getClusterName() != null) {
+      try {
+        // validate that cluster_name is valid
+        clusters.getCluster(request.getClusterName());
+      } catch (ClusterNotFoundException e) {
+        throw new ParentObjectNotFoundException("Attempted to add a host to a 
cluster which doesn't exist: "
+            + " clusterName=" + request.getClusterName());
+      }
+    }
+  }
+
+
+  /**
+   * Add hosts based on a blueprint and hostgroup.  This will create the 
necessary resources and install/start all
+   * if the components on the hosts.
+   *
+   * @param request  add hosts request
+   * @return async request response
+   *
+   * @throws ResourceAlreadyExistsException  if an added host already exists 
in the cluster
+   * @throws SystemException                 in an unknown exception occurs
+   * @throws NoSuchParentResourceException   a parent resource doesnt exist
+   * @throws UnsupportedPropertyException    an unsupported property was 
specified for the request
+   */
+  private RequestStatusResponse addHostsUsingHostgroup(final Request request)
+      throws ResourceAlreadyExistsException,
+      SystemException,
+      NoSuchParentResourceException,
+      UnsupportedPropertyException {
+
+    //todo: idempotency of request.  Need to define failure models ...
+    Set<Map<String, Object>> propertySet = request.getProperties();
+    if (propertySet == null || propertySet.isEmpty()) {
+      LOG.warn("Received a create host request with no associated property 
sets");
+      return null;
+    }
+
+    Set<String> addedHosts = new HashSet<String>();
+    // all hosts will have same cluster
+    String clusterName = null;
+    for (Map<String, Object> properties : propertySet) {
+      clusterName = (String) properties.get(HOST_CLUSTER_NAME_PROPERTY_ID);
+      String bpName = (String) properties.get(BLUEPRINT_PROPERTY_ID);
+      String hgName = (String) properties.get(HOSTGROUP_PROPERTY_ID);
+      String hostname = getHostNameFromProperties(properties);
+
+      addedHosts.add(hostname);
+
+      String configGroupName = getConfigurationGroupName(bpName, hgName);
+      BlueprintEntity blueprint = getExistingBlueprint(bpName);
+      Stack stack = parseStack(blueprint);
+      Map<String, HostGroupImpl> blueprintHostGroups = 
parseBlueprintHostGroups(blueprint, stack);
+      addHostToHostgroup(hgName, hostname, blueprintHostGroups);
+      createHostAndComponentResources(blueprintHostGroups, clusterName, this);
+      //todo: optimize: update once per hostgroup with added hosts
+      addHostToExistingConfigGroups(configGroupName, clusterName, hostname);
+    }
+    return ((HostComponentResourceProvider) 
getResourceProvider(Resource.Type.HostComponent)).
+        installAndStart(clusterName, addedHosts);
+  }
+
+  /**
+   * Add the new host to an existing config group.
+   *
+   * @param configGroupName  name of the config group
+   * @param clusterName      cluster name
+   * @param hostName         host name
+   *
+   * @throws SystemException                an unknown exception occurred
+   * @throws UnsupportedPropertyException   an unsupported property was 
specified in the request
+   * @throws NoSuchParentResourceException  a parent resource doesn't exist
+   */
+  private void addHostToExistingConfigGroups(String configGroupName, String 
clusterName, String hostName)
+      throws SystemException,
+      UnsupportedPropertyException,
+      NoSuchParentResourceException {
+
+    Clusters clusters;
+    Cluster cluster;
+    try {
+      clusters = getManagementController().getClusters();
+      cluster = clusters.getCluster(clusterName);
+    } catch (AmbariException e) {
+      throw new IllegalArgumentException(
+          String.format("Attempt to add hosts to a non-existent cluster: 
'%s'", clusterName));
+    }
+    Map<Long, ConfigGroup> configGroups = cluster.getConfigGroups();
+    for (ConfigGroup group : configGroups.values()) {
+      if (group.getName().equals(configGroupName)) {
+        try {
+          group.addHost(clusters.getHost(hostName));
+          group.persist();
+        } catch (AmbariException e) {
+          // shouldn't occur, this host was just added to the cluster
+          throw new SystemException(String.format(
+              "Unable to obtain newly created host '%s' from cluster '%s'", 
hostName, clusterName));
+        }
+      }
+    }
+  }
+
+  /**
+   * Associate a host with a host group.
+   *
+   * @param hostGroupName        name of host group
+   * @param hostname             host name
+   * @param blueprintHostGroups  map of host group name to host group
+   *
+   * @throws IllegalArgumentException if the specified host group doesn't exist
+   */
+  private void addHostToHostgroup(String hostGroupName, String hostname, 
Map<String, HostGroupImpl> blueprintHostGroups)
+      throws IllegalArgumentException {
+
+    HostGroupImpl hostGroup = blueprintHostGroups.get(hostGroupName);
+    if (hostGroup == null) {
+      // this case should have been caught sooner
+      throw new IllegalArgumentException(String.format("Invalid host_group 
specified '%s'. " +
+          "All request host groups must have a corresponding host group in the 
specified blueprint", hostGroupName));
+    }
+
+    hostGroup.addHostInfo(hostname);
+  }
+
+
+  protected Set<HostResponse> getHosts(Set<HostRequest> requests) throws 
AmbariException {
     Set<HostResponse> response = new HashSet<HostResponse>();
 
     AmbariManagementController controller = getManagementController();
@@ -529,9 +696,7 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
     return response;
   }
 
-  protected synchronized void updateHosts(Set<HostRequest> requests,
-      Map<String, String> requestProperties)
-      throws AmbariException {
+  protected synchronized void updateHosts(Set<HostRequest> requests) throws 
AmbariException {
 
     if (requests.isEmpty()) {
       LOG.warn("Received an empty requests set");
@@ -541,20 +706,15 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
     AmbariManagementController controller = getManagementController();
     Clusters                   clusters   = controller.getClusters();
 
-    // We don't expect batch requests for different clusters, that's why
-    // nothing bad should happen if value is overwritten few times
-    String maintenanceCluster = null;
-
     for (HostRequest request : requests) {
       if (request.getHostname() == null || request.getHostname().isEmpty()) {
         throw new IllegalArgumentException("Invalid arguments, hostname should 
be provided");
       }
     }
 
-
     for (HostRequest request : requests) {
       if (LOG.isDebugEnabled()) {
-        LOG.debug("Received a updateHost request"
+        LOG.debug("Received an updateHost request"
             + ", hostname=" + request.getHostname()
             + ", request=" + request);
       }
@@ -592,7 +752,6 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
               "maintenance state to one of " + 
EnumSet.of(MaintenanceState.OFF, MaintenanceState.ON));
           } else {
             h.setMaintenanceState(c.getClusterId(), newState);
-            maintenanceCluster = c.getClusterName();
           }
         }
       }
@@ -710,4 +869,21 @@ public class HostResourceProvider extends 
AbstractControllerResourceProvider {
       }
     }
   }
+
+  /**
+   * Obtain the hostname from the request properties.  The hostname property 
name may differ
+   * depending on the request type.  For the low level host resource creation 
calls, it is always
+   * "Hosts/host_name".  For multi host "add host from hostgroup", the 
hostname property is a top level
+   * property "host_name".
+   *
+   * @param properties  request properties
+   *
+   * @return the host name for the host request
+   */
+  private String getHostNameFromProperties(Map<String, Object> properties) {
+    String hostname = (String) properties.get(HOST_NAME_PROPERTY_ID);
+
+    return hostname != null ? hostname :
+        (String) properties.get(HOST_NAME_NO_CATEGORY_PROPERTY_ID);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
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 945a4db..125b71b 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
@@ -341,11 +341,10 @@ public interface Cluster {
   public void addConfigGroup(ConfigGroup configGroup) throws AmbariException;
 
   /**
-   * Get all config groups associated with this cluster
-   * @return
-   * @throws AmbariException
+   * Get config groups associated with this cluster
+   * @return unmodifiable map of config group id to config group.  Will not 
return null.
    */
-  public Map<Long, ConfigGroup> getConfigGroups() throws AmbariException;
+  public Map<Long, ConfigGroup> getConfigGroups();
 
   /**
    * Delete this config group identified by the config group id

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
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 e3f6d4b..5a9731a 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
@@ -483,7 +483,7 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
-  public Map<Long, ConfigGroup> getConfigGroups() throws AmbariException {
+  public Map<Long, ConfigGroup> getConfigGroups() {
     loadConfigGroups();
     clusterGlobalLock.readLock().lock();
     try {

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 1f57397..75e0868 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -77,6 +77,7 @@ import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import 
org.apache.ambari.server.controller.internal.ComponentResourceProviderTest;
+import 
org.apache.ambari.server.controller.internal.HostComponentResourceProviderTest;
 import org.apache.ambari.server.controller.internal.HostResourceProviderTest;
 import org.apache.ambari.server.controller.internal.RequestOperationLevel;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
@@ -365,7 +366,7 @@ public class AmbariManagementControllerTest {
   }
 
   private long stopServiceComponentHosts(String clusterName,
-      String serviceName) throws AmbariException {
+      String serviceName) throws Exception {
     Cluster c = clusters.getCluster(clusterName);
     Service s = c.getService(serviceName);
     Set<ServiceComponentHostRequest> requests = new
@@ -380,8 +381,8 @@ public class AmbariManagementControllerTest {
     }
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
-    RequestStatusResponse resp = controller.updateHostComponents(requests,
-      mapRequestProps, false);
+    RequestStatusResponse resp = 
HostComponentResourceProviderTest.updateHostComponents(controller, injector, 
requests,
+        mapRequestProps, false);
 
     // manually change live state to started as no running action manager
     for (ServiceComponent sc :
@@ -1505,16 +1506,11 @@ public class AmbariManagementControllerTest {
     clusters.getHost("h2").persist();
     clusters.getHost("h3").persist();
 
-    Map<String, String> hostAttrs =
-        new HashMap<String, String>();
-    hostAttrs.put("attr1", "val1");
-    hostAttrs.put("attr2", "val2");
-
-    String clusterName = "c1";
+   String clusterName = "c1";
 
     HostRequest r1 = new HostRequest("h1", clusterName, null);
-    HostRequest r2 = new HostRequest("h2", clusterName, hostAttrs);
-    HostRequest r3 = new HostRequest("h3", null, hostAttrs);
+    HostRequest r2 = new HostRequest("h2", clusterName, null);
+    HostRequest r3 = new HostRequest("h3", null, null);
 
     Set<HostRequest> set1 = new HashSet<HostRequest>();
     set1.add(r1);
@@ -1525,13 +1521,6 @@ public class AmbariManagementControllerTest {
     Assert.assertEquals(1, clusters.getClustersForHost("h1").size());
     Assert.assertEquals(1, clusters.getClustersForHost("h2").size());
     Assert.assertEquals(0, clusters.getClustersForHost("h3").size());
-
-    Assert.assertEquals(4, clusters.getHost("h2").getHostAttributes().size());
-    Assert.assertEquals(2, clusters.getHost("h3").getHostAttributes().size());
-    Assert.assertEquals("val1",
-        clusters.getHost("h2").getHostAttributes().get("attr1"));
-    Assert.assertEquals("val2",
-        clusters.getHost("h2").getHostAttributes().get("attr2"));
   }
 
   @Test
@@ -2334,7 +2323,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testServiceComponentHostsWithDecommissioned() throws 
AmbariException {
+  public void testServiceComponentHostsWithDecommissioned() throws Exception {
 
     final String host1 = "h1";
     final String host2 = "h2";
@@ -2408,7 +2397,7 @@ public class AmbariManagementControllerTest {
     r = new ServiceComponentHostRequest(clusterName, "HDFS", "DATANODE", 
host2, null);
     r.setAdminState("DECOMMISSIONED");
     try {
-      controller.updateHostComponents(Collections.singleton(r), new 
HashMap<String, String>(), false);
+      updateHostComponents(Collections.singleton(r), new HashMap<String, 
String>(), false);
       Assert.fail("Must throw exception when decommission attribute is 
updated.");
     } catch (IllegalArgumentException ex) {
       Assert.assertTrue(ex.getMessage().contains("Property adminState cannot 
be modified through update"));
@@ -3363,7 +3352,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testServiceComponentHostUpdateRecursive() throws AmbariException 
{
+  public void testServiceComponentHostUpdateRecursive() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     String serviceName1 = "HDFS";
@@ -3444,7 +3433,7 @@ public class AmbariManagementControllerTest {
           componentName1, host1,
           State.STARTED.toString());
       reqs.add(req1);
-      controller.updateHostComponents(reqs, Collections.<String, 
String>emptyMap(), true);
+      updateHostComponents(reqs, Collections.<String, String>emptyMap(), true);
       fail("Expected failure for invalid transition");
     } catch (Exception e) {
       // Expected
@@ -3472,7 +3461,7 @@ public class AmbariManagementControllerTest {
       reqs.add(req3);
       reqs.add(req4);
       reqs.add(req5);
-      controller.updateHostComponents(reqs, Collections.<String, 
String>emptyMap(), true);
+      updateHostComponents(reqs, Collections.<String, String>emptyMap(), true);
       fail("Expected failure for invalid states");
     } catch (Exception e) {
       // Expected
@@ -3494,7 +3483,7 @@ public class AmbariManagementControllerTest {
     reqs.add(req3);
     reqs.add(req4);
     reqs.add(req5);
-    RequestStatusResponse trackAction = controller.updateHostComponents(reqs,
+    RequestStatusResponse trackAction = updateHostComponents(reqs,
         Collections.<String, String>emptyMap(), true);
     Assert.assertNotNull(trackAction);
 
@@ -3527,14 +3516,14 @@ public class AmbariManagementControllerTest {
         State.INSTALLED.toString());
     reqs.add(req1);
     reqs.add(req2);
-    trackAction = controller.updateHostComponents(reqs, Collections.<String,
+    trackAction = updateHostComponents(reqs, Collections.<String,
         String>emptyMap(), true);
     Assert.assertNull(trackAction);
   }
 
   @Ignore
   @Test
-  public void testServiceComponentHostUpdateStackId() throws AmbariException {
+  public void testServiceComponentHostUpdateStackId() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     String serviceName1 = "HDFS";
@@ -3614,7 +3603,7 @@ public class AmbariManagementControllerTest {
     Map<String,String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "testServiceComponentHostUpdateStackId");
 
-    RequestStatusResponse resp = controller.updateHostComponents(reqs, 
mapRequestProps, true);
+    RequestStatusResponse resp = updateHostComponents(reqs, mapRequestProps, 
true);
     List<Stage> stages = actionDB.getAllStages(resp.getRequestId());
     Assert.assertEquals(1, stages.size());
     Assert.assertEquals(2, stages.get(0).getOrderedHostRoleCommands().size());
@@ -3659,7 +3648,7 @@ public class AmbariManagementControllerTest {
     req3.setDesiredStackId("HDP-0.2");
     reqs.add(req3);
 
-    resp = controller.updateHostComponents(reqs, Collections.<String, 
String>emptyMap(), true);
+    resp = updateHostComponents(reqs, Collections.<String, String>emptyMap(), 
true);
     stages = actionDB.getAllStages(resp.getRequestId());
     Assert.assertEquals(2, stages.size());
     Assert.assertEquals(2, stages.get(0).getOrderedHostRoleCommands().size());
@@ -3687,7 +3676,7 @@ public class AmbariManagementControllerTest {
 
   @Ignore
   @Test
-  public void testServiceComponentHostUpdateStackIdError() throws 
AmbariException {
+  public void testServiceComponentHostUpdateStackIdError() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     String serviceName1 = "HDFS";
@@ -3818,7 +3807,7 @@ public class AmbariManagementControllerTest {
     req1.setDesiredStackId("HDP-0.2");
     reqs.add(req1);
 
-    RequestStatusResponse resp = controller.updateHostComponents(reqs,
+    RequestStatusResponse resp = updateHostComponents(reqs,
         Collections.<String,String>emptyMap(), true);
     Assert.assertNull(resp);
 
@@ -3831,14 +3820,14 @@ public class AmbariManagementControllerTest {
         State.INSTALLED.toString());
     req1.setDesiredStackId("HDP-0.2");
     reqs.add(req1);
-    resp = controller.updateHostComponents(reqs, 
Collections.<String,String>emptyMap(), true);
+    resp = updateHostComponents(reqs, Collections.<String,String>emptyMap(), 
true);
     Assert.assertNull(resp);
   }
 
   private void 
updateHostAndCompareExpectedFailure(Set<ServiceComponentHostRequest> reqs,
                                                    String expectedMessage) {
     try {
-      controller.updateHostComponents(reqs, 
Collections.<String,String>emptyMap(), true);
+      updateHostComponents(reqs, Collections.<String,String>emptyMap(), true);
       fail("Expected failure: " + expectedMessage);
     } catch (Exception e) {
       LOG.info("Actual exception message: " + e.getMessage());
@@ -4758,7 +4747,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
             componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     configVersions.clear();
     configVersions.put("typeC", "v1");
@@ -4785,7 +4774,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
             componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     // update configs at SC level
     configVersions.clear();
@@ -4799,7 +4788,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testConfigUpdates() throws AmbariException {
+  public void testConfigUpdates() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -4906,7 +4895,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
         componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     configVersions.clear();
     configVersions.put("typeC", "v1");
@@ -4933,7 +4922,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
         componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     // update configs at SC level
     configVersions.clear();
@@ -5042,7 +5031,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
       componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     // Reconfigure SCH level
     configVersions.clear();
@@ -5050,7 +5039,7 @@ public class AmbariManagementControllerTest {
     schReqs.clear();
     schReqs.add(new ServiceComponentHostRequest(clusterName, serviceName,
       componentName1, host1, null));
-    Assert.assertNull(controller.updateHostComponents(schReqs, 
Collections.<String, String>emptyMap(), true));
+    Assert.assertNull(updateHostComponents(schReqs, Collections.<String, 
String>emptyMap(), true));
 
     // Clear Entity Manager
     entityManager.clear();
@@ -5284,8 +5273,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testReconfigureClientWithServiceStarted() throws
-    AmbariException {
+  public void testReconfigureClientWithServiceStarted() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -5774,7 +5762,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testReInstallClientComponent() throws AmbariException {
+  public void testReInstallClientComponent() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -5818,7 +5806,7 @@ public class AmbariManagementControllerTest {
     Set<ServiceComponentHostRequest> setReqs = new
       HashSet<ServiceComponentHostRequest>();
     setReqs.add(schr);
-    RequestStatusResponse resp = controller.updateHostComponents(setReqs,
+    RequestStatusResponse resp = updateHostComponents(setReqs,
       Collections.<String, String>emptyMap(), false);
 
     Assert.assertNotNull(resp);
@@ -5960,7 +5948,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testDecommissonDatanodeAction() throws AmbariException {
+  public void testDecommissonDatanodeAction() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -6087,13 +6075,13 @@ public class AmbariManagementControllerTest {
         componentName1, host2, State.INSTALLED.toString());
     Set<ServiceComponentHostRequest> requests = new 
HashSet<ServiceComponentHostRequest>();
     requests.add(r);
-    controller.updateHostComponents(requests, Collections.<String, 
String>emptyMap(), true);
+    updateHostComponents(requests, Collections.<String, String>emptyMap(), 
true);
     
s.getServiceComponent(componentName1).getServiceComponentHost(host2).setState(State.INSTALLED);
     r = new ServiceComponentHostRequest(clusterName, serviceName,
         componentName1, host2, State.STARTED.toString());
     requests.clear();
     requests.add(r);
-    controller.updateHostComponents(requests, Collections.<String, 
String>emptyMap(), true);
+    updateHostComponents(requests, Collections.<String, String>emptyMap(), 
true);
     
s.getServiceComponent(componentName1).getServiceComponentHost(host2).setState(State.STARTED);
 
     params = new HashMap<String, String>(){{
@@ -7616,7 +7604,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testServiceStopWhileStopping() throws AmbariException {
+  public void testServiceStopWhileStopping() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -7733,7 +7721,7 @@ public class AmbariManagementControllerTest {
           Set<ServiceComponentHostRequest> reqs1 = new
             HashSet<ServiceComponentHostRequest>();
           reqs1.add(r1);
-          controller.updateHostComponents(reqs1, Collections.<String, 
String>emptyMap(), true);
+          updateHostComponents(reqs1, Collections.<String, String>emptyMap(), 
true);
           Assert.assertEquals(State.INSTALLED, sch.getDesiredState());
         }
       }
@@ -7890,7 +7878,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testUpdateHostComponentsBadState() throws AmbariException {
+  public void testUpdateHostComponentsBadState() throws Exception {
     String clusterName = "foo1";
     createCluster(clusterName);
     clusters.getCluster(clusterName)
@@ -7971,7 +7959,7 @@ public class AmbariManagementControllerTest {
     Map<String, String> requestProps = new HashMap<String, String>();
     requestProps.put("datanode", "dn_value");
     requestProps.put("namenode", "nn_value");
-    RequestStatusResponse rsr = 
controller.updateHostComponents(Collections.singleton(schr), requestProps, 
false);
+    RequestStatusResponse rsr = 
updateHostComponents(Collections.singleton(schr), requestProps, false);
 
     List<Stage> stages = actionDB.getAllStages(rsr.getRequestId());
     Assert.assertEquals(1, stages.size());
@@ -7988,7 +7976,6 @@ public class AmbariManagementControllerTest {
     for (ServiceComponentHost sch : 
clusters.getCluster(clusterName).getServiceComponentHosts(host2)) {
       Assert.assertEquals(State.UNKNOWN, sch.getState());
     }
-
   }
 
   @Test
@@ -8452,7 +8439,7 @@ public class AmbariManagementControllerTest {
     // disable HC for non-clients
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, 
componentName1, host1, "DISABLED"));
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, 
componentName2, host1, "DISABLED"));
-    controller.updateHostComponents(schRequests, new HashMap<String,String>(), 
false);
+    updateHostComponents(schRequests, new HashMap<String,String>(), false);
 
     // delete HC
     schRequests.clear();
@@ -8635,7 +8622,7 @@ public class AmbariManagementControllerTest {
     schRequests.clear();
     // disable HC, DN was already stopped
     schRequests.add(new ServiceComponentHostRequest(clusterName, serviceName, 
componentName1, host1, "DISABLED"));
-    controller.updateHostComponents(schRequests, new HashMap<String,String>(), 
false);
+    updateHostComponents(schRequests, new HashMap<String,String>(), false);
 
     // delete HC
     schRequests.clear();
@@ -9003,21 +8990,21 @@ public class AmbariManagementControllerTest {
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"NAMENODE", "host1", "DISABLED"));
 
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, true);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, true);
 
       Assert.assertEquals(State.DISABLED, componentHost.getState());
 
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"NAMENODE", "host1", "INSTALLED"));
 
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, true);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, true);
 
       Assert.assertEquals(State.INSTALLED, componentHost.getState());
 
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"NAMENODE", "host1", "DISABLED"));
 
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, true);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, true);
 
       Assert.assertEquals(State.DISABLED, componentHost.getState());
 
@@ -9029,7 +9016,7 @@ public class AmbariManagementControllerTest {
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"NAMENODE", "host2", "INSTALLED"));
 
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, true);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, true);
 
       namenodes = 
cluster.getService("HDFS").getServiceComponent("NAMENODE").getServiceComponentHosts();
       Assert.assertEquals(2, namenodes.size());
@@ -9071,7 +9058,7 @@ public class AmbariManagementControllerTest {
       componentHost.handleEvent(new 
ServiceComponentHostOpSucceededEvent(componentHost.getServiceComponentName(), 
componentHost.getHostName(), System.currentTimeMillis()));
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"NAMENODE", "host1", "INSTALLED"));
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, true);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, true);
       assertEquals(State.INSTALLED, namenodes.get("host1").getState());
 
       // make unknown
@@ -9087,7 +9074,7 @@ public class AmbariManagementControllerTest {
       // make disabled
       componentHostRequests.clear();
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, 
"DATANODE", "host2", "DISABLED"));
-      amc.updateHostComponents(componentHostRequests, mapRequestProps, false);
+      updateHostComponents(amc, componentHostRequests, mapRequestProps, false);
       org.junit.Assert.assertEquals(State.DISABLED, sch.getState());
 
       // ServiceComponentHost remains in disabled after service stop
@@ -9770,8 +9757,8 @@ public class AmbariManagementControllerTest {
     // passivate a host
     HostRequest hr = new HostRequest(host1, clusterName, requestProperties);
     hr.setMaintenanceState(MaintenanceState.ON.name());
-    HostResourceProviderTest.updateHosts(controller, Collections.singleton(hr),
-        new HashMap<String, String>());
+    HostResourceProviderTest.updateHosts(controller, Collections.singleton(hr)
+    );
 
     Host host = hosts.get(host1);
     Assert.assertEquals(MaintenanceState.ON,
@@ -9793,8 +9780,8 @@ public class AmbariManagementControllerTest {
 
     // reset
     hr.setMaintenanceState(MaintenanceState.OFF.name());
-    HostResourceProviderTest.updateHosts(controller, Collections.singleton(hr),
-        new HashMap<String, String>());
+    HostResourceProviderTest.updateHosts(controller, Collections.singleton(hr)
+    );
 
     host = hosts.get(host1);
     Assert.assertEquals(MaintenanceState.OFF,
@@ -9817,8 +9804,8 @@ public class AmbariManagementControllerTest {
     Set<HostRequest> set = new HashSet<HostRequest>();
     set.add(hr1);
     set.add(hr2);
-    HostResourceProviderTest.updateHosts(controller, set,
-        new HashMap<String, String>());
+    HostResourceProviderTest.updateHosts(controller, set
+    );
 
     host = hosts.get(host1);
     Assert.assertEquals(MaintenanceState.ON,
@@ -9836,8 +9823,8 @@ public class AmbariManagementControllerTest {
     set.add(hr1);
     set.add(hr2);
 
-    HostResourceProviderTest.updateHosts(controller, set,
-        new HashMap<String, String>());
+    HostResourceProviderTest.updateHosts(controller, set
+    );
     host = hosts.get(host1);
     Assert.assertEquals(MaintenanceState.OFF,
         host.getMaintenanceState(cluster.getClusterId()));
@@ -10334,7 +10321,7 @@ public class AmbariManagementControllerTest {
 
     Map<String, String> requestProperties = new HashMap<String, String>();
     requestProperties.put("namenode", "p1");
-    RequestStatusResponse resp = 
controller.updateHostComponents(Collections.singleton(req), requestProperties, 
false);
+    RequestStatusResponse resp = 
updateHostComponents(Collections.singleton(req), requestProperties, false);
 
     // succeed in creating a task
     assertNotNull(resp);
@@ -10346,15 +10333,33 @@ public class AmbariManagementControllerTest {
     }
 
     // no new commands since no targeted info
-    resp = controller.updateHostComponents(Collections.singleton(req), new 
HashMap<String, String>(), false);
+    resp = updateHostComponents(Collections.singleton(req), new 
HashMap<String, String>(), false);
     assertNull(resp);
 
     // role commands added for targeted command
-    resp = controller.updateHostComponents(Collections.singleton(req), 
requestProperties, false);
+    resp = updateHostComponents(Collections.singleton(req), requestProperties, 
false);
     assertNotNull(resp);
 
   }
 
+  // this is a temporary measure as a result of moving updateHostComponents 
from AmbariManagementController
+  // to HostComponentResourceProvider.  Eventually the tests should be moved 
out of this class.
+  private RequestStatusResponse 
updateHostComponents(Set<ServiceComponentHostRequest> requests,
+                                                     Map<String, String> 
requestProperties,
+                                                     boolean runSmokeTest) 
throws Exception {
+
+    return updateHostComponents(controller, requests, requestProperties, 
runSmokeTest);
+  }
+
+  private RequestStatusResponse 
updateHostComponents(AmbariManagementController controller,
+                                                     
Set<ServiceComponentHostRequest> requests,
+                                                     Map<String, String> 
requestProperties,
+                                                     boolean runSmokeTest) 
throws Exception {
+
+    return HostComponentResourceProviderTest.updateHostComponents(
+        controller, injector, requests, requestProperties, runSmokeTest);
+  }
+
 
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
index f7149a8..f382588 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
@@ -420,6 +420,7 @@ public class ClusterResourceProviderTest {
     
expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
     expect(hostGroup.getName()).andReturn("group1").anyTimes();
     
expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
+    expect(hostGroup.getBlueprintName()).andReturn(blueprintName).anyTimes();
     expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
     expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
     expect(hostGroupComponent3.getName()).andReturn("component3").anyTimes();
@@ -634,7 +635,7 @@ public class ClusterResourceProviderTest {
     assertEquals(1, configGroupRequests.size());
     ConfigGroupRequest configGroupRequest = 
configGroupRequests.iterator().next();
     assertEquals(clusterName, configGroupRequest.getClusterName());
-    assertEquals("group1", configGroupRequest.getGroupName());
+    assertEquals(blueprintName + ":group1", configGroupRequest.getGroupName());
     assertEquals("service1", configGroupRequest.getTag());
     assertEquals("Host Group Configuration", 
configGroupRequest.getDescription());
     Set<String> hosts = configGroupRequest.getHosts();
@@ -1688,6 +1689,7 @@ public class ClusterResourceProviderTest {
 
     
expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
     expect(hostGroup.getName()).andReturn("group1").anyTimes();
+    expect(hostGroup.getBlueprintName()).andReturn(blueprintName).anyTimes();
     
expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
     expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
     expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
@@ -1886,7 +1888,7 @@ public class ClusterResourceProviderTest {
     assertEquals(1, configGroupRequests.size());
     ConfigGroupRequest configGroupRequest = 
configGroupRequests.iterator().next();
     assertEquals(clusterName, configGroupRequest.getClusterName());
-    assertEquals("group1", configGroupRequest.getGroupName());
+    assertEquals(blueprintName + ":group1", configGroupRequest.getGroupName());
     assertEquals("service1", configGroupRequest.getTag());
     assertEquals("Host Group Configuration", 
configGroupRequest.getDescription());
     Set<String> hosts = configGroupRequest.getHosts();
@@ -2392,6 +2394,7 @@ public class ClusterResourceProviderTest {
 
     
expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
     expect(hostGroup.getName()).andReturn("group1").anyTimes();
+    expect(hostGroup.getBlueprintName()).andReturn(blueprintName).anyTimes();
     
expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
     expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
     expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
@@ -2616,7 +2619,7 @@ public class ClusterResourceProviderTest {
     assertEquals(1, configGroupRequests.size());
     ConfigGroupRequest configGroupRequest = 
configGroupRequests.iterator().next();
     assertEquals(clusterName, configGroupRequest.getClusterName());
-    assertEquals("group1", configGroupRequest.getGroupName());
+    assertEquals(blueprintName + ":group1", configGroupRequest.getGroupName());
     assertEquals("service1", configGroupRequest.getTag());
     assertEquals("Host Group Configuration", 
configGroupRequest.getDescription());
     Set<String> hosts = configGroupRequest.getHosts();

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
index abe30cc..0ffc6e1 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
@@ -19,30 +19,40 @@
 package org.apache.ambari.server.controller.internal;
 
 import com.google.inject.Injector;
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.MaintenanceStateHelper;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
 import org.apache.ambari.server.controller.spi.Predicate;
 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.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.state.cluster.ClustersImpl;
 import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -53,6 +63,9 @@ import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 /**
  * HostComponentResourceProvider tests.
@@ -241,6 +254,14 @@ public class HostComponentResourceProviderTest {
     RequestStatusResponse response = 
createNiceMock(RequestStatusResponse.class);
     ResourceProviderFactory resourceProviderFactory = 
createNiceMock(ResourceProviderFactory.class);
     Injector injector = createNiceMock(Injector.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service = createNiceMock(Service.class);
+    ServiceComponent component = createNiceMock(ServiceComponent.class);
+    ServiceComponentHost componentHost = 
createNiceMock(ServiceComponentHost.class);
+    RequestStageContainer stageContainer = 
createNiceMock(RequestStageContainer.class);
+    MaintenanceStateHelper maintenanceStateHelper = 
createNiceMock(MaintenanceStateHelper.class);
+
 
     Map<String, String> mapRequestProps = new HashMap<String, String>();
     mapRequestProps.put("context", "Called from a test");
@@ -248,27 +269,49 @@ public class HostComponentResourceProviderTest {
     Set<ServiceComponentHostResponse> nameResponse = new 
HashSet<ServiceComponentHostResponse>();
     nameResponse.add(new ServiceComponentHostResponse(
         "Cluster102", "Service100", "Component100", "Host100", "STARTED", "", 
"", "", null));
-    
-    HostComponentResourceProvider provider = 
-        new HostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController, injector);
 
     // set expectations
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    expect(managementController.findServiceName(cluster, 
"Component100")).andReturn("Service100").anyTimes();
+    expect(clusters.getCluster("Cluster102")).andReturn(cluster).anyTimes();
+    expect(cluster.getService("Service100")).andReturn(service).anyTimes();
+    
expect(service.getServiceComponent("Component100")).andReturn(component).anyTimes();
+    
expect(component.getServiceComponentHost("Host100")).andReturn(componentHost).anyTimes();
+    expect(component.getName()).andReturn("Component100").anyTimes();
+    expect(componentHost.getState()).andReturn(State.INSTALLED).anyTimes();
+    expect(response.getMessage()).andReturn("response msg").anyTimes();
+    expect(response.getRequestId()).andReturn(1000L);
+
+    //Cluster is default type.  Maintenance mode is not being tested here so 
the default is returned.
+    expect(maintenanceStateHelper.isOperationAllowed(Resource.Type.Cluster, 
componentHost)).andReturn(true).anyTimes();
+
     expect(managementController.getHostComponents(
         
EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse).once();
-    expect(managementController.updateHostComponents(
-        AbstractResourceProviderTest.Matcher.getHostComponentRequestSet(
-            "Cluster102", "Service100", "Component100", "Host100", null, 
"STARTED"),
-            eq(mapRequestProps), eq(false))).andReturn(response).once();
-    
+
+    Map<String, Map<State, List<ServiceComponentHost>>> changedHosts = new 
HashMap<String, Map<State, List<ServiceComponentHost>>>();
+    List<ServiceComponentHost> changedComponentHosts = new 
ArrayList<ServiceComponentHost>();
+    changedComponentHosts.add(componentHost);
+    changedHosts.put("Component100", Collections.singletonMap(State.STARTED, 
changedComponentHosts));
+
+    expect(managementController.addStages(null, cluster, mapRequestProps, 
null, null, null, changedHosts,
+        Collections.<ServiceComponentHost>emptyList(), false, 
false)).andReturn(stageContainer).once();
+
+    stageContainer.persist();
+    
expect(stageContainer.getRequestStatusResponse()).andReturn(response).once();
+
+    HostComponentResourceProvider provider =
+        new 
TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            managementController, injector, maintenanceStateHelper);
+
     
expect(resourceProviderFactory.getHostComponentResourceProvider(anyObject(Set.class),
         anyObject(Map.class),
         eq(managementController))).
         andReturn(provider).anyTimes();
 
     // replay
-    replay(managementController, response, resourceProviderFactory);
+    replay(managementController, response, resourceProviderFactory, clusters, 
cluster, service,
+        component, componentHost, stageContainer, maintenanceStateHelper);
 
     Map<String, Object> properties = new LinkedHashMap<String, Object>();
 
@@ -279,11 +322,116 @@ public class HostComponentResourceProviderTest {
 
     // update the cluster named Cluster102
     Predicate predicate = new PredicateBuilder().property(
-        
HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
-    provider.updateResources(request, predicate);
+        
HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").and().
+        
property(HostComponentResourceProvider.HOST_COMPONENT_HOST_NAME_PROPERTY_ID).equals("Host100").and().
+        
property(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("Component100").toPredicate();
+    RequestStatus requestStatus = provider.updateResources(request, predicate);
+    Resource responseResource = requestStatus.getRequestResource();
+    assertEquals("response msg", 
responseResource.getPropertyValue(PropertyHelper.getPropertyId("Requests", 
"message")));
+    assertEquals(1000L, 
responseResource.getPropertyValue(PropertyHelper.getPropertyId("Requests", 
"id")));
+    assertEquals("InProgress", 
responseResource.getPropertyValue(PropertyHelper.getPropertyId("Requests", 
"status")));
+    assertTrue(requestStatus.getAssociatedResources().isEmpty());
 
     // verify
-    verify(managementController, response, resourceProviderFactory);
+    verify(managementController, response, resourceProviderFactory, 
stageContainer);
+  }
+
+  @Test
+  public void testInstallAndStart() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = 
createMock(AmbariManagementController.class);
+    RequestStatusResponse response = 
createNiceMock(RequestStatusResponse.class);
+    ResourceProviderFactory resourceProviderFactory = 
createNiceMock(ResourceProviderFactory.class);
+    Injector injector = createNiceMock(Injector.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service = createNiceMock(Service.class);
+    ServiceComponent component = createNiceMock(ServiceComponent.class);
+    ServiceComponentHost componentHost = 
createNiceMock(ServiceComponentHost.class);
+    RequestStageContainer stageContainer = 
createNiceMock(RequestStageContainer.class);
+    MaintenanceStateHelper maintenanceStateHelper = 
createNiceMock(MaintenanceStateHelper.class);
+
+    Collection<String> hosts = new HashSet<String>();
+    hosts.add("Host100");
+
+    Map<String, String> mapRequestProps = new HashMap<String, String>();
+    mapRequestProps.put("context", "Install and start components on added 
hosts");
+
+    Set<ServiceComponentHostResponse> nameResponse = new 
HashSet<ServiceComponentHostResponse>();
+    nameResponse.add(new ServiceComponentHostResponse(
+        "Cluster102", "Service100", "Component100", "Host100", "INIT", "", 
"INIT", "", null));
+    Set<ServiceComponentHostResponse> nameResponse2 = new 
HashSet<ServiceComponentHostResponse>();
+    nameResponse2.add(new ServiceComponentHostResponse(
+        "Cluster102", "Service100", "Component100", "Host100", "INIT", "", 
"INSTALLED", "", null));
+
+
+    // set expectations
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    expect(managementController.findServiceName(cluster, 
"Component100")).andReturn("Service100").anyTimes();
+    expect(clusters.getCluster("Cluster102")).andReturn(cluster).anyTimes();
+    expect(cluster.getService("Service100")).andReturn(service).anyTimes();
+    
expect(service.getServiceComponent("Component100")).andReturn(component).anyTimes();
+    
expect(component.getServiceComponentHost("Host100")).andReturn(componentHost).anyTimes();
+    expect(component.getName()).andReturn("Component100").anyTimes();
+    // actual state is always INIT until stages actually execute
+    expect(componentHost.getState()).andReturn(State.INIT).anyTimes();
+    expect(componentHost.getHostName()).andReturn("Host100").anyTimes();
+    
expect(componentHost.getServiceComponentName()).andReturn("Component100").anyTimes();
+    expect(response.getMessage()).andReturn("response msg").anyTimes();
+    //expect(response.getRequestId()).andReturn(1000L);
+
+    //Cluster is default type.  Maintenance mode is not being tested here so 
the default is returned.
+    expect(maintenanceStateHelper.isOperationAllowed(Resource.Type.Cluster, 
componentHost)).andReturn(true).anyTimes();
+
+    //todo: can we change to prevent having to call twice?
+    expect(managementController.getHostComponents(
+        
EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse);
+    expect(managementController.getHostComponents(
+        
EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse2);
+
+    Map<String, Map<State, List<ServiceComponentHost>>> changedHosts =
+        new HashMap<String, Map<State, List<ServiceComponentHost>>>();
+    List<ServiceComponentHost> changedComponentHosts = 
Collections.singletonList(componentHost);
+    changedHosts.put("Component100", Collections.singletonMap(State.INSTALLED, 
changedComponentHosts));
+
+    Map<String, Map<State, List<ServiceComponentHost>>> changedHosts2 =
+        new HashMap<String, Map<State, List<ServiceComponentHost>>>();
+    List<ServiceComponentHost> changedComponentHosts2 = 
Collections.singletonList(componentHost);
+    changedHosts2.put("Component100", Collections.singletonMap(State.STARTED, 
changedComponentHosts2));
+
+    expect(managementController.addStages(null, cluster, mapRequestProps, 
null, null, null, changedHosts,
+        Collections.<ServiceComponentHost>emptyList(), false, 
false)).andReturn(stageContainer).once();
+
+    expect(managementController.addStages(stageContainer, cluster, 
mapRequestProps, null, null, null, changedHosts2,
+        Collections.<ServiceComponentHost>emptyList(), false, 
false)).andReturn(stageContainer).once();
+
+    stageContainer.persist();
+    expect(stageContainer.getProjectedState("Host100", 
"Component100")).andReturn(State.INSTALLED).once();
+    
expect(stageContainer.getRequestStatusResponse()).andReturn(response).once();
+
+    HostComponentResourceProvider provider =
+        new 
TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            managementController, injector, maintenanceStateHelper);
+
+    
expect(resourceProviderFactory.getHostComponentResourceProvider(anyObject(Set.class),
+        anyObject(Map.class),
+        eq(managementController))).
+        andReturn(provider).anyTimes();
+
+    // replay
+    replay(managementController, response, resourceProviderFactory, clusters, 
cluster, service,
+        component, componentHost, stageContainer, maintenanceStateHelper);
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+    
properties.put(HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID, 
"STARTED");
+
+    RequestStatusResponse requestResponse = 
provider.installAndStart("Cluster102", hosts);
+
+    assertSame(response, requestResponse);
+    // verify
+    verify(managementController, response, resourceProviderFactory, 
stageContainer);
   }
 
   @Test
@@ -309,7 +457,7 @@ public class HostComponentResourceProviderTest {
 
     AbstractResourceProviderTest.TestObserver observer = new 
AbstractResourceProviderTest.TestObserver();
 
-    ((ObservableResourceProvider)provider).addObserver(observer);
+    provider.addObserver(observer);
 
     Predicate predicate = new PredicateBuilder().
         
property(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("Component100").and().
@@ -372,4 +520,44 @@ public class HostComponentResourceProviderTest {
     unsupported = 
provider.checkPropertyIds(Collections.singleton("config/unknown_property"));
     Assert.assertTrue(unsupported.isEmpty());
   }
+
+  // Used to directly call updateHostComponents on the resource provider.
+  // This exists as a temporary solution as a result of moving 
updateHostComponents from
+  // AmbariManagentControllerImpl to HostComponentResourceProvider.
+  public static RequestStatusResponse 
updateHostComponents(AmbariManagementController controller,
+                                                           Injector injector,
+                                                           
Set<ServiceComponentHostRequest> requests,
+                                                           Map<String, String> 
requestProperties,
+                                                           boolean 
runSmokeTest) throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+    HostComponentResourceProvider provider =
+        new 
TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            controller, injector, 
injector.getInstance(MaintenanceStateHelper.class));
+    RequestStageContainer requestStages = provider.updateHostComponents(null, 
requests, requestProperties, runSmokeTest);
+    requestStages.persist();
+    return requestStages.getRequestStatusResponse();
+  }
+
+  private static class TestHostComponentResourceProvider extends 
HostComponentResourceProvider {
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds          the property ids
+     * @param keyPropertyIds       the key property ids
+     * @param managementController the management controller
+     */
+    public TestHostComponentResourceProvider(Set<String> propertyIds, 
Map<Resource.Type, String> keyPropertyIds,
+                                             AmbariManagementController 
managementController, Injector injector,
+                                             MaintenanceStateHelper 
maintenanceStateHelper) throws Exception {
+
+      super(propertyIds, keyPropertyIds, managementController, injector);
+
+      Class<?> c = getClass().getSuperclass();
+      Field f = c.getDeclaredField("maintenanceStateHelper");
+      f.setAccessible(true);
+      f.set(this, maintenanceStateHelper);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java
----------------------------------------------------------------------
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 cab75ee..2e80e24 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
@@ -51,11 +51,13 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
+
 import static org.powermock.api.easymock.PowerMock.replayAll;
 import java.net.InetAddress;
 import static org.powermock.api.easymock.PowerMock.*;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -1153,7 +1155,15 @@ public class HostResourceProviderTest {
 
   public static void createHosts(AmbariManagementController controller, 
Set<HostRequest> requests) throws AmbariException {
     HostResourceProvider provider = getHostProvider(controller);
-    provider.createHosts(requests);
+    Set<Map<String, Object>> properties = new HashSet<Map<String, Object>>();
+
+    for (HostRequest request : requests) {
+      Map<String, Object> requestProperties = new HashMap<String, Object>();
+      requestProperties.put(HostResourceProvider.HOST_NAME_PROPERTY_ID, 
request.getHostname());
+      
requestProperties.put(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID, 
request.getClusterName());
+      properties.add(requestProperties);
+    }
+    provider.createHosts(PropertyHelper.getCreateRequest(properties, 
Collections.<String, String>emptyMap()));
   }
 
   public static Set<HostResponse> getHosts(AmbariManagementController 
controller,
@@ -1168,11 +1178,9 @@ public class HostResourceProviderTest {
     provider.deleteHosts(requests);
   }
   
-  public static void updateHosts(AmbariManagementController controller, 
Set<HostRequest> requests,
-      Map<String, String> requestProperties)
+  public static void updateHosts(AmbariManagementController controller, 
Set<HostRequest> requests)
       throws AmbariException {
     HostResourceProvider provider = getHostProvider(controller);
-    provider.updateHosts(requests, requestProperties);
+    provider.updateHosts(requests);
   }
-  
 }

Reply via email to