You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2014/11/26 23:57:01 UTC
[1/2] ambari git commit: AMBARI-8458. Add support for "add hosts"
specifying host name,
blueprint name and host group name AMBARI-8437. Fix regression that prvented
cluster creation via blueprints
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);
}
-
}
[2/2] ambari git commit: AMBARI-8458. Add support for "add hosts"
specifying host name,
blueprint name and host group name AMBARI-8437. Fix regression that prvented
cluster creation via blueprints
Posted by js...@apache.org.
AMBARI-8458. Add support for "add hosts" specifying host name, blueprint name and host group name
AMBARI-8437. Fix regression that prvented cluster creation via blueprints
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/058dc168
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/058dc168
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/058dc168
Branch: refs/heads/trunk
Commit: 058dc168e6173f4206837a1db87d066b372b07b1
Parents: 501785f
Author: John Speidel <js...@hortonworks.com>
Authored: Wed Nov 26 13:35:45 2014 -0500
Committer: John Speidel <js...@hortonworks.com>
Committed: Wed Nov 26 17:56:02 2014 -0500
----------------------------------------------------------------------
.../controller/AmbariManagementController.java | 18 -
.../AmbariManagementControllerImpl.java | 336 +-----------
.../ambari/server/controller/HostRequest.java | 31 +-
.../internal/AbstractResourceProvider.java | 2 +-
.../internal/BaseBlueprintProcessor.java | 81 +++
.../internal/ClusterControllerImpl.java | 13 +-
.../internal/ClusterResourceProvider.java | 46 +-
.../internal/ConfigGroupResourceProvider.java | 31 +-
.../internal/HostComponentResourceProvider.java | 544 ++++++++++++++++++-
.../internal/HostResourceProvider.java | 324 ++++++++---
.../org/apache/ambari/server/state/Cluster.java | 7 +-
.../server/state/cluster/ClusterImpl.java | 2 +-
.../AmbariManagementControllerTest.java | 145 ++---
.../internal/ClusterResourceProviderTest.java | 9 +-
.../HostComponentResourceProviderTest.java | 220 +++++++-
.../internal/HostResourceProviderTest.java | 18 +-
16 files changed, 1239 insertions(+), 588 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 5af88a8..a1ece2c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -235,24 +235,6 @@ public interface AmbariManagementController {
throws AmbariException;
/**
- * Update the host component identified by the given request object with the
- * values carried by the given request object.
- *
- *
- *
- * @param requests the request object which defines which host component to
- * update and the values to set
- * @param requestProperties the request properties
- * @param runSmokeTest indicates whether or not to run a smoke test
- *
- * @return a track action response
- *
- * @throws AmbariException thrown if the resource cannot be updated
- */
- public RequestStatusResponse updateHostComponents(
- Set<ServiceComponentHostRequest> requests, Map<String, String> requestProperties, boolean runSmokeTest) throws AmbariException;
-
- /**
* Updates the users specified.
*
* @param requests the users to modify
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 7d08a7b..0e65a1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -44,7 +44,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -120,11 +119,8 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
-import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
-import org.apache.ambari.server.state.svccomphost.ServiceComponentHostDisableEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
-import org.apache.ambari.server.state.svccomphost.ServiceComponentHostRestoreEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostUpgradeEvent;
@@ -975,9 +971,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
try {
if (serviceComponentHostMap == null
|| !serviceComponentHostMap.containsKey(request.getHostname())) {
- ServiceComponentHostNotFoundException e = new ServiceComponentHostNotFoundException(cluster.getClusterName(),
+ throw new ServiceComponentHostNotFoundException(cluster.getClusterName(),
s.getName(), sc.getName(), request.getHostname());
- throw e;
}
ServiceComponentHost sch = serviceComponentHostMap.get(request.getHostname());
@@ -1309,8 +1304,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
/**
* Save cluster update results to retrieve later
- * @param clusterRequest
- * @param clusterResponse
+ * @param clusterRequest cluster request info
+ * @param clusterResponse cluster response info
*/
public void saveClusterUpdate(ClusterRequest clusterRequest, ClusterResponse clusterResponse) {
clusterUpdateCache.put(clusterRequest, clusterResponse);
@@ -1705,7 +1700,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
private List<ServiceOsSpecific> getOSSpecificsByFamily(Map<String, ServiceOsSpecific> osSpecifics, String osFamily) {
List<ServiceOsSpecific> foundedOSSpecifics = new ArrayList<ServiceOsSpecific>();
for (Entry<String, ServiceOsSpecific> osSpecific : osSpecifics.entrySet()) {
- if (osSpecific.getKey().indexOf(osFamily) != -1) {
+ if (osSpecific.getKey().contains(osFamily)) {
foundedOSSpecifics.add(osSpecific.getValue());
}
}
@@ -1833,8 +1828,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
nowTimestamp,
scHost.getDesiredStackVersion().getStackId());
} else if (oldSchState == State.STARTED
-// TODO: oldSchState == State.INSTALLED is always false, looks like a bug
-// || oldSchState == State.INSTALLED
+ // TODO: oldSchState == State.INSTALLED is always false, looks like a bug
+ //|| oldSchState == State.INSTALLED
|| oldSchState == State.STOPPING) {
roleCommand = RoleCommand.STOP;
event = new ServiceComponentHostStopEvent(
@@ -2105,272 +2100,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
return requestStages;
}
- @Override
- public synchronized RequestStatusResponse updateHostComponents(Set<ServiceComponentHostRequest> requests,
- Map<String, String> requestProperties, boolean runSmokeTest)
- throws AmbariException {
-
- if (requests.isEmpty()) {
- LOG.warn("Received an empty requests set");
- return null;
- }
-
- Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts =
- new HashMap<String, Map<State, List<ServiceComponentHost>>>();
- Collection<ServiceComponentHost> ignoredScHosts =
- new ArrayList<ServiceComponentHost>();
-
- Set<String> clusterNames = new HashSet<String>();
- Map<String, Map<String, Map<String, Set<String>>>> hostComponentNames =
- new HashMap<String, Map<String, Map<String, Set<String>>>>();
- Set<State> seenNewStates = new HashSet<State>();
- Map<ServiceComponentHost, State> directTransitionScHosts = new HashMap<ServiceComponentHost, State>();
-
- // 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;
-
- // Determine operation level
- Resource.Type reqOpLvl;
- if (requestProperties.containsKey(RequestOperationLevel.OPERATION_LEVEL_ID)) {
- RequestOperationLevel operationLevel = new RequestOperationLevel(requestProperties);
- reqOpLvl = operationLevel.getLevel();
- } else {
- String message = "Can not determine request operation level. " +
- "Operation level property should " +
- "be specified for this request.";
- LOG.warn(message);
- reqOpLvl = Resource.Type.Cluster;
- }
-
- for (ServiceComponentHostRequest request : requests) {
- validateServiceComponentHostRequest(request);
-
- Cluster cluster = clusters.getCluster(request.getClusterName());
-
- if (StringUtils.isEmpty(request.getServiceName())) {
- request.setServiceName(findServiceName(cluster, request.getComponentName()));
- }
-
- LOG.info("Received a updateHostComponent request"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + request.getServiceName()
- + ", componentName=" + request.getComponentName()
- + ", hostname=" + request.getHostname()
- + ", request=" + request);
-
- clusterNames.add(request.getClusterName());
-
- if (clusterNames.size() > 1) {
- throw new IllegalArgumentException("Updates to multiple clusters is not"
- + " supported");
- }
-
- if (!hostComponentNames.containsKey(request.getClusterName())) {
- hostComponentNames.put(request.getClusterName(),
- new HashMap<String, Map<String, Set<String>>>());
- }
- if (!hostComponentNames.get(request.getClusterName())
- .containsKey(request.getServiceName())) {
- hostComponentNames.get(request.getClusterName()).put(
- request.getServiceName(), new HashMap<String, Set<String>>());
- }
- if (!hostComponentNames.get(request.getClusterName())
- .get(request.getServiceName())
- .containsKey(request.getComponentName())) {
- hostComponentNames.get(request.getClusterName())
- .get(request.getServiceName()).put(request.getComponentName(),
- new HashSet<String>());
- }
- if (hostComponentNames.get(request.getClusterName())
- .get(request.getServiceName()).get(request.getComponentName())
- .contains(request.getHostname())) {
- throw new IllegalArgumentException("Invalid request contains duplicate"
- + " hostcomponents");
- }
- hostComponentNames.get(request.getClusterName())
- .get(request.getServiceName()).get(request.getComponentName())
- .add(request.getHostname());
-
- Service s = cluster.getService(request.getServiceName());
- ServiceComponent sc = s.getServiceComponent(
- request.getComponentName());
- ServiceComponentHost sch = sc.getServiceComponentHost(
- request.getHostname());
- State oldState = sch.getState();
- State newState = null;
- if (request.getDesiredState() != null) {
- newState = State.valueOf(request.getDesiredState());
- if (!newState.isValidDesiredState()) {
- throw new IllegalArgumentException("Invalid arguments, invalid"
- + " desired state, desiredState=" + newState.toString());
- }
- }
-
- // Setting Maintenance state for host component
- if (null != request.getMaintenanceState()) {
- MaintenanceStateHelper psh = injector.getInstance(MaintenanceStateHelper.class);
-
- MaintenanceState newMaint = MaintenanceState.valueOf(request.getMaintenanceState());
- MaintenanceState oldMaint = psh.getEffectiveState(sch);
-
- if (newMaint != oldMaint) {
- if (sc.isClientComponent()) {
- throw new IllegalArgumentException("Invalid arguments, cannot set " +
- "maintenance state on a client component");
- } else if (newMaint.equals(MaintenanceState.IMPLIED_FROM_HOST)
- || newMaint.equals(MaintenanceState.IMPLIED_FROM_SERVICE)) {
- throw new IllegalArgumentException("Invalid arguments, can only set " +
- "maintenance state to one of " + EnumSet.of(MaintenanceState.OFF, MaintenanceState.ON));
- } else {
- sch.setMaintenanceState(newMaint);
- maintenanceCluster = sch.getClusterName();
- }
- }
- }
-
- if (newState == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Nothing to do for new updateServiceComponentHost request"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + request.getServiceName()
- + ", componentName=" + request.getComponentName()
- + ", hostname=" + request.getHostname()
- + ", oldState=" + oldState
- + ", newDesiredState=null");
- }
- continue;
- }
-
- if (sc.isClientComponent() &&
- !newState.isValidClientComponentState()) {
- throw new IllegalArgumentException("Invalid desired state for a client"
- + " component");
- }
-
- seenNewStates.add(newState);
-
- State oldSchState = sch.getState();
- // Client component reinstall allowed
- if (newState == oldSchState &&
- !sc.isClientComponent() &&
- !requestProperties.containsKey(sch.getServiceComponentName().toLowerCase())) {
-
- ignoredScHosts.add(sch);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Ignoring ServiceComponentHost"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + s.getName()
- + ", componentName=" + sc.getName()
- + ", hostname=" + sch.getHostName()
- + ", currentState=" + oldSchState
- + ", newDesiredState=" + newState);
- }
- continue;
- }
-
- if (! maintenanceStateHelper.isOperationAllowed(reqOpLvl, sch)) {
- ignoredScHosts.add(sch);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Ignoring ServiceComponentHost"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + s.getName()
- + ", componentName=" + sc.getName()
- + ", hostname=" + sch.getHostName());
- }
- continue;
- }
-
- if (!State.isValidStateTransition(oldSchState, newState)) {
- throw new AmbariException("Invalid transition for"
- + " servicecomponenthost"
- + ", clusterName=" + cluster.getClusterName()
- + ", clusterId=" + cluster.getClusterId()
- + ", serviceName=" + sch.getServiceName()
- + ", componentName=" + sch.getServiceComponentName()
- + ", hostname=" + sch.getHostName()
- + ", currentState=" + oldSchState
- + ", newDesiredState=" + newState);
- }
-
- if (isDirectTransition(oldSchState, newState)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Handling direct transition update to ServiceComponentHost"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + s.getName()
- + ", componentName=" + sc.getName()
- + ", hostname=" + sch.getHostName()
- + ", currentState=" + oldSchState
- + ", newDesiredState=" + newState);
- }
- directTransitionScHosts.put(sch, newState);
- } else {
- if (!changedScHosts.containsKey(sc.getName())) {
- changedScHosts.put(sc.getName(),
- new EnumMap<State, List<ServiceComponentHost>>(State.class));
- }
- if (!changedScHosts.get(sc.getName()).containsKey(newState)) {
- changedScHosts.get(sc.getName()).put(newState,
- new ArrayList<ServiceComponentHost>());
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Handling update to ServiceComponentHost"
- + ", clusterName=" + request.getClusterName()
- + ", serviceName=" + s.getName()
- + ", componentName=" + sc.getName()
- + ", hostname=" + sch.getHostName()
- + ", currentState=" + oldSchState
- + ", newDesiredState=" + newState);
- }
- changedScHosts.get(sc.getName()).get(newState).add(sch);
- }
- }
-
- if (seenNewStates.size() > 1) {
- // FIXME should we handle this scenario
- throw new IllegalArgumentException("Cannot handle different desired"
- + " state changes for a set of service components at the same time");
- }
-
- // Perform direct transitions (without task generation)
- for (Entry<ServiceComponentHost, State> entry : directTransitionScHosts.entrySet()) {
- ServiceComponentHost componentHost = entry.getKey();
- State newState = entry.getValue();
- long timestamp = System.currentTimeMillis();
- ServiceComponentHostEvent event;
- componentHost.setDesiredState(newState);
- switch (newState) {
- case DISABLED:
- event = new ServiceComponentHostDisableEvent(
- componentHost.getServiceComponentName(),
- componentHost.getHostName(),
- timestamp);
- break;
- case INSTALLED:
- event = new ServiceComponentHostRestoreEvent(
- componentHost.getServiceComponentName(),
- componentHost.getHostName(),
- timestamp);
- break;
- default:
- throw new AmbariException("Direct transition from " + componentHost.getState() + " to " + newState + " not supported");
- }
- try {
- componentHost.handleEvent(event);
- } catch (InvalidStateTransitionException e) {
- //Should not occur, must be covered by previous checks
- throw new AmbariException("Internal error - not supported transition", e);
- }
- }
-
- Cluster cluster = clusters.getCluster(clusterNames.iterator().next());
-
- return createAndPersistStages(cluster, requestProperties, null, null, null,
- changedScHosts, ignoredScHosts, runSmokeTest, false);
- }
-
-
- private void validateServiceComponentHostRequest(ServiceComponentHostRequest request) {
+ //todo: for now made this public since is is still used by createHostComponents
+ //todo: delete after all host component logic is in HostComponentResourceProvider
+ public void validateServiceComponentHostRequest(ServiceComponentHostRequest request) {
if (request.getClusterName() == null
|| request.getClusterName().isEmpty()
|| request.getComponentName() == null
@@ -2435,31 +2167,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
return serviceName;
}
-
- /**
- * Checks if assigning new state does not require performing
- * any additional actions
- */
- private boolean isDirectTransition(State oldState, State newState) {
- switch (newState) {
- case INSTALLED:
- if (oldState == State.DISABLED) {
- return true;
- }
- break;
- case DISABLED:
- if (oldState == State.INSTALLED ||
- oldState == State.INSTALL_FAILED ||
- oldState == State.UNKNOWN) {
- return true;
- }
- break;
- default:
- break;
- }
- return false;
- }
-
@Override
public synchronized void updateUsers(Set<UserRequest> requests) throws AmbariException {
for (UserRequest request : requests) {
@@ -2935,13 +2642,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
@Override
public void updateGroups(Set<GroupRequest> requests) throws AmbariException {
- for (GroupRequest request: requests) {
- final Group group = users.getGroup(request.getGroupName());
- if (group == null) {
- continue;
- }
- // currently no group updates are supported
- }
+ // currently no group updates are supported
}
protected String getClientHostForRunningAction(Cluster cluster, Service service, ServiceComponent serviceComponent)
@@ -3239,16 +2940,16 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
String errorMessage = null;
String[] suffixes = configs.getRepoValidationSuffixes(rr.getOsType());
- for (int i = 0; i < suffixes.length; i++) {
- String suffix = String.format(suffixes[i], repoName);
+ for (String suffix : suffixes) {
+ String formatted_suffix = String.format(suffix, repoName);
String spec = rr.getBaseUrl();
- if (spec.charAt(spec.length()-1) != '/' && suffix.charAt(0) != '/') {
- spec = rr.getBaseUrl() + "/" + suffix;
- } else if (spec.charAt(spec.length()-1) == '/' && suffix.charAt(0) == '/') {
- spec = rr.getBaseUrl() + suffix.substring(1);
+ if (spec.charAt(spec.length() - 1) != '/' && formatted_suffix.charAt(0) != '/') {
+ spec = rr.getBaseUrl() + "/" + formatted_suffix;
+ } else if (spec.charAt(spec.length() - 1) == '/' && formatted_suffix.charAt(0) == '/') {
+ spec = rr.getBaseUrl() + formatted_suffix.substring(1);
} else {
- spec = rr.getBaseUrl() + suffix;
+ spec = rr.getBaseUrl() + formatted_suffix;
}
try {
@@ -3257,8 +2958,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
errorMessage = "Could not access base url . " + rr.getBaseUrl() + " . ";
if (LOG.isDebugEnabled()) {
errorMessage += ioe;
- }
- else {
+ } else {
errorMessage += ioe.getMessage();
}
bFound = false;
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java
index b577bb0..a616839 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java
@@ -31,6 +31,9 @@ public class HostRequest {
private String rackInfo;
private List<ConfigurationRequest> desiredConfigs; // UPDATE
private String maintenanceState; // UPDATE
+ private String blueprint;
+ private String hostgroup;
+ private String hostToClone;
public HostRequest(String hostname, String clusterName, Map<String, String> hostAttributes) {
this.hostname = hostname;
@@ -94,6 +97,30 @@ public class HostRequest {
return maintenanceState;
}
+ public void setBlueprintName(String blueprintName) {
+ blueprint = blueprintName;
+ }
+
+ public String getBlueprintName() {
+ return blueprint;
+ }
+
+ public void setHostGroupName(String hostgroupName) {
+ hostgroup = hostgroupName;
+ }
+
+ public String getHostGroupName() {
+ return hostgroup;
+ }
+
+ public void setHostToClone(String hostname) {
+ hostToClone = hostname;
+ }
+
+ public String getHostToClone() {
+ return hostToClone;
+ }
+
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{ hostname=").append(hostname).append(", clusterName=").append(clusterName);
@@ -105,7 +132,9 @@ public class HostRequest {
sb.append(",");
}
++i;
- sb.append(attr.getKey() + "=" + attr.getValue());
+ sb.append(attr.getKey());
+ sb.append("=");
+ sb.append(attr.getValue());
}
sb.append(']');
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
index 2c9179d..69d13b5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
@@ -380,7 +380,7 @@ public abstract class AbstractResourceProvider extends BaseProvider implements R
String absCategory = PropertyHelper.getPropertyCategory(entry.getKey());
String propName = PropertyHelper.getPropertyName(entry.getKey());
- if (absCategory.startsWith(desiredConfigKey)) {
+ if (absCategory != null && absCategory.startsWith(desiredConfigKey)) {
config = (null == config) ? new ConfigurationRequest() : config;
parseProperties(config, absCategory, propName, entry.getValue().toString());
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
index 9be73cc..9cfb635 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
@@ -24,8 +24,12 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.orm.dao.BlueprintDAO;
import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
import org.apache.ambari.server.orm.entities.BlueprintEntity;
@@ -37,6 +41,7 @@ import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.DependencyInfo;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -442,6 +447,82 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
throw new IllegalArgumentException(msg);
}
+ /**
+ * Create host and host_component resources.
+ *
+ * @param blueprintHostGroups host groups specified in blueprint
+ * @param clusterName cluster name
+ *
+ * @throws SystemException an unexpected exception occurred
+ * @throws UnsupportedPropertyException an invalid property was specified
+ * @throws ResourceAlreadyExistsException attempt to create a host or host_component which already exists
+ * @throws NoSuchParentResourceException a required parent resource is missing
+ */
+ protected void createHostAndComponentResources(Map<String, HostGroupImpl> blueprintHostGroups, String clusterName)
+ throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
+
+ createHostAndComponentResources(blueprintHostGroups, clusterName, getResourceProvider(Resource.Type.Host));
+ }
+
+ /**
+ * Create host and host_component resources via the specified host resource provider.
+ *
+ * @param blueprintHostGroups host groups specified in blueprint
+ * @param clusterName cluster name
+ * @param hostProvider host resource provider
+ *
+ * @throws SystemException an unexpected exception occurred
+ * @throws UnsupportedPropertyException an invalid property was specified
+ * @throws ResourceAlreadyExistsException attempt to create a host or host_component which already exists
+ * @throws NoSuchParentResourceException a required parent resource is missing
+ */
+ protected void createHostAndComponentResources(Map<String, HostGroupImpl> blueprintHostGroups,
+ String clusterName,
+ ResourceProvider hostProvider)
+ throws SystemException,
+ UnsupportedPropertyException,
+ ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ ResourceProvider hostComponentProvider = getResourceProvider(Resource.Type.HostComponent);
+ for (HostGroupImpl group : blueprintHostGroups.values()) {
+ for (String host : group.getHostInfo()) {
+ Map<String, Object> hostProperties = new HashMap<String, Object>();
+ hostProperties.put("Hosts/cluster_name", clusterName);
+ hostProperties.put("Hosts/host_name", host);
+
+ hostProvider.createResources(new RequestImpl(
+ null, Collections.singleton(hostProperties), null, null));
+
+ // create clusters/hosts/host_components
+ Set<Map<String, Object>> setHostComponentRequestProps = new HashSet<Map<String, Object>>();
+ for (String hostComponent : group.getComponents()) {
+ // AMBARI_SERVER is not recognized by Ambari as a component
+ if (! hostComponent.equals("AMBARI_SERVER")) {
+ Map<String, Object> hostComponentProperties = new HashMap<String, Object>();
+ hostComponentProperties.put("HostRoles/cluster_name", clusterName);
+ hostComponentProperties.put("HostRoles/host_name", host);
+ hostComponentProperties.put("HostRoles/component_name", hostComponent);
+ setHostComponentRequestProps.add(hostComponentProperties);
+ }
+ }
+ hostComponentProvider.createResources(new RequestImpl(
+ null, setHostComponentRequestProps, null, null));
+ }
+ }
+ }
+
+ /**
+ * Get a config group name based on a bp and host group.
+ *
+ * @param bpName blueprint name
+ * @param hostGroupName host group name
+ * @return config group name
+ */
+ protected String getConfigurationGroupName(String bpName, String hostGroupName) {
+ return String.format("%s:%s", bpName, hostGroupName);
+ }
+
// ----- Inner Classes -----------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
index 352e0ad..b075d25 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
@@ -339,9 +339,20 @@ public class ClusterControllerImpl implements ClusterController {
return null;
}
+
+ /**
+ * Provides a non-wrapped resource provider..
+ *
+ * @param type type of resource provider to obtain
+ * @return a non-wrapped resource provider
+ */
@Override
public ResourceProvider ensureResourceProvider(Type type) {
- return ensureResourceProviderWrapper(type);
+ //todo: in some cases it is necessary to down cast the returned resource provider
+ //todo: to a concrete type. Perhaps we can provided a 'T getDelegate()' method
+ //todo: on the wrapper so no casting would be necessary.
+ ExtendedResourceProviderWrapper providerWrapper = ensureResourceProviderWrapper(type);
+ return providerWrapper == null ? null : providerWrapper.resourceProvider;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index bb6a39c..15cd8de 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -599,49 +599,6 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
}
/**
- * Create host and host_component resources.
- *
- * @param blueprintHostGroups host groups specified in blueprint
- * @param clusterName cluster name
- *
- * @throws SystemException an unexpected exception occurred
- * @throws UnsupportedPropertyException an invalid property was specified
- * @throws ResourceAlreadyExistsException attempt to create a host or host_component which already exists
- * @throws NoSuchParentResourceException a required parent resource is missing
- */
- private void createHostAndComponentResources(Map<String, HostGroupImpl> blueprintHostGroups, String clusterName)
- throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
-
- ResourceProvider hostProvider = getResourceProvider(Resource.Type.Host);
- ResourceProvider hostComponentProvider = getResourceProvider(Resource.Type.HostComponent);
- for (HostGroupImpl group : blueprintHostGroups.values()) {
- for (String host : group.getHostInfo()) {
- Map<String, Object> hostProperties = new HashMap<String, Object>();
- hostProperties.put("Hosts/cluster_name", clusterName);
- hostProperties.put("Hosts/host_name", host);
-
- hostProvider.createResources(new RequestImpl(
- null, Collections.singleton(hostProperties), null, null));
-
- // create clusters/hosts/host_components
- Set<Map<String, Object>> setHostComponentRequestProps = new HashSet<Map<String, Object>>();
- for (String hostComponent : group.getComponents()) {
- // AMBARI_SERVER is not recognized by Ambari as a component
- if (! hostComponent.equals("AMBARI_SERVER")) {
- Map<String, Object> hostComponentProperties = new HashMap<String, Object>();
- hostComponentProperties.put("HostRoles/cluster_name", clusterName);
- hostComponentProperties.put("HostRoles/host_name", host);
- hostComponentProperties.put("HostRoles/component_name", hostComponent);
- setHostComponentRequestProps.add(hostComponentProperties);
- }
- }
- hostComponentProvider.createResources(new RequestImpl(
- null, setHostComponentRequestProps, null, null));
- }
- }
- }
-
- /**
* Create component resources.
*
* @param blueprintHostGroups host groups specified in blueprint
@@ -1158,8 +1115,9 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
for (Map.Entry<String, Map<String, Config>> entry : groupConfigs.entrySet()) {
String service = entry.getKey();
Map<String, Config> serviceConfigs = entry.getValue();
+ String hostGroupName = getConfigurationGroupName(entity.getBlueprintName(), entity.getName());
ConfigGroupRequest request = new ConfigGroupRequest(
- null, clusterName, entity.getName(), service, "Host Group Configuration",
+ null, clusterName, hostGroupName, service, "Host Group Configuration",
new HashSet<String>(group.getHostInfo()), serviceConfigs);
((ConfigGroupResourceProvider) getResourceProvider(Resource.Type.ConfigGroup)).
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
index c73a8d4..3fcb84b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
@@ -17,8 +17,6 @@
*/
package org.apache.ambari.server.controller.internal;
-import com.google.common.collect.MapDifference;
-import com.google.common.collect.Maps;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.ConfigGroupNotFoundException;
@@ -180,19 +178,13 @@ public class ConfigGroupResourceProvider extends
for (Map<String, Object> propertyMap : getPropertyMaps(iterator.next(), predicate)) {
requests.add(getConfigGroupRequest(propertyMap));
}
-
- modifyResources(new Command<Void>() {
- @Override
- public Void invoke() throws AmbariException {
- updateConfigGroups(requests);
- return null;
- }
- });
}
+ RequestStatus status = updateResources(requests);
+
notifyUpdate(Resource.Type.ConfigGroup, request, predicate);
- return getRequestStatus(null);
+ return status;
}
@Override
@@ -265,6 +257,23 @@ public class ConfigGroupResourceProvider extends
return getRequestStatus(null, associatedResources);
}
+ public RequestStatus updateResources(final Set<ConfigGroupRequest> requests)
+ throws SystemException,
+ UnsupportedPropertyException,
+ NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ updateConfigGroups(requests);
+ return null;
+ }
+ });
+
+ return getRequestStatus(null);
+ }
+
private synchronized Set<ConfigGroupResponse> getConfigGroups
(Set<ConfigGroupRequest> requests) throws AmbariException {
Set<ConfigGroupResponse> responses = new HashSet<ConfigGroupResponse>();
http://git-wip-us.apache.org/repos/asf/ambari/blob/058dc168/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
index 4600538..47d3f70 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
@@ -17,20 +17,31 @@
*/
package org.apache.ambari.server.controller.internal;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.google.inject.Inject;
import com.google.inject.Injector;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
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.ServiceComponentHostRequest;
import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.predicate.EqualsPredicate;
+import org.apache.ambari.server.controller.predicate.NotPredicate;
+import org.apache.ambari.server.controller.predicate.OrPredicate;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -45,7 +56,17 @@ import org.apache.ambari.server.controller.utilities.PropertyHelper;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
-import com.google.inject.persist.Transactional;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
+import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostDisableEvent;
+import org.apache.ambari.server.state.svccomphost.ServiceComponentHostRestoreEvent;
+import org.apache.commons.lang.StringUtils;
/**
* Resource provider for host component resources.
@@ -79,7 +100,7 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
= PropertyHelper.getPropertyId("HostRoles", "desired_admin_state");
protected static final String HOST_COMPONENT_MAINTENANCE_STATE_PROPERTY_ID
= "HostRoles/maintenance_state";
-
+
//Component name mappings
private final Map<String, PropertyProvider> HOST_COMPONENT_PROPERTIES_PROVIDER = new HashMap<String, PropertyProvider>();
private static final int HOST_COMPONENT_HTTP_PROPERTY_REQUEST_CONNECT_TIMEOUT = 1500; //milliseconds
@@ -95,6 +116,13 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID,
HOST_COMPONENT_HOST_NAME_PROPERTY_ID}));
+ /**
+ * maintenance state helper
+ */
+ @Inject
+ private MaintenanceStateHelper maintenanceStateHelper;
+
+
// ----- Constructors ----------------------------------------------------
/**
@@ -153,7 +181,6 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
}
@Override
- @Transactional
public Set<Resource> getResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
@@ -194,7 +221,7 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
setResourceProperty(resource, HOST_COMPONENT_ACTUAL_CONFIGS_PROPERTY_ID,
response.getActualConfigs(), requestedIds);
setResourceProperty(resource, HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID,
- Boolean.valueOf(response.isStaleConfig()), requestedIds);
+ response.isStaleConfig(), requestedIds);
if (response.getAdminState() != null) {
setResourceProperty(resource, HOST_COMPONENT_DESIRED_ADMIN_STATE_PROPERTY_ID,
@@ -222,26 +249,24 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
@Override
public RequestStatus updateResources(final Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
- final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
- RequestStatusResponse response = null;
- final boolean runSmokeTest = "true".equals(getQueryParameterValue(
- QUERY_PARAMETERS_RUN_SMOKE_TEST_ID, predicate)) ? true : false;
+ if (request.getProperties().isEmpty()) {
+ throw new IllegalArgumentException("Received an update request with no properties");
+ }
- Iterator<Map<String, Object>> iterator = request.getProperties().iterator();
- if (iterator.hasNext()) {
- for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
- requests.add(getRequest(propertyMap));
- }
- response = modifyResources(new Command<RequestStatusResponse>() {
- @Override
- public RequestStatusResponse invoke() throws AmbariException {
- return getManagementController().updateHostComponents(requests, request.getRequestInfoProperties(), runSmokeTest);
- }
- });
+ RequestStageContainer requestStages = doUpdateResources(null, request, predicate);
+ RequestStatusResponse response = null;
+ if (requestStages != null) {
+ try {
+ requestStages.persist();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+ response = requestStages.getRequestStatusResponse();
notifyUpdate(Resource.Type.HostComponent, request, predicate);
}
+
return getRequestStatus(response);
}
@@ -284,14 +309,247 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
return unsupportedProperties;
}
+ RequestStatusResponse installAndStart(String cluster, Collection<String> hosts) throws SystemException,
+ UnsupportedPropertyException, NoSuchParentResourceException {
- // ----- utility methods -------------------------------------------------
+ final RequestStageContainer requestStages;
+ Map<String, Object> installProperties = new HashMap<String, Object>();
+
+ installProperties.put(HOST_COMPONENT_STATE_PROPERTY_ID, "INSTALLED");
+ Map<String, String> requestInfo = new HashMap<String, String>();
+ requestInfo.put("context", "Install and start components on added hosts");
+ Request installRequest = PropertyHelper.getUpdateRequest(installProperties, requestInfo);
+
+ Collection<EqualsPredicate> hostPredicates = new ArrayList<EqualsPredicate>();
+ for (String host : hosts) {
+ hostPredicates.add(new EqualsPredicate<String>(HOST_COMPONENT_HOST_NAME_PROPERTY_ID, host));
+ }
+
+ Predicate statePredicate = new EqualsPredicate<String>(HOST_COMPONENT_STATE_PROPERTY_ID, "INIT");
+ Predicate clusterPredicate = new EqualsPredicate<String>(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, cluster);
+ Predicate hostPredicate = new OrPredicate(hostPredicates.toArray(new Predicate[hostPredicates.size()]));
+ Predicate hostAndStatePredicate = new AndPredicate(statePredicate, hostPredicate);
+ Predicate installPredicate = new AndPredicate(hostAndStatePredicate, clusterPredicate);
+
+ try {
+ LOG.info("Installing all components on added hosts");
+ requestStages = doUpdateResources(null, installRequest, installPredicate);
+ notifyUpdate(Resource.Type.HostComponent, installRequest, installPredicate);
+
+ Map<String, Object> startProperties = new HashMap<String, Object>();
+ startProperties.put(HOST_COMPONENT_STATE_PROPERTY_ID, "STARTED");
+ Request startRequest = PropertyHelper.getUpdateRequest(startProperties, requestInfo);
+ // Important to query against desired_state as this has been updated when install stage was created
+ // If I query against state, then the getRequest compares predicate prop against desired_state and then when the predicate
+ // is later applied explicitly, it gets compared to live_state. Since live_state == INSTALLED == INIT at this point and
+ // desired_state == INSTALLED, we will always get 0 matches since both comparisons can't be true :(
+ Predicate installedStatePredicate = new EqualsPredicate<String>(HOST_COMPONENT_DESIRED_STATE_PROPERTY_ID, "INSTALLED");
+ Predicate notClientPredicate = new NotPredicate(new ClientComponentPredicate());
+ Predicate clusterAndClientPredicate = new AndPredicate(clusterPredicate, notClientPredicate);
+ hostAndStatePredicate = new AndPredicate(installedStatePredicate, hostPredicate);
+ Predicate startPredicate = new AndPredicate(clusterAndClientPredicate, hostAndStatePredicate);
+
+ LOG.info("Starting all non-client components on added hosts");
+ //todo: if a host in in state HEARTBEAT_LOST, no stage will be created, so if this occurs during INSTALL
+ //todo: then no INSTALL stage will exist which will result in invalid state transition INIT->STARTED
+ doUpdateResources(requestStages, startRequest, startPredicate);
+ notifyUpdate(Resource.Type.HostComponent, startRequest, startPredicate);
+ try {
+ requestStages.persist();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+ return requestStages.getRequestStatusResponse();
+ } catch (NoSuchResourceException e) {
+ // shouldn't encounter this exception here
+ throw new SystemException("An unexpected exception occurred while processing add hosts", e);
+ }
+ }
+
+
+ /**
+ * Update the host component identified by the given request object with the
+ * values carried by the given request object.
+ *
+ * @param stages stages of the associated request
+ * @param requests the request object which defines which host component to
+ * update and the values to set
+ * @param requestProperties the request properties
+ * @param runSmokeTest indicates whether or not to run a smoke test
+ *
+ * @return a track action response
+ *
+ * @throws AmbariException thrown if the resource cannot be updated
+ */
+ //todo: This was moved from AmbariManagementController and needs a lot of refactoring.
+ //todo: Look into using the predicate instead of Set<ServiceComponentHostRequest>
+ //todo: change to private access when all AMC tests have been moved.
+ protected synchronized RequestStageContainer updateHostComponents(RequestStageContainer stages,
+ Set<ServiceComponentHostRequest> requests,
+ Map<String, String> requestProperties,
+ boolean runSmokeTest) throws AmbariException {
+
+ Clusters clusters = getManagementController().getClusters();
+
+
+ Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts = new HashMap<String, Map<State, List<ServiceComponentHost>>>();
+ Collection<ServiceComponentHost> ignoredScHosts = new ArrayList<ServiceComponentHost>();
+ Set<String> clusterNames = new HashSet<String>();
+ Map<String, Map<String, Map<String, Set<String>>>> requestClusters = new HashMap<String, Map<String, Map<String, Set<String>>>>();
+ Map<ServiceComponentHost, State> directTransitionScHosts = new HashMap<ServiceComponentHost, State>();
+
+ Resource.Type reqOpLvl = determineOperationLevel(requestProperties);
+
+
+ for (ServiceComponentHostRequest request : requests) {
+ validateServiceComponentHostRequest(request);
+
+ Cluster cluster = clusters.getCluster(request.getClusterName());
+
+ if (StringUtils.isEmpty(request.getServiceName())) {
+ request.setServiceName(getManagementController().findServiceName(cluster, request.getComponentName()));
+ }
+
+ ServiceComponent sc = getServiceComponent(
+ request.getClusterName(), request.getServiceName(), request.getComponentName());
+
+ logRequestInfo("Received a updateHostComponent request", request);
+
+ clusterNames.add(request.getClusterName());
+
+ if (clusterNames.size() > 1) {
+ throw new IllegalArgumentException("Updates to multiple clusters is not"
+ + " supported");
+ }
+
+ // maps of cluster->services, services->components, components->hosts
+ Map<String, Map<String, Set<String>>> clusterServices = requestClusters.get(request.getClusterName());
+ if (clusterServices == null) {
+ clusterServices = new HashMap<String, Map<String, Set<String>>>();
+ requestClusters.put(request.getClusterName(), clusterServices);
+ }
+
+ Map<String, Set<String>> serviceComponents = clusterServices.get(request.getServiceName());
+ if (serviceComponents == null) {
+ serviceComponents = new HashMap<String, Set<String>>();
+ clusterServices.put(request.getServiceName(), serviceComponents);
+ }
+
+ Set<String> componentHosts = serviceComponents.get(request.getComponentName());
+ if (componentHosts == null) {
+ componentHosts = new HashSet<String>();
+ serviceComponents.put(request.getComponentName(), componentHosts) ;
+ }
+
+ if (componentHosts.contains(request.getHostname())) {
+ throw new IllegalArgumentException("Invalid request contains duplicate hostcomponents");
+ }
+
+ componentHosts.add(request.getHostname());
+
+
+ ServiceComponentHost sch = sc.getServiceComponentHost(request.getHostname());
+ State oldState = sch.getState();
+ State newState = null;
+ if (request.getDesiredState() != null) {
+ // set desired state on host component
+ newState = State.valueOf(request.getDesiredState());
+ // throw exception if desired state isn't a valid desired state (static check)
+ if (!newState.isValidDesiredState()) {
+ throw new IllegalArgumentException("Invalid arguments, invalid"
+ + " desired state, desiredState=" + newState.toString());
+ }
+ }
+
+ // Setting Maintenance state for host component
+ if (null != request.getMaintenanceState()) {
+ MaintenanceState newMaint = MaintenanceState.valueOf(request.getMaintenanceState());
+ MaintenanceState oldMaint = maintenanceStateHelper.getEffectiveState(sch);
+
+ if (newMaint != oldMaint) {
+ if (sc.isClientComponent()) {
+ throw new IllegalArgumentException("Invalid arguments, cannot set maintenance state on a client component");
+ } else if (newMaint.equals(MaintenanceState.IMPLIED_FROM_HOST) || newMaint.equals(MaintenanceState.IMPLIED_FROM_SERVICE)) {
+ throw new IllegalArgumentException("Invalid arguments, can only set maintenance state to one of " +
+ EnumSet.of(MaintenanceState.OFF, MaintenanceState.ON));
+ } else {
+ sch.setMaintenanceState(newMaint);
+ }
+ }
+ }
+
+ if (newState == null) {
+ logComponentInfo("Nothing to do for new updateServiceComponentHost", request, oldState, null);
+ continue;
+ }
+
+ if (sc.isClientComponent() &&
+ !newState.isValidClientComponentState()) {
+ throw new IllegalArgumentException("Invalid desired state for a client"
+ + " component");
+ }
+
+ State oldSchState = sch.getState();
+ // Client component reinstall allowed
+ if (newState == oldSchState && !sc.isClientComponent() &&
+ !requestProperties.containsKey(sch.getServiceComponentName().toLowerCase())) {
+
+ ignoredScHosts.add(sch);
+ logComponentInfo("Ignoring ServiceComponentHost", request, oldState, newState);
+ continue;
+ }
+
+ if (! maintenanceStateHelper.isOperationAllowed(reqOpLvl, sch)) {
+ ignoredScHosts.add(sch);
+ logComponentInfo("Ignoring ServiceComponentHost", request, oldState, newState);
+ continue;
+ }
+
+ if (! isValidStateTransition(stages, oldSchState, newState, sch)) {
+ throw new AmbariException("Invalid state transition for host component"
+ + ", clusterName=" + cluster.getClusterName()
+ + ", clusterId=" + cluster.getClusterId()
+ + ", serviceName=" + sch.getServiceName()
+ + ", componentName=" + sch.getServiceComponentName()
+ + ", hostname=" + sch.getHostName()
+ + ", currentState=" + oldSchState
+ + ", newDesiredState=" + newState);
+ }
+
+ if (isDirectTransition(oldSchState, newState)) {
+ logComponentInfo("Handling direct transition update to host component", request, oldState, newState);
+ directTransitionScHosts.put(sch, newState);
+ } else {
+ if (!changedScHosts.containsKey(sc.getName())) {
+ changedScHosts.put(sc.getName(),
+ new EnumMap<State, List<ServiceComponentHost>>(State.class));
+ }
+ if (!changedScHosts.get(sc.getName()).containsKey(newState)) {
+ changedScHosts.get(sc.getName()).put(newState,
+ new ArrayList<ServiceComponentHost>());
+ }
+ logComponentInfo("Handling update to host component", request, oldState, newState);
+ changedScHosts.get(sc.getName()).get(newState).add(sch);
+ }
+ }
+
+ doDirectTransitions(directTransitionScHosts);
+
+ // just getting the first cluster
+ Cluster cluster = clusters.getCluster(clusterNames.iterator().next());
+
+ return getManagementController().addStages(stages, cluster, requestProperties, null, null, null,
+ changedScHosts, ignoredScHosts, runSmokeTest, false);
+ }
@Override
protected Set<String> getPKPropertyIds() {
return pkPropertyIds;
}
+
+ // ----- utility methods -------------------------------------------------
+
/**
* Get a component request object from a map of property values.
*
@@ -324,4 +582,248 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
return serviceComponentHostRequest;
}
+
+ private RequestStageContainer doUpdateResources(final RequestStageContainer stages, final Request request, Predicate predicate)
+ throws UnsupportedPropertyException, SystemException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+
+ final boolean runSmokeTest = "true".equals(getQueryParameterValue(
+ QUERY_PARAMETERS_RUN_SMOKE_TEST_ID, predicate));
+
+ Set<String> queryIds = Collections.singleton(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+
+ Request queryRequest = PropertyHelper.getReadRequest(queryIds);
+ // will take care of 404 exception
+ Set<Resource> matchingResources = getResources(queryRequest, predicate);
+
+ for (Resource queryResource : matchingResources) {
+ if (predicate.evaluate(queryResource)) {
+ Map<String, Object> updateRequestProperties = new HashMap<String, Object>();
+
+ // add props from query resource
+ updateRequestProperties.putAll(PropertyHelper.getProperties(queryResource));
+
+ // add properties from update request
+ //todo: should we flag value size > 1?
+ if (request.getProperties() != null && request.getProperties().size() != 0) {
+ updateRequestProperties.putAll(request.getProperties().iterator().next());
+ }
+ requests.add(getRequest(updateRequestProperties));
+ }
+ }
+
+ RequestStageContainer requestStages = modifyResources(new Command<RequestStageContainer>() {
+ @Override
+ public RequestStageContainer invoke() throws AmbariException {
+ return updateHostComponents(stages, requests, request.getRequestInfoProperties(),
+ runSmokeTest);
+ }
+ });
+ notifyUpdate(Resource.Type.HostComponent, request, predicate);
+
+ return requestStages;
+ }
+
+ /**
+ * Determine whether a host component state change is valid.
+ * Looks at projected state from the current stages associated with the request.
+ *
+ *
+ * @param stages request stages
+ * @param startState host component start state
+ * @param desiredState host component desired state
+ * @param host host where state change is occurring
+ *
+ * @return whether the state transition is valid
+ */
+ private boolean isValidStateTransition(RequestStageContainer stages, State startState,
+ State desiredState, ServiceComponentHost host) {
+
+ if (stages != null) {
+ State projectedState = stages.getProjectedState(host.getHostName(), host.getServiceComponentName());
+ startState = projectedState == null ? startState : projectedState;
+ }
+
+ return State.isValidStateTransition(startState, desiredState);
+ }
+
+ /**
+ * Checks if assigning new state does not require performing
+ * any additional actions
+ */
+ public boolean isDirectTransition(State oldState, State newState) {
+ switch (newState) {
+ case INSTALLED:
+ if (oldState == State.DISABLED) {
+ return true;
+ }
+ break;
+ case DISABLED:
+ if (oldState == State.INSTALLED ||
+ oldState == State.INSTALL_FAILED ||
+ oldState == State.UNKNOWN) {
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ private ServiceComponent getServiceComponent(String clusterName, String serviceName, String componentName)
+ throws AmbariException {
+
+ Clusters clusters = getManagementController().getClusters();
+ return clusters.getCluster(clusterName).getService(serviceName).getServiceComponent(componentName);
+ }
+
+ // Perform direct transitions (without task generation)
+ private void doDirectTransitions(Map<ServiceComponentHost, State> directTransitionScHosts) throws AmbariException {
+ for (Map.Entry<ServiceComponentHost, State> entry : directTransitionScHosts.entrySet()) {
+ ServiceComponentHost componentHost = entry.getKey();
+ State newState = entry.getValue();
+ long timestamp = System.currentTimeMillis();
+ ServiceComponentHostEvent event;
+ componentHost.setDesiredState(newState);
+ switch (newState) {
+ case DISABLED:
+ event = new ServiceComponentHostDisableEvent(
+ componentHost.getServiceComponentName(),
+ componentHost.getHostName(),
+ timestamp);
+ break;
+ case INSTALLED:
+ event = new ServiceComponentHostRestoreEvent(
+ componentHost.getServiceComponentName(),
+ componentHost.getHostName(),
+ timestamp);
+ break;
+ default:
+ throw new AmbariException("Direct transition from " + componentHost.getState() + " to " + newState + " not supported");
+ }
+ try {
+ componentHost.handleEvent(event);
+ } catch (InvalidStateTransitionException e) {
+ //Should not occur, must be covered by previous checks
+ throw new AmbariException("Internal error - not supported transition", e);
+ }
+ }
+ }
+
+ /**
+ * Logs request info.
+ *
+ * @param msg base log msg
+ * @param request the request to log
+ */
+ private void logRequestInfo(String msg, ServiceComponentHostRequest request) {
+ LOG.info("{}, clusterName={}, serviceName={}, componentName={}, hostname={}, request={}",
+ msg,
+ request.getClusterName(),
+ request.getServiceName(),
+ request.getComponentName(),
+ request.getHostname(),
+ request);
+ }
+
+ /**
+ * Logs component info.
+ *
+ * @param msg base log msg
+ * @param request the request to log
+ * @param oldState current state
+ * @param newDesiredState new desired state
+ */
+ private void logComponentInfo(String msg, ServiceComponentHostRequest request, State oldState, State newDesiredState) {
+ LOG.debug("{}, clusterName={}, serviceName={}, componentName={}, hostname={}, currentState={}, newDesiredState={}",
+ msg,
+ request.getClusterName(),
+ request.getServiceName(),
+ request.getComponentName(),
+ request.getHostname(),
+ oldState == null ? "null" : oldState,
+ newDesiredState == null ? "null" : newDesiredState);
+ }
+
+ /**
+ * Get the "operation level" from the request.
+ *
+ * @param requestProperties request properties
+ * @return the "operation level"
+ */
+ private Resource.Type determineOperationLevel(Map<String, String> requestProperties) {
+ // Determine operation level
+ Resource.Type reqOpLvl;
+ if (requestProperties.containsKey(RequestOperationLevel.OPERATION_LEVEL_ID)) {
+ reqOpLvl = new RequestOperationLevel(requestProperties).getLevel();
+ } else {
+ String message = "Can not determine request operation level. " +
+ "Operation level property should " +
+ "be specified for this request.";
+ LOG.warn(message);
+ reqOpLvl = Resource.Type.Cluster;
+ }
+ return reqOpLvl;
+ }
+
+ /**
+ * Validate a host component request.
+ *
+ * @param request request to validate
+ * @throws IllegalArgumentException if the request is invalid
+ */
+ private void validateServiceComponentHostRequest(ServiceComponentHostRequest request) {
+ if (request.getClusterName() == null
+ || request.getClusterName().isEmpty()
+ || request.getComponentName() == null
+ || request.getComponentName().isEmpty()
+ || request.getHostname() == null
+ || request.getHostname().isEmpty()) {
+ throw new IllegalArgumentException("Invalid arguments"
+ + ", cluster name, component name and host name should be"
+ + " provided");
+ }
+
+ if (request.getAdminState() != null) {
+ throw new IllegalArgumentException("Property adminState cannot be modified through update. Use service " +
+ "specific DECOMMISSION action to decommision/recommission components.");
+ }
+ }
+
+
+ // ----- inner classes ---------------------------------------------------
+
+ /**
+ * Predicate that identifies client components.
+ */
+ private class ClientComponentPredicate implements Predicate {
+ @Override
+ public boolean evaluate(Resource resource) {
+ boolean isClient = false;
+
+ String componentName = (String) resource.getPropertyValue(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+ try {
+ if (componentName != null && !componentName.isEmpty()) {
+ AmbariManagementController managementController = getManagementController();
+ String clusterName = (String) resource.getPropertyValue(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID);
+ String serviceName = (String) resource.getPropertyValue(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID);
+ if (StringUtils.isEmpty(serviceName)) {
+ Cluster cluster = managementController.getClusters().getCluster(clusterName);
+ serviceName = managementController.findServiceName(cluster, componentName);
+ }
+
+ ServiceComponent sc = getServiceComponent((String) resource.getPropertyValue(
+ HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID), serviceName, componentName);
+ isClient = sc.isClientComponent();
+ }
+ } catch (AmbariException e) {
+ // this is really a system exception since cluster/service should have been already verified
+ throw new RuntimeException(
+ "An unexpected exception occurred while trying to determine if a component is a client", e);
+ }
+ return isClient;
+ }
+ }
}