You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/04/18 18:13:28 UTC
ambari git commit: AMBARI-20774 - Service Upgrade VDF Creates Host
Version Entries For All Hosts With INSTALLING (jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/branch-feature-AMBARI-12556 b013be0b9 -> 56f838b5b
AMBARI-20774 - Service Upgrade VDF Creates Host Version Entries For All Hosts With INSTALLING (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/56f838b5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/56f838b5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/56f838b5
Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 56f838b5b0a5681dffb703f503fcf443cb3b6dbd
Parents: b013be0
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Apr 17 17:19:45 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Apr 18 14:13:21 2017 -0400
----------------------------------------------------------------------
.../ClusterStackVersionResourceProvider.java | 136 ++++-----
.../org/apache/ambari/server/state/Cluster.java | 40 ++-
.../server/state/cluster/ClusterImpl.java | 169 +++++++-----
.../server/upgrade/UpgradeCatalog300.java | 8 +-
.../ServicesNamenodeTruncateCheckTest.java | 2 +-
.../AmbariManagementControllerImplTest.java | 6 +-
...ClusterStackVersionResourceProviderTest.java | 273 +++++++++++--------
.../HostVersionOutOfSyncListenerTest.java | 42 ++-
.../server/state/cluster/ClusterTest.java | 62 +++--
9 files changed, 413 insertions(+), 325 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 9c54a9d..e39588e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -20,7 +20,6 @@ package org.apache.ambari.server.controller.internal;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
@@ -77,7 +76,6 @@ import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ComponentInfo;
import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.RepositoryType;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.ServiceComponentHost;
@@ -89,6 +87,7 @@ import org.apache.ambari.server.utils.StageUtils;
import org.apache.ambari.server.utils.VersionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
+import org.apache.hadoop.metrics2.sink.relocated.google.common.collect.Lists;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
@@ -350,10 +349,10 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
stackId = currentStackVersion;
}
- RepositoryVersionEntity repoVersionEnt = repositoryVersionDAO.findByStackAndVersion(
+ RepositoryVersionEntity repoVersionEntity = repositoryVersionDAO.findByStackAndVersion(
stackId, desiredRepoVersion);
- if (repoVersionEnt == null) {
+ if (repoVersionEntity == null) {
throw new IllegalArgumentException(String.format(
"Repo version %s is not available for stack %s",
desiredRepoVersion, stackId));
@@ -361,14 +360,40 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
VersionDefinitionXml desiredVersionDefinition = null;
try {
- desiredVersionDefinition = repoVersionEnt.getRepositoryXml();
+ desiredVersionDefinition = repoVersionEntity.getRepositoryXml();
} catch (Exception e) {
throw new IllegalArgumentException(
String.format("Version %s is backed by a version definition, but it could not be parsed", desiredRepoVersion), e);
}
- // get all of the host eligible for stack distribution
- List<Host> hosts = getHostsForStackDistribution(cluster);
+ // if true, then we need to force all new host versions into the INSTALLED state
+ boolean forceInstalled = Boolean.parseBoolean((String)propertyMap.get(
+ CLUSTER_STACK_VERSION_FORCE));
+
+ try {
+ // either create the necessary host version entries, or set them to INSTALLING when attempting to re-distribute an existing version
+ return createOrUpdateHostVersions(cluster, repoVersionEntity, desiredVersionDefinition,
+ stackId, forceInstalled, propertyMap);
+ } catch (AmbariException e) {
+ throw new SystemException("Can not persist request", e);
+ }
+ }
+
+ @Transactional
+ RequestStatus createOrUpdateHostVersions(Cluster cluster,
+ RepositoryVersionEntity repoVersionEntity, VersionDefinitionXml versionDefinitionXml,
+ StackId stackId, boolean forceInstalled, Map<String, Object> propertyMap)
+ throws AmbariException, SystemException {
+
+ final String clusterName = cluster.getClusterName();
+ final String authName = getManagementController().getAuthName();
+ final String desiredRepoVersion = repoVersionEntity.getVersion();
+
+ ClusterVersionEntity clusterVersionEntity = clusterVersionDAO.findByClusterAndStackAndVersion(
+ clusterName, stackId, desiredRepoVersion);
+
+ // get all of the hosts eligible for stack distribution
+ List<Host> hosts = Lists.newArrayList(cluster.getHosts());
/*
If there is a repository that is already ATTEMPTED to be installed and the version
@@ -384,7 +409,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
install by name. if the package-version is not known, then the 'newest' is ALWAYS installed.
In this case, 2.5.0.0. 2.4 is never picked up.
*/
- for (ClusterVersionEntity clusterVersion : clusterVersionDAO.findByCluster(clName)) {
+ for (ClusterVersionEntity clusterVersion : clusterVersionDAO.findByCluster(cluster.getClusterName())) {
RepositoryVersionEntity clusterRepoVersion = clusterVersion.getRepositoryVersion();
int compare = compareVersions(clusterRepoVersion.getVersion(), desiredRepoVersion);
@@ -397,18 +422,18 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
// !!! the version is greater to the one to install
// if the stacks are different, then don't fail (further check same-stack version strings)
- if (!StringUtils.equals(clusterRepoVersion.getStackName(), repoVersionEnt.getStackName())) {
+ if (!StringUtils.equals(clusterRepoVersion.getStackName(), repoVersionEntity.getStackName())) {
continue;
}
// if there is no backing VDF for the desired version, allow the operation (legacy behavior)
- if (null == desiredVersionDefinition) {
+ if (null == versionDefinitionXml) {
continue;
}
// backing VDF does not define the package version for any of the hosts, cannot install (allows a VDF with package-version)
for (Host host : hosts) {
- if (StringUtils.isBlank(desiredVersionDefinition.getPackageVersion(host.getOsFamily()))) {
+ if (StringUtils.isBlank(versionDefinitionXml.getPackageVersion(host.getOsFamily()))) {
String msg = String.format("Ambari cannot install version %s. Version %s is already installed.",
desiredRepoVersion, clusterRepoVersion.getVersion());
throw new IllegalArgumentException(msg);
@@ -416,49 +441,17 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
}
}
- // if true, then we need to force all new host versions into the INSTALLED state
- boolean forceInstalled = Boolean.parseBoolean((String)propertyMap.get(
- CLUSTER_STACK_VERSION_FORCE));
-
- final RequestStatusResponse response;
-
- try {
- if (forceInstalled) {
- createHostVersions(cluster, hosts, stackId, desiredRepoVersion, RepositoryVersionState.INSTALLED);
- response = null;
- } else {
- createHostVersions(cluster, hosts, stackId, desiredRepoVersion,
- RepositoryVersionState.INSTALLING);
-
- RequestStageContainer installRequest = createOrchestration(cluster, stackId, hosts,
- repoVersionEnt, desiredVersionDefinition, propertyMap);
-
- response = installRequest.getRequestStatusResponse();
- }
- } catch (AmbariException e) {
- throw new SystemException("Can not persist request", e);
+ RepositoryVersionState repositoryVersionState = RepositoryVersionState.INSTALLING;
+ if (forceInstalled) {
+ repositoryVersionState = RepositoryVersionState.INSTALLED;
}
- return getRequestStatus(response);
- }
-
- @Transactional
- void createHostVersions(Cluster cluster, List<Host> hosts, StackId stackId,
- String desiredRepoVersion, RepositoryVersionState repoState)
- throws AmbariException, SystemException {
- final String clusterName = cluster.getClusterName();
- final String authName = getManagementController().getAuthName();
-
- ClusterVersionEntity clusterVersionEntity = clusterVersionDAO.findByClusterAndStackAndVersion(
- clusterName, stackId, desiredRepoVersion);
-
+ // if there is no cluster version entity, then create one
if (clusterVersionEntity == null) {
try {
// Create/persist new cluster stack version
- cluster.createClusterVersion(stackId, desiredRepoVersion, authName, repoState);
-
- clusterVersionEntity = clusterVersionDAO.findByClusterAndStackAndVersion(clusterName,
- stackId, desiredRepoVersion);
+ clusterVersionEntity = cluster.createClusterVersion(stackId, desiredRepoVersion, authName,
+ repositoryVersionState);
} catch (AmbariException e) {
throw new SystemException(
String.format("Can not create cluster stack version %s for cluster %s",
@@ -466,20 +459,22 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
}
} else {
// Move cluster version into the specified state (retry installation)
- cluster.transitionClusterVersion(stackId, desiredRepoVersion, repoState);
+ cluster.transitionClusterVersion(stackId, desiredRepoVersion, repositoryVersionState);
}
- // Will also initialize all Host Versions to the specified state state.
- cluster.transitionHosts(clusterVersionEntity, repoState);
+ // the cluster will create/update all of the host versions to the correct state
+ List<Host> hostsNeedingInstallCommands = cluster.transitionHostsToInstalling(
+ clusterVersionEntity, repoVersionEntity, versionDefinitionXml, forceInstalled);
- // Directly transition host versions to NOT_REQUIRED for hosts that don't
- // have versionable components
- for (Host host : hosts) {
- if (!host.hasComponentsAdvertisingVersions(stackId)) {
- transitionHostVersionToNotRequired(host, cluster,
- clusterVersionEntity.getRepositoryVersion());
- }
+ RequestStatusResponse response = null;
+ if (!forceInstalled) {
+ RequestStageContainer installRequest = createOrchestration(cluster, stackId,
+ hostsNeedingInstallCommands, repoVersionEntity, versionDefinitionXml, propertyMap);
+
+ response = installRequest.getRequestStatusResponse();
}
+
+ return getRequestStatus(response);
}
@Transactional
@@ -910,29 +905,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
}
/**
- * Gets all of the hosts in a cluster which are not in "maintenance mode" and
- * are considered to be healthy. In the case of stack distribution, a host
- * must be explicitely marked as being in maintenance mode for it to be
- * considered as unhealthy.
- *
- * @param cluster
- * the cluster (not {@code null}).
- * @return the list of hosts that are not in maintenance mode and are
- * elidgable to have a stack distributed to them.
- */
- private List<Host> getHostsForStackDistribution(Cluster cluster) {
- Collection<Host> hosts = cluster.getHosts();
- List<Host> healthyHosts = new ArrayList<>(hosts.size());
- for (Host host : hosts) {
- if (host.getMaintenanceState(cluster.getClusterId()) == MaintenanceState.OFF) {
- healthyHosts.add(host);
- }
- }
-
- return healthyHosts;
- }
-
- /**
* Updates the version states. Transactional to ensure only one transaction for all updates
* @param clusterId the cluster
* @param current the repository that is current for the cluster
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/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 c961995..25b4a19 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
@@ -36,6 +36,7 @@ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.server.state.scheduler.RequestExecution;
import com.google.common.collect.ListMultimap;
@@ -229,25 +230,40 @@ public interface Cluster {
/**
* Creates or updates host versions for all of the hosts within a cluster
* based on state of cluster stack version. This is used to transition all
- * hosts into the specified state.
+ * hosts into the correct state (which may not be
+ * {@link RepositoryVersionState#INSTALLING}).
* <p/>
* The difference between this method compared to
* {@link Cluster#mapHostVersions} is that it affects all hosts (not only
* missing hosts).
* <p/>
* Hosts that are in maintenance mode will be transititioned directly into
- * {@link RepositoryVersionState#OUT_OF_SYNC} instead.
+ * {@link RepositoryVersionState#OUT_OF_SYNC} instead. Hosts which do not need
+ * the version distributed to them will move into the
+ * {@link RepositoryVersionState#NOT_REQUIRED} state.
*
* @param sourceClusterVersion
* cluster version to be queried for a stack name/version info and
* desired RepositoryVersionState. The only valid state of a cluster
* version is {@link RepositoryVersionState#INSTALLING}
- * @param state
- * the state to transition the cluster's hosts to.
+ * @param repoVersionEntity
+ * the repository that the hosts are being transitioned for (not
+ * {@code null}).
+ * @param versionDefinitionXml
+ * the VDF, or {@code null} if none.
+ * @param forceInstalled
+ * if {@code true}, then this will transition everything directly to
+ * {@link RepositoryVersionState#INSTALLED} instead of
+ * {@link RepositoryVersionState#INSTALLING}. Hosts which should
+ * received other states (like
+ * {@link RepositoryVersionState#NOT_REQUIRED} will continue to
+ * receive those states.
+ * @return a list of hosts which need the repository installed.
* @throws AmbariException
*/
- void transitionHosts(ClusterVersionEntity sourceClusterVersion, RepositoryVersionState state)
- throws AmbariException;
+ List<Host> transitionHostsToInstalling(ClusterVersionEntity sourceClusterVersion,
+ RepositoryVersionEntity repoVersionEntity, VersionDefinitionXml versionDefinitionXml,
+ boolean forceInstalled) throws AmbariException;
/**
* For a given host, will either either update an existing Host Version Entity for the given version, or create
@@ -280,8 +296,9 @@ public interface Cluster {
* Create a cluster version for the given stack and version, whose initial
* state must either be either {@link RepositoryVersionState#UPGRADING} (if no
* other cluster version exists) or {@link RepositoryVersionState#INSTALLING}
- * (if at exactly one CURRENT cluster version already exists) or {@link RepositoryVersionState#INIT}
- * (if the cluster is being created using a specific repository version).
+ * (if at exactly one CURRENT cluster version already exists) or
+ * {@link RepositoryVersionState#INIT} (if the cluster is being created using
+ * a specific repository version).
*
* @param stackId
* Stack ID
@@ -291,9 +308,10 @@ public interface Cluster {
* User performing the operation
* @param state
* Initial state
+ * @return the newly created and persisted {@link ClusterVersionEntity}.
* @throws AmbariException
*/
- void createClusterVersion(StackId stackId, String version,
+ ClusterVersionEntity createClusterVersion(StackId stackId, String version,
String userName, RepositoryVersionState state) throws AmbariException;
/**
@@ -675,10 +693,10 @@ public interface Cluster {
* Gets an {@link UpgradeEntity} if there is an upgrade in progress or an
* upgrade that has been suspended. This will return the associated
* {@link UpgradeEntity} if it exists.
- *
+ *
* @return an upgrade which will either be in progress or suspended, or
* {@code null} if none.
- *
+ *
*/
UpgradeEntity getUpgradeInProgress();
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/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 b7cc4cd..2e89bb8 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
@@ -124,6 +124,7 @@ import org.apache.ambari.server.state.HostHealthStatus;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.RepositoryType;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.Service;
@@ -141,6 +142,7 @@ import org.apache.ambari.server.state.UpgradeContextFactory;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.server.state.scheduler.RequestExecution;
import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
import org.apache.ambari.server.state.stack.upgrade.Direction;
@@ -1172,99 +1174,115 @@ public class ClusterImpl implements Cluster {
* {@inheritDoc}
*/
@Override
- public void transitionHosts(ClusterVersionEntity sourceClusterVersion,
- RepositoryVersionState state) throws AmbariException {
+ @Transactional
+ public List<Host> transitionHostsToInstalling(ClusterVersionEntity sourceClusterVersion,
+ RepositoryVersionEntity repoVersionEntity, VersionDefinitionXml versionDefinitionXml,
+ boolean forceInstalled) throws AmbariException {
if (sourceClusterVersion == null) {
throw new AmbariException("Could not find current stack version of cluster " + getClusterName());
}
- if (state != sourceClusterVersion.getState()) {
- throw new AmbariException("Unable to transition cluster hosts into " + state
+ if (RepositoryVersionState.INSTALLING != sourceClusterVersion.getState()) {
+ throw new AmbariException(
+ "Unable to transition cluster hosts into " + RepositoryVersionState.INSTALLING
+ ". The only valid state is " + sourceClusterVersion.getState());
}
- Map<String, Host> hosts = clusters.getHostsForCluster(getClusterName());
- Set<String> existingHostsWithClusterStackAndVersion = new HashSet<>();
- HashMap<String, HostVersionEntity> existingHostStackVersions = new HashMap<>();
+ // the hosts to return so that INSTALL commands can be generated for them
+ final List<Host> hostsRequiringInstallation;
clusterGlobalLock.writeLock().lock();
try {
- StackEntity repoVersionStackEntity = sourceClusterVersion.getRepositoryVersion().getStack();
- StackId repoVersionStackId = new StackId(repoVersionStackEntity);
- List<HostVersionEntity> existingHostVersionEntities = hostVersionDAO.findByClusterStackAndVersion(
- getClusterName(), repoVersionStackId,
- sourceClusterVersion.getRepositoryVersion().getVersion());
+ // get this once for easy lookup later
+ Map<String, Host> hosts = clusters.getHostsForCluster(getClusterName());
+ hostsRequiringInstallation = new ArrayList<>(hosts.size());
- // for each host that already has a stack and version, keep track of them
- for (HostVersionEntity entity : existingHostVersionEntities) {
- String hostName = entity.getHostName();
- existingHostsWithClusterStackAndVersion.add(hostName);
- existingHostStackVersions.put(hostName, entity);
- }
+ // for every host, either create or update the host version to the right
+ // state - starting with STATE
+ Collection<HostEntity> hostEntities = getClusterEntity().getHostEntities();
- // find any hosts that do not have the stack/repo version already
- Sets.SetView<String> hostsMissingRepoVersion = Sets.difference(
- hosts.keySet(), existingHostsWithClusterStackAndVersion);
+ for (HostEntity hostEntity : hostEntities) {
+ // start with INSTALLING
+ RepositoryVersionState state = RepositoryVersionState.INSTALLING;
+ if (forceInstalled) {
+ state = RepositoryVersionState.INSTALLED;
+ }
- createOrUpdateHostVersionToState(sourceClusterVersion, hosts,
- existingHostStackVersions, hostsMissingRepoVersion, state);
- } finally {
- clusterGlobalLock.writeLock().unlock();
- }
- }
+ // is this host version not required b/c of versionable components
+ Host host = hosts.get(hostEntity.getHostName());
+ if (!host.hasComponentsAdvertisingVersions(desiredStackVersion)) {
+ state = RepositoryVersionState.NOT_REQUIRED;
+ }
- /**
- * Moved out to a separate method due to performance reasons
- * Iterates over all hosts and creates or transitions existing host versions
- * to a given state. If host version for desired stack/version does not exist,
- * host version is created and initialized to a given state. Otherwise, existing
- * host version state is updated
- * Hosts in maintenance mode are auto skipped.
- *
- * @param sourceClusterVersion cluster version to be queried for a stack
- * name/version info when creating a new host version
- * @param hosts list of all hosts
- * @param existingHostStackVersions map of existing host versions to be updated
- * @param hostsMissingRepoVersion set of hostnames of hosts that have no desired host version
- * @param newState target host version state for transition
- */
- @Transactional
- void createOrUpdateHostVersionToState(ClusterVersionEntity sourceClusterVersion,
- Map<String, Host> hosts, HashMap<String, HostVersionEntity> existingHostStackVersions,
- Sets.SetView<String> hostsMissingRepoVersion, RepositoryVersionState newState) {
+ // if the repository is still required, check against the repo type
+ if (state != RepositoryVersionState.NOT_REQUIRED) {
+ if (repoVersionEntity.getType() != RepositoryType.STANDARD) {
+ // does the host gets a different repo state based on VDF and repo
+ // type
+ boolean hostRequiresRepository = false;
+ Set<String> servicesInRepository = versionDefinitionXml.getAvailableServiceNames();
+
+ List<ServiceComponentHost> schs = getServiceComponentHosts(hostEntity.getHostName());
+ for (ServiceComponentHost serviceComponentHost : schs) {
+ String serviceName = serviceComponentHost.getServiceName();
+ if (servicesInRepository.contains(serviceName)) {
+ hostRequiresRepository = true;
+ break;
+ }
+ }
- for (String hostname : hosts.keySet()) {
- // start off with the requested new state for each host
- RepositoryVersionState repositoryVersionState = newState;
+ // if not required, then move onto the next host
+ if (!hostRequiresRepository) {
+ state = RepositoryVersionState.NOT_REQUIRED;
+ }
+ }
+ }
- // if the host is in maintenance mode, that's an explicit marker which
- // indicates that it should not be transitioned to INSTALLING; instead
- // they will be transitioned to OUT_OF_SYNC
- Host host = hosts.get(hostname);
- if (host.getMaintenanceState(getClusterId()) != MaintenanceState.OFF) {
- repositoryVersionState = RepositoryVersionState.OUT_OF_SYNC;
- }
+ // last check if it's still required - check for MM
+ if (state != RepositoryVersionState.NOT_REQUIRED) {
+ if (host.getMaintenanceState(clusterId) != MaintenanceState.OFF) {
+ state = RepositoryVersionState.OUT_OF_SYNC;
+ }
+ }
- if (hostsMissingRepoVersion.contains(hostname)) {
- // Create new host stack version
- HostEntity hostEntity = hostDAO.findByName(hostname);
- HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntity,
- sourceClusterVersion.getRepositoryVersion(), repositoryVersionState);
+ // now that the correct state is determdined for the host version,
+ // either update or create it
+ HostVersionEntity hostVersionEntity = null;
+ Collection<HostVersionEntity> hostVersions = hostEntity.getHostVersionEntities();
+ for (HostVersionEntity existingHostVersion : hostVersions) {
+ if (existingHostVersion.getRepositoryVersion().getId() == repoVersionEntity.getId()) {
+ hostVersionEntity = existingHostVersion;
+ break;
+ }
+ }
- LOG.info("Creating host version for {}, state={}, repo={} (repo_id={})",
+ if (null == hostVersionEntity) {
+ hostVersionEntity = new HostVersionEntity(hostEntity, repoVersionEntity, state);
+ hostVersionDAO.create(hostVersionEntity);
+
+ // bi-directional association update
+ hostVersions.add(hostVersionEntity);
+ hostDAO.merge(hostEntity);
+ } else {
+ hostVersionEntity.setState(state);
+ hostVersionEntity = hostVersionDAO.merge(hostVersionEntity);
+ }
+
+ LOG.info("Created host version for {}, state={}, repository version={} (repo_id={})",
hostVersionEntity.getHostName(), hostVersionEntity.getState(),
- hostVersionEntity.getRepositoryVersion().getVersion(), hostVersionEntity.getRepositoryVersion().getId());
+ repoVersionEntity.getVersion(), repoVersionEntity.getId());
- hostVersionDAO.create(hostVersionEntity);
- } else {
- // Update existing host stack version
- HostVersionEntity hostVersionEntity = existingHostStackVersions.get(hostname);
- hostVersionEntity.setState(repositoryVersionState);
- hostVersionEntity = hostVersionDAO.merge(hostVersionEntity);
+ if (state == RepositoryVersionState.INSTALLING) {
+ hostsRequiringInstallation.add(host);
+ }
}
+ } finally {
+ clusterGlobalLock.writeLock().unlock();
}
+
+ return hostsRequiringInstallation;
}
/**
@@ -1597,11 +1615,11 @@ public class ClusterImpl implements Cluster {
}
@Override
- public void createClusterVersion(StackId stackId, String version,
+ public ClusterVersionEntity createClusterVersion(StackId stackId, String version,
String userName, RepositoryVersionState state) throws AmbariException {
clusterGlobalLock.writeLock().lock();
try {
- createClusterVersionInternal(stackId, version, userName, state);
+ return createClusterVersionInternal(stackId, version, userName, state);
} finally {
clusterGlobalLock.writeLock().unlock();
}
@@ -1612,7 +1630,7 @@ public class ClusterImpl implements Cluster {
*
* This method is intended to be called only when cluster lock is already acquired.
*/
- private void createClusterVersionInternal(StackId stackId, String version,
+ private ClusterVersionEntity createClusterVersionInternal(StackId stackId, String version,
String userName, RepositoryVersionState state) throws AmbariException {
if (!ALLOWED_REPOSITORY_STATES.contains(state)) {
throw new AmbariException("The allowed state for a new cluster version must be within " + ALLOWED_REPOSITORY_STATES);
@@ -1630,9 +1648,8 @@ public class ClusterImpl implements Cluster {
RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackAndVersion(
stackId, version);
if (repositoryVersionEntity == null) {
- LOG.warn("Could not find repository version for stack=" + stackId
- + ", version=" + version);
- return;
+ throw new AmbariException(
+ "Unable to find repository version for stack " + stackId + " and version " + version);
}
ClusterEntity clusterEntity = getClusterEntity();
@@ -1642,6 +1659,8 @@ public class ClusterImpl implements Cluster {
clusterVersionDAO.create(clusterVersionEntity);
clusterEntity.getClusterVersionEntities().add(clusterVersionEntity);
clusterEntity = clusterDAO.merge(clusterEntity);
+
+ return clusterVersionEntity;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index 0b1d538..4a3d0e0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -36,9 +36,9 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
import org.apache.ambari.server.controller.internal.CalculatedStatus;
import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
import org.apache.ambari.server.orm.dao.DaoUtils;
import org.apache.ambari.server.orm.dao.RequestDAO;
import org.apache.ambari.server.orm.entities.RequestEntity;
@@ -291,7 +291,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
// the cluster configuration mapping table
dbAccessor.dropTable(CLUSTER_CONFIG_MAPPING_TABLE);
}
-
+
/**
* Updates Log Search configs.
*
@@ -311,12 +311,12 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
if (!configType.endsWith("-logsearch-conf")) {
continue;
}
-
+
Set<String> removeProperties = new HashSet<>();
removeProperties.add("service_name");
removeProperties.add("component_mappings");
removeProperties.add("content");
-
+
removeConfigurationPropertiesFromCluster(cluster, configType, removeProperties);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
index 2954f0d..ca71e3f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServicesNamenodeTruncateCheckTest.java
@@ -53,8 +53,8 @@ public class ServicesNamenodeTruncateCheckTest {
private Clusters m_clusters = EasyMock.createMock(Clusters.class);
private ServicesNamenodeTruncateCheck m_check = new ServicesNamenodeTruncateCheck();
- private RepositoryVersionDAO m_repositoryVersionDAO = EasyMock.createMock(RepositoryVersionDAO.class);
private final Map<String, String> m_configMap = new HashMap<>();
+ private RepositoryVersionDAO m_repositoryVersionDAO = EasyMock.createMock(RepositoryVersionDAO.class);
@Before
public void setup() throws Exception {
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index 625ac8a..f35122a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -2359,8 +2359,10 @@ public class AmbariManagementControllerImplTest {
expect(cluster.getDesiredStackVersion()).andReturn(new StackId("HDP-2.1")).atLeastOnce();
// this getting called one time means the cluster version is getting created
- cluster.createClusterVersion(anyObject(StackId.class), anyObject(String.class), anyObject(String.class), anyObject(RepositoryVersionState.class));
- expectLastCall().once();
+ ClusterVersionEntity clusterVersionEntity = createNiceMock(ClusterVersionEntity.class);
+ expect(cluster.createClusterVersion(anyObject(StackId.class), anyObject(String.class),
+ anyObject(String.class), anyObject(RepositoryVersionState.class))).andReturn(
+ clusterVersionEntity).once();
expect(clusters.getCluster("c1")).andReturn(cluster).atLeastOnce();
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index 5ef31b5..8f7b31d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -19,111 +19,112 @@
package org.apache.ambari.server.controller.internal;
import static org.easymock.EasyMock.anyLong;
- import static org.easymock.EasyMock.anyObject;
- import static org.easymock.EasyMock.capture;
- import static org.easymock.EasyMock.createMock;
- import static org.easymock.EasyMock.createNiceMock;
- import static org.easymock.EasyMock.eq;
- import static org.easymock.EasyMock.expect;
- import static org.easymock.EasyMock.expectLastCall;
- import static org.easymock.EasyMock.replay;
- import static org.easymock.EasyMock.verify;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.lang.reflect.Field;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.LinkedHashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.Set;
-
- import org.apache.ambari.annotations.Experimental;
- import org.apache.ambari.annotations.ExperimentalFeature;
- import org.apache.ambari.server.AmbariException;
- import org.apache.ambari.server.H2DatabaseCleaner;
- import org.apache.ambari.server.Role;
- import org.apache.ambari.server.actionmanager.ActionManager;
- import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
- import org.apache.ambari.server.actionmanager.HostRoleCommand;
- import org.apache.ambari.server.actionmanager.Stage;
- import org.apache.ambari.server.actionmanager.StageFactory;
- import org.apache.ambari.server.agent.CommandReport;
- import org.apache.ambari.server.agent.ExecutionCommand;
- import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
- import org.apache.ambari.server.api.services.AmbariMetaInfo;
- import org.apache.ambari.server.configuration.Configuration;
- import org.apache.ambari.server.controller.AmbariManagementController;
- import org.apache.ambari.server.controller.ExecuteActionRequest;
- import org.apache.ambari.server.controller.RequestStatusResponse;
- import org.apache.ambari.server.controller.ResourceProviderFactory;
- 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.PropertyHelper;
- import org.apache.ambari.server.orm.GuiceJpaInitializer;
- import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
- import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
- import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
- import org.apache.ambari.server.orm.dao.HostVersionDAO;
- import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
- import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
- import org.apache.ambari.server.orm.dao.StackDAO;
- import org.apache.ambari.server.orm.entities.ClusterEntity;
- import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
- import org.apache.ambari.server.orm.entities.HostVersionEntity;
- import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
- import org.apache.ambari.server.orm.entities.ResourceEntity;
- import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
- import org.apache.ambari.server.orm.entities.StackEntity;
- import org.apache.ambari.server.orm.entities.UpgradeEntity;
- import org.apache.ambari.server.security.TestAuthenticationFactory;
- import org.apache.ambari.server.security.authorization.AuthorizationException;
- import org.apache.ambari.server.security.authorization.ResourceType;
- import org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction;
- import org.apache.ambari.server.state.Cluster;
- import org.apache.ambari.server.state.Clusters;
- import org.apache.ambari.server.state.ConfigHelper;
- import org.apache.ambari.server.state.Host;
- import org.apache.ambari.server.state.MaintenanceState;
- import org.apache.ambari.server.state.RepositoryType;
- import org.apache.ambari.server.state.RepositoryVersionState;
- 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.ServiceInfo;
- import org.apache.ambari.server.state.ServiceOsSpecific;
- import org.apache.ambari.server.state.StackId;
- import org.apache.ambari.server.state.cluster.ClusterImpl;
- import org.apache.ambari.server.state.stack.upgrade.Direction;
- import org.apache.ambari.server.topology.TopologyManager;
- import org.apache.ambari.server.utils.StageUtils;
- import org.apache.commons.io.IOUtils;
- import org.easymock.Capture;
- import org.easymock.EasyMock;
- import org.easymock.IAnswer;
- import org.junit.After;
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.Ignore;
- import org.junit.Test;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.context.SecurityContextHolder;
-
- import com.google.gson.JsonArray;
- import com.google.gson.JsonObject;
- import com.google.gson.JsonParser;
- import com.google.inject.AbstractModule;
- import com.google.inject.Guice;
- import com.google.inject.Injector;
- import com.google.inject.util.Modules;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.reflect.Field;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.H2DatabaseCleaner;
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.actionmanager.ActionManager;
+import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.Stage;
+import org.apache.ambari.server.actionmanager.StageFactory;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ExecuteActionRequest;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.ResourceProviderFactory;
+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.PropertyHelper;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
+import org.apache.ambari.server.orm.dao.HostVersionDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.HostVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
+import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.security.TestAuthenticationFactory;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.RepositoryType;
+import org.apache.ambari.server.state.RepositoryVersionState;
+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.ServiceInfo;
+import org.apache.ambari.server.state.ServiceOsSpecific;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.cluster.ClusterImpl;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.topology.TopologyManager;
+import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.util.Modules;
/**
@@ -222,6 +223,9 @@ public class ClusterStackVersionResourceProviderTest {
repoVersion.setId(1l);
repoVersion.setOperatingSystems(OS_JSON);
+ final String hostWithoutVersionableComponents = "host2";
+
+ List<Host> hostsNeedingInstallCommands = new ArrayList<>();
Map<String, Host> hostsForCluster = new HashMap<>();
int hostCount = 10;
for (int i = 0; i < hostCount; i++) {
@@ -236,6 +240,10 @@ public class ClusterStackVersionResourceProviderTest {
replay(host);
hostsForCluster.put(hostname, host);
+
+ if (!StringUtils.equals(hostWithoutVersionableComponents, hostname)) {
+ hostsNeedingInstallCommands.add(host);
+ }
}
final ServiceComponentHost schDatanode = createMock(ServiceComponentHost.class);
@@ -300,7 +308,7 @@ public class ClusterStackVersionResourceProviderTest {
@Override
public List<ServiceComponentHost> answer() throws Throwable {
String hostname = (String) EasyMock.getCurrentArguments()[0];
- if (hostname.equals("host2")) {
+ if (hostname.equals(hostWithoutVersionableComponents)) {
return schsH2;
} else {
return schsH1;
@@ -308,6 +316,10 @@ public class ClusterStackVersionResourceProviderTest {
}
}).anyTimes();
+ expect(cluster.transitionHostsToInstalling(anyObject(ClusterVersionEntity.class),
+ anyObject(RepositoryVersionEntity.class), anyObject(VersionDefinitionXml.class),
+ eq(false))).andReturn(hostsNeedingInstallCommands).atLeastOnce();
+
ExecutionCommand executionCommand = createNiceMock(ExecutionCommand.class);
ExecutionCommandWrapper executionCommandWrapper = createNiceMock(ExecutionCommandWrapper.class);
@@ -644,7 +656,8 @@ public class ClusterStackVersionResourceProviderTest {
ambariMetaInfo.getComponent("HDP", "2.1.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
-
+ final String hostWithoutVersionableComponents = "host3";
+ List<Host> hostsNeedingInstallCommands = new ArrayList<>();
Map<String, Host> hostsForCluster = new HashMap<>();
int hostCount = 10;
for (int i = 0; i < hostCount; i++) {
@@ -659,6 +672,11 @@ public class ClusterStackVersionResourceProviderTest {
replay(host);
hostsForCluster.put(hostname, host);
+
+
+ if (!StringUtils.equals(hostWithoutVersionableComponents, hostname)) {
+ hostsNeedingInstallCommands.add(host);
+ }
}
Service hdfsService = createNiceMock(Service.class);
@@ -735,7 +753,7 @@ public class ClusterStackVersionResourceProviderTest {
@Override
public List<ServiceComponentHost> answer() throws Throwable {
String hostname = (String) EasyMock.getCurrentArguments()[0];
- if (hostname.equals("host2")) {
+ if (hostname.equals("host2")) {
return schsH2;
} else if (hostname.equals("host3")) {
return schsH3;
@@ -745,6 +763,10 @@ public class ClusterStackVersionResourceProviderTest {
}
}).anyTimes();
+ expect(cluster.transitionHostsToInstalling(anyObject(ClusterVersionEntity.class),
+ anyObject(RepositoryVersionEntity.class), anyObject(VersionDefinitionXml.class),
+ eq(false))).andReturn(hostsNeedingInstallCommands).atLeastOnce();
+
// ExecutionCommand executionCommand = createNiceMock(ExecutionCommand.class);
ExecutionCommand executionCommand = new ExecutionCommand();
ExecutionCommandWrapper executionCommandWrapper = createNiceMock(ExecutionCommandWrapper.class);
@@ -877,6 +899,9 @@ public class ClusterStackVersionResourceProviderTest {
ambariMetaInfo.getComponent("HDP", "2.1.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
+ final String hostWithoutVersionableComponents = "host3";
+ List<Host> hostsNeedingInstallCommands = new ArrayList<>();
+
Map<String, Host> hostsForCluster = new HashMap<>();
int hostCount = 10;
for (int i = 0; i < hostCount; i++) {
@@ -891,6 +916,10 @@ public class ClusterStackVersionResourceProviderTest {
replay(host);
hostsForCluster.put(hostname, host);
+
+ if (!StringUtils.equals(hostWithoutVersionableComponents, hostname)) {
+ hostsNeedingInstallCommands.add(host);
+ }
}
Service hdfsService = createNiceMock(Service.class);
@@ -977,6 +1006,10 @@ public class ClusterStackVersionResourceProviderTest {
}
}).anyTimes();
+ expect(cluster.transitionHostsToInstalling(anyObject(ClusterVersionEntity.class),
+ anyObject(RepositoryVersionEntity.class), anyObject(VersionDefinitionXml.class),
+ eq(false))).andReturn(hostsNeedingInstallCommands).atLeastOnce();
+
// ExecutionCommand executionCommand = createNiceMock(ExecutionCommand.class);
ExecutionCommand executionCommand = new ExecutionCommand();
ExecutionCommandWrapper executionCommandWrapper = createNiceMock(ExecutionCommandWrapper.class);
@@ -998,10 +1031,8 @@ public class ClusterStackVersionResourceProviderTest {
anyObject(String.class))).andReturn(stage).
times((int) Math.ceil(hostCount / MAX_TASKS_PER_STAGE));
- expect(
- repositoryVersionDAOMock.findByStackAndVersion(
- anyObject(StackId.class),
- anyObject(String.class))).andReturn(repoVersion);
+ expect(repositoryVersionDAOMock.findByStackAndVersion(anyObject(StackId.class),
+ anyObject(String.class))).andReturn(repoVersion);
Capture<org.apache.ambari.server.actionmanager.Request> c = Capture.newInstance();
Capture<ExecuteActionRequest> ear = Capture.newInstance();
@@ -1636,7 +1667,9 @@ public class ClusterStackVersionResourceProviderTest {
repoVersionEntity.setVersionXml(IOUtils.toString(new FileInputStream(f)));
repoVersionEntity.setVersionXsd("version_definition.xsd");
repoVersionEntity.setType(RepositoryType.STANDARD);
+ repoVersionEntity.setVersion(repoVersion);
+ List<Host> hostsNeedingInstallCommands = new ArrayList<>();
Map<String, Host> hostsForCluster = new HashMap<>();
List<HostVersionEntity> hostVersionEntitiesMergedWithNotRequired = new ArrayList<>();
int hostCount = 10;
@@ -1652,6 +1685,7 @@ public class ClusterStackVersionResourceProviderTest {
// transition correct into the not required state
if (i < hostCount - 2) {
expect(host.hasComponentsAdvertisingVersions(eq(stackId))).andReturn(true).atLeastOnce();
+ hostsNeedingInstallCommands.add(host);
} else {
expect(host.hasComponentsAdvertisingVersions(eq(stackId))).andReturn(false).atLeastOnce();
@@ -1662,7 +1696,8 @@ public class ClusterStackVersionResourceProviderTest {
replay(hostVersionEntity);
hostVersionEntitiesMergedWithNotRequired.add(hostVersionEntity);
- expect(host.getAllHostVersions()).andReturn(hostVersionEntitiesMergedWithNotRequired).anyTimes();
+ expect(host.getAllHostVersions()).andReturn(
+ hostVersionEntitiesMergedWithNotRequired).anyTimes();
}
replay(host);
@@ -1735,15 +1770,15 @@ public class ClusterStackVersionResourceProviderTest {
// then return the real one it's going to use
expect(clusterVersionDAO.findByClusterAndStackAndVersion(anyObject(String.class),
anyObject(StackId.class), anyObject(String.class))).andReturn(null).once();
- expect(clusterVersionDAO.findByClusterAndStackAndVersion(anyObject(String.class),
- anyObject(StackId.class), anyObject(String.class))).andReturn(cve).once();
+
+ expect(cluster.createClusterVersion(anyObject(StackId.class), eq(repoVersion),
+ EasyMock.anyString(), eq(RepositoryVersionState.INSTALLED))).andReturn(cve).once();
// now the important expectations - that the cluster transition methods were
// called correctly
- cluster.transitionHosts(cve, RepositoryVersionState.INSTALLED);
- for (HostVersionEntity hostVersionEntity : hostVersionEntitiesMergedWithNotRequired) {
- expect(hostVersionDAO.merge(hostVersionEntity)).andReturn(hostVersionEntity).once();
- }
+ expect(cluster.transitionHostsToInstalling(cve, repoVersionEntity,
+ repoVersionEntity.getRepositoryXml(), true)).andReturn(
+ hostsNeedingInstallCommands).once();
// replay
replay(managementController, response, clusters, hdfsService, resourceProviderFactory,
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
index dc9ce5e..fef9276 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
@@ -71,6 +71,8 @@ public class HostVersionOutOfSyncListenerTest {
private final String stackId = "HDP-2.2.0";
private final String yetAnotherStackId = "HDP-2.1.1";
+ private final String CURRENT_VERSION = "2.2.0-2086";
+
private Injector injector;
@Inject
@@ -122,9 +124,6 @@ public class HostVersionOutOfSyncListenerTest {
* @throws AmbariException
*/
private void createClusterAndHosts(String INSTALLED_VERSION, StackId stackId) throws AmbariException {
- // Configuring 3-node cluster with 2 repo versions
- String CURRENT_VERSION = "2.2.0-2086";
-
Host h1 = clusters.getHost("h1");
h1.setState(HostState.HEALTHY);
@@ -133,6 +132,10 @@ public class HostVersionOutOfSyncListenerTest {
addHost("h3");
clusters.mapHostToCluster("h3", "c1");
+ // create the new repo version
+ RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(stackId,
+ INSTALLED_VERSION);
+
c1.createClusterVersion(stackId, INSTALLED_VERSION, "admin", RepositoryVersionState.INSTALLING);
c1.setCurrentStackVersion(stackId);
c1.recalculateAllClusterVersionStates();
@@ -151,13 +154,14 @@ public class HostVersionOutOfSyncListenerTest {
zkTopology.put("ZOOKEEPER_SERVER", new ArrayList<>(zkServerHosts));
addService(c1, hostList, zkTopology, "ZOOKEEPER");
- // Register and install new version
- RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(stackId,
- INSTALLED_VERSION);
+ // install new version
helper.createHostVersion("h1", repositoryVersionEntity, RepositoryVersionState.INSTALLED);
+ helper.createHostVersion("h2", repositoryVersionEntity, RepositoryVersionState.INSTALLED);
+ helper.createHostVersion("h3", repositoryVersionEntity, RepositoryVersionState.INSTALLED);
+
c1.recalculateAllClusterVersionStates();
- assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,
- RepositoryVersionState.INSTALLED);
+
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION, RepositoryVersionState.INSTALLED);
assertRepoVersionState(stackId.getStackId(), CURRENT_VERSION, RepositoryVersionState.CURRENT);
// Add new host and verify that it has all host versions present
@@ -210,9 +214,15 @@ public class HostVersionOutOfSyncListenerTest {
StackId stackId = new StackId(this.stackId);
StackId yaStackId = new StackId(yetAnotherStackId);
+ // get new hosts installed with the first repo
createClusterAndHosts(INSTALLED_VERSION, stackId);
+
+ // register the new repo
addRepoVersion(INSTALLED_VERSION_2, yaStackId);
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,RepositoryVersionState.INSTALLED);
+ assertRepoVersionState(yaStackId.getStackId(), INSTALLED_VERSION_2,RepositoryVersionState.INSTALLED);
+ assertRepoVersionState(yaStackId.getStackId(), CURRENT_VERSION, RepositoryVersionState.CURRENT);
//Add HDFS service
List<String> hostList = new ArrayList<>();
@@ -233,10 +243,6 @@ public class HostVersionOutOfSyncListenerTest {
List<HostVersionEntity> hostVersions = hostVersionDAO.findAll();
- assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,
- RepositoryVersionState.INSTALLED);
- assertRepoVersionState(yaStackId.getStackId(), INSTALLED_VERSION_2,
- RepositoryVersionState.INSTALLED);
for (HostVersionEntity hostVersionEntity : hostVersions) {
if (hostVersionEntity.getRepositoryVersion().getVersion().equals(INSTALLED_VERSION) ||
hostVersionEntity.getRepositoryVersion().getVersion().equals(INSTALLED_VERSION_2)) {
@@ -247,6 +253,11 @@ public class HostVersionOutOfSyncListenerTest {
}
}
}
+
+
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,RepositoryVersionState.OUT_OF_SYNC);
+ assertRepoVersionState(yaStackId.getStackId(), INSTALLED_VERSION_2,RepositoryVersionState.OUT_OF_SYNC);
+ assertRepoVersionState(yaStackId.getStackId(), CURRENT_VERSION, RepositoryVersionState.CURRENT);
}
@@ -306,6 +317,9 @@ public class HostVersionOutOfSyncListenerTest {
createClusterAndHosts(INSTALLED_VERSION, stackId);
addRepoVersion(INSTALLED_VERSION_2, yaStackId);
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION, RepositoryVersionState.INSTALLED);
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION_2, RepositoryVersionState.INSTALLED);
+
//Add ZOOKEEPER_CLIENT component
List<String> hostList = new ArrayList<>();
hostList.add("h1");
@@ -319,8 +333,8 @@ public class HostVersionOutOfSyncListenerTest {
changedHosts.add("h2");
changedHosts.add("h3");
- assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,
- RepositoryVersionState.INSTALLED);
+ assertRepoVersionState(stackId.getStackId(), INSTALLED_VERSION,RepositoryVersionState.OUT_OF_SYNC);
+
List<HostVersionEntity> hostVersions = hostVersionDAO.findAll();
for (HostVersionEntity hostVersionEntity : hostVersions) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/56f838b5/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
index 345c463..e5e2643 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
@@ -224,8 +224,12 @@ public class ClusterTest {
}
private void createDefaultCluster(Set<String> hostNames) throws Exception {
- // TODO, use common function
StackId stackId = new StackId("HDP", "0.1");
+ createDefaultCluster(hostNames, stackId);
+ }
+
+ private void createDefaultCluster(Set<String> hostNames, StackId stackId) throws Exception {
+ // TODO, use common function
StackEntity stackEntity = stackDAO.find(stackId.getStackName(), stackId.getStackVersion());
org.junit.Assert.assertNotNull(stackEntity);
@@ -1638,19 +1642,20 @@ public class ClusterTest {
* Tests that hosts can be correctly transitioned into the "INSTALLING" state.
* This method also tests that hosts in MM will not be transitioned, as per
* the contract of
- * {@link Cluster#transitionHostsToInstalling(ClusterVersionEntity)}.
+ * {@link Cluster#transitionHostsToInstalling(ClusterVersionEntity, RepositoryVersionEntity, org.apache.ambari.server.state.repository.VersionDefinitionXml, boolean)}.
*
* @throws Exception
*/
@Test
- public void testTransitionHostVersions() throws Exception {
- createDefaultCluster();
+ public void testTransitionHostsToInstalling() throws Exception {
+ // this will create a cluster with a few hosts and no host components
+ StackId originalStackId = new StackId("HDP", "2.0.5");
+ createDefaultCluster(Sets.newHashSet("h1", "h2"), originalStackId);
- StackId stackId = new StackId("HDP", "0.2");
+ StackId stackId = new StackId("HDP", "2.0.6");
helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion());
- c1.createClusterVersion(stackId, "0.2", "admin",
- RepositoryVersionState.INSTALLING);
+ c1.createClusterVersion(stackId, "2.0.6", "admin", RepositoryVersionState.INSTALLING);
ClusterVersionEntity entityHDP2 = null;
for (ClusterVersionEntity entity : c1.getAllClusterVersions()) {
@@ -1658,7 +1663,7 @@ public class ClusterTest {
StackId repoVersionStackId = new StackId(repoVersionStackEntity);
if (repoVersionStackId.getStackName().equals("HDP")
- && repoVersionStackId.getStackVersion().equals("0.2")) {
+ && repoVersionStackId.getStackVersion().equals("2.0.6")) {
entityHDP2 = entity;
break;
}
@@ -1669,7 +1674,9 @@ public class ClusterTest {
List<HostVersionEntity> hostVersionsH1Before = hostVersionDAO.findByClusterAndHost("c1", "h1");
assertEquals(1, hostVersionsH1Before.size());
- c1.transitionHosts(entityHDP2, RepositoryVersionState.INSTALLING);
+ // this should move both to NOT_REQUIRED since they have no versionable
+ // components
+ c1.transitionHostsToInstalling(entityHDP2, entityHDP2.getRepositoryVersion(), null, false);
List<HostVersionEntity> hostVersionsH1After = hostVersionDAO.findByClusterAndHost("c1", "h1");
assertEquals(2, hostVersionsH1After.size());
@@ -1678,8 +1685,8 @@ public class ClusterTest {
for (HostVersionEntity entity : hostVersionsH1After) {
StackEntity repoVersionStackEntity = entity.getRepositoryVersion().getStack();
if (repoVersionStackEntity.getStackName().equals("HDP")
- && repoVersionStackEntity.getStackVersion().equals("0.2")) {
- assertEquals(RepositoryVersionState.INSTALLING, entity.getState());
+ && repoVersionStackEntity.getStackVersion().equals("2.0.6")) {
+ assertEquals(RepositoryVersionState.NOT_REQUIRED, entity.getState());
checked = true;
break;
}
@@ -1687,8 +1694,29 @@ public class ClusterTest {
assertTrue(checked);
- // Test for update of existing host stack version
- c1.transitionHosts(entityHDP2, RepositoryVersionState.INSTALLING);
+ // add some host components
+ Service hdfs = serviceFactory.createNew(c1, "HDFS");
+ c1.addService(hdfs);
+
+ // Add HDFS components
+ ServiceComponent datanode = serviceComponentFactory.createNew(hdfs, "NAMENODE");
+ ServiceComponent namenode = serviceComponentFactory.createNew(hdfs, "DATANODE");
+ hdfs.addServiceComponent(datanode);
+ hdfs.addServiceComponent(namenode);
+
+ // add to hosts
+ ServiceComponentHost namenodeHost1 = serviceComponentHostFactory.createNew(namenode, "h1");
+ ServiceComponentHost datanodeHost2 = serviceComponentHostFactory.createNew(datanode, "h2");
+
+ assertNotNull(namenodeHost1);
+ assertNotNull(datanodeHost2);
+
+ c1.transitionClusterVersion(stackId, entityHDP2.getRepositoryVersion().getVersion(),
+ RepositoryVersionState.INSTALLING);
+
+ // with hosts now having components which report versions, we should have
+ // two in the INSTALLING state
+ c1.transitionHostsToInstalling(entityHDP2, entityHDP2.getRepositoryVersion(), null, false);
hostVersionsH1After = hostVersionDAO.findByClusterAndHost("c1", "h1");
assertEquals(2, hostVersionsH1After.size());
@@ -1697,7 +1725,7 @@ public class ClusterTest {
for (HostVersionEntity entity : hostVersionsH1After) {
StackEntity repoVersionStackEntity = entity.getRepositoryVersion().getStack();
if (repoVersionStackEntity.getStackName().equals("HDP")
- && repoVersionStackEntity.getStackVersion().equals("0.2")) {
+ && repoVersionStackEntity.getStackVersion().equals("2.0.6")) {
assertEquals(RepositoryVersionState.INSTALLING, entity.getState());
checked = true;
break;
@@ -1727,7 +1755,7 @@ public class ClusterTest {
hostInMaintenanceMode.setMaintenanceState(c1.getClusterId(), MaintenanceState.ON);
// transition host versions to INSTALLING
- c1.transitionHosts(entityHDP2, RepositoryVersionState.INSTALLING);
+ c1.transitionHostsToInstalling(entityHDP2, entityHDP2.getRepositoryVersion(), null, false);
List<HostVersionEntity> hostInMaintModeVersions = hostVersionDAO.findByClusterAndHost("c1",
hostInMaintenanceMode.getHostName());
@@ -1739,7 +1767,7 @@ public class ClusterTest {
for (HostVersionEntity hostVersionEntity : hostInMaintModeVersions) {
StackEntity repoVersionStackEntity = hostVersionEntity.getRepositoryVersion().getStack();
if (repoVersionStackEntity.getStackName().equals("HDP")
- && repoVersionStackEntity.getStackVersion().equals("0.2")) {
+ && repoVersionStackEntity.getStackVersion().equals("2.0.6")) {
assertEquals(RepositoryVersionState.OUT_OF_SYNC, hostVersionEntity.getState());
}
}
@@ -1748,7 +1776,7 @@ public class ClusterTest {
for (HostVersionEntity hostVersionEntity : otherHostVersions) {
StackEntity repoVersionStackEntity = hostVersionEntity.getRepositoryVersion().getStack();
if (repoVersionStackEntity.getStackName().equals("HDP")
- && repoVersionStackEntity.getStackVersion().equals("0.2")) {
+ && repoVersionStackEntity.getStackVersion().equals("2.0.6")) {
assertEquals(RepositoryVersionState.INSTALLING, hostVersionEntity.getState());
}
}