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); } - }