You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2015/01/19 21:31:48 UTC
ambari git commit: AMBARI-9183. Rollling Upgrade - Server bootstrap
creates incorrect repo version (Yurii Shylov via ncole)
Repository: ambari
Updated Branches:
refs/heads/trunk 01fa8eb03 -> fe3f405fa
AMBARI-9183. Rollling Upgrade - Server bootstrap creates incorrect repo version (Yurii Shylov via ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fe3f405f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fe3f405f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fe3f405f
Branch: refs/heads/trunk
Commit: fe3f405fadeafec62e2e257a60342fe7ebe52484
Parents: 01fa8eb
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Jan 19 15:15:03 2015 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Jan 19 15:15:03 2015 -0500
----------------------------------------------------------------------
.../ambari/server/agent/HeartBeatHandler.java | 14 ++-
.../AmbariManagementControllerImpl.java | 19 ---
.../internal/UpgradeResourceProvider.java | 1 -
.../ambari/server/orm/dao/HostVersionDAO.java | 28 +++++
.../org/apache/ambari/server/state/Cluster.java | 2 +-
.../server/state/cluster/ClusterImpl.java | 122 ++++++++++---------
.../server/state/cluster/ClustersImpl.java | 1 -
.../svccomphost/ServiceComponentHostImpl.java | 72 +++++++++--
.../server/state/cluster/ClusterTest.java | 6 +-
9 files changed, 167 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index b5fda49..929329d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -73,6 +73,7 @@ import org.apache.ambari.server.state.HostHealthStatus;
import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.SecurityState;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
@@ -470,19 +471,22 @@ public class HeartBeatHandler {
// Reading component version if it is present
if (StringUtils.isNotBlank(report.getStructuredOut())) {
+ ComponentVersionStructuredOut structuredOutput = null;
try {
- final ComponentVersionStructuredOut structuredOutput = gson.fromJson(report.getStructuredOut(), ComponentVersionStructuredOut.class);
+ structuredOutput = gson.fromJson(report.getStructuredOut(), ComponentVersionStructuredOut.class);
+ } catch (JsonSyntaxException ex) {
+ //Json structure for component version was incorrect
+ //do nothing, pass this data further for processing
+ }
+ if (structuredOutput != null && StringUtils.isNotBlank(structuredOutput.getVersion())) {
final String previousVersion = scHost.getVersion();
- if (StringUtils.isNotBlank(structuredOutput.getVersion()) && !StringUtils.equals(previousVersion, structuredOutput.getVersion())) {
+ if (!StringUtils.equals(previousVersion, structuredOutput.getVersion())) {
scHost.setVersion(structuredOutput.getVersion());
if (previousVersion != null && !previousVersion.equals("UNKNOWN")) {
scHost.setUpgradeState(UpgradeState.COMPLETE);
}
scHostsRequireRecalculation.add(scHost);
}
- } catch (JsonSyntaxException ex) {
- //Json structure for component version was incorrect
- //do nothing, pass this data further for processing
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/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 6dabcbb..512ffdb 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
@@ -75,7 +75,6 @@ import org.apache.ambari.server.actionmanager.StageFactory;
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.RepositoryVersionResourceProvider;
import org.apache.ambari.server.controller.internal.RequestOperationLevel;
import org.apache.ambari.server.controller.internal.RequestStageContainer;
import org.apache.ambari.server.controller.internal.URLStreamProvider;
@@ -98,7 +97,6 @@ import org.apache.ambari.server.security.ldap.LdapSyncDto;
import org.apache.ambari.server.stageplanner.RoleGraph;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.CommandScriptDefinition;
import org.apache.ambari.server.state.ComponentInfo;
import org.apache.ambari.server.state.Config;
@@ -125,7 +123,6 @@ 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.scheduler.RequestExecutionFactory;
-import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
@@ -207,8 +204,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
private AmbariLdapDataPopulator ldapDataPopulator;
@Inject
private RepositoryVersionDAO repositoryVersionDAO;
- @Inject
- private RepositoryVersionHelper repositoryVersionHelper;
private MaintenanceStateHelper maintenanceStateHelper;
@@ -366,20 +361,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
StackId newStackId = new StackId(request.getStackVersion());
c.setDesiredStackVersion(newStackId);
clusters.setCurrentStackVersion(request.getClusterName(), newStackId);
-
- try {
- // Because Ambari may eventually support multiple clusters, it may be possible that a previously installed cluster
- // already inserted the Repository Version for this stack and version.
- RepositoryVersionEntity existingRepositoryVersion = repositoryVersionDAO.findByStackAndVersion(newStackId.getStackId(), newStackId.getStackVersion());
- if (existingRepositoryVersion == null) {
- repositoryVersionDAO.create(newStackId.getStackId(), newStackId.getStackVersion(), newStackId.getStackId(),
- repositoryVersionHelper.getUpgradePackageNameSafe(newStackId.getStackId(), newStackId.getStackVersion(), newStackId.getStackVersion()),
- repositoryVersionHelper.serializeOperatingSystems(stackInfo.getRepositories()));
- }
- c.createClusterVersion(stackId.getStackId(), stackId.getStackVersion(), getAuthName(), RepositoryVersionState.CURRENT);
- } catch (Exception e) {
- throw new AmbariException("Unable to create Repository Version and/or Cluster Version for Stack " + stackId.toString() + ". Error: " + e.getMessage());
- }
}
if (request.getHostNames() != null) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index da034ce..d9c9aec 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -469,7 +469,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
UpgradeEntity entity = new UpgradeEntity();
- // !!! FIXME not quite right here, upcoming patch is supposed to get this right
entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
entity.setToVersion(version);
entity.setUpgradeGroups(groupEntities);
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
index ed9fa24..d816102 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java
@@ -26,7 +26,10 @@ import com.google.inject.persist.Transactional;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.HostVersionEntity;
import org.apache.ambari.server.state.RepositoryVersionState;
+
import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
import javax.persistence.TypedQuery;
import java.util.List;
@@ -125,6 +128,31 @@ public class HostVersionDAO {
}
/**
+ * Retrieve the single host version whose state is {@link org.apache.ambari.server.state.RepositoryVersionState#CURRENT}, of which there should be exactly one at all times
+ * for the given host.
+ *
+ * @param clusterName Cluster name
+ * @param hostName Host name
+ * @return Returns the single host version for this host whose state is {@link org.apache.ambari.server.state.RepositoryVersionState#CURRENT}, or {@code null} otherwise.
+ */
+ @RequiresSession
+ public HostVersionEntity findByHostAndStateCurrent(String clusterName, String hostName) {
+ try {
+ List<?> results = findByClusterHostAndState(clusterName, hostName, RepositoryVersionState.CURRENT);
+ if (results.isEmpty()) {
+ return null;
+ } else {
+ if (results.size() == 1) {
+ return (HostVersionEntity) results.get(0);
+ }
+ }
+ throw new NonUniqueResultException();
+ } catch (NoResultException ignored) {
+ return null;
+ }
+ }
+
+ /**
* Retrieve the single host version for the given cluster, stack name, stack version, and host name.
*
* @param clusterName Cluster name
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/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 fd0188c..b344a05 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
@@ -173,7 +173,7 @@ public interface Cluster {
/**
* Create a cluster version for the given stack and version, whose initial state must either
- * be either {@link RepositoryVersionState#CURRENT} (if no other cluster version exists) or
+ * be either {@link RepositoryVersionState#UPGRADING} (if no other cluster version exists) or
* {@link RepositoryVersionState#INSTALLING} (if at exactly one CURRENT cluster version already exists).
* @param stack Stack name
* @param version Stack version
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/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 19a5f9f..bf5bf50 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
@@ -44,6 +44,7 @@ import org.apache.ambari.server.ParentObjectNotFoundException;
import org.apache.ambari.server.ServiceComponentHostNotFoundException;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariSessionManager;
import org.apache.ambari.server.controller.ClusterResponse;
import org.apache.ambari.server.controller.ConfigurationResponse;
@@ -79,6 +80,7 @@ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.RequestScheduleEntity;
import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.ClusterHealthReport;
@@ -226,6 +228,9 @@ public class ClusterImpl implements Cluster {
private RepositoryVersionDAO repositoryVersionDAO;
@Inject
+ private Configuration configuration;
+
+ @Inject
private AmbariSessionManager sessionManager;
private volatile boolean svcHostsLoaded = false;
@@ -1258,13 +1263,18 @@ public class ClusterImpl implements Cluster {
readWriteLock.writeLock().lock();
try {
Map<String, Host> hosts = clusters.getHostsForCluster(this.getClusterName());
- String stackId = this.getCurrentStackVersion().getStackId();
+ StackId stackId = getCurrentStackVersion();
+
ClusterVersionEntity clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(this.getClusterName(),
- stackId, repositoryVersion);
+ stackId.getStackId(), repositoryVersion);
if (clusterVersion == null) {
- throw new AmbariException(String.format("Repository version %s not found for cluster %s",
- repositoryVersion, getClusterName()));
+ if (clusterVersionDAO.findByCluster(getClusterName()).isEmpty()) {
+ createClusterVersionInternal(stackId.getStackId(), repositoryVersion, AuthorizationHelper.getAuthenticatedName(configuration.getAnonymousAuditName()), RepositoryVersionState.UPGRADING);
+ clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(this.getClusterName(), stackId.getStackId(), repositoryVersion);
+ } else {
+ throw new AmbariException(String.format("Repository version %s not found for cluster %s", repositoryVersion, getClusterName()));
+ }
}
RepositoryVersionState worstState;
@@ -1277,7 +1287,7 @@ public class ClusterImpl implements Cluster {
// anything else is not supported as of now
return;
}
- worstState = RepositoryVersionState.UPGRADED;
+ worstState = RepositoryVersionState.CURRENT;
for (Host host : hosts.values()) {
String hostName = host.getHostName();
if (host.getState() != HostState.HEALTHY) {
@@ -1286,19 +1296,20 @@ public class ClusterImpl implements Cluster {
hostName, worstState));
}
- HostVersionEntity hostVersion = hostVersionDAO.findByClusterStackVersionAndHost(this.getClusterName(),
- stackId, repositoryVersion, hostName);
- if (hostVersion == null) {
- LOG.warn(String.format("Repo version %s is not installed on host %s",
- repositoryVersion, hostName));
- worstState = getWorstState(worstState, RepositoryVersionState.OUT_OF_SYNC);
- } else {
- worstState = getWorstState(worstState, hostVersion.getState());
+ HostVersionEntity hostVersion = hostVersionDAO.findByClusterStackVersionAndHost(this.getClusterName(), stackId.getStackId(), repositoryVersion, hostName);
+ if (clusterVersionDAO.findByClusterAndStateCurrent(getClusterName()) != null) { //TODO workaround to skip this check during clean install
+ if (hostVersion == null) {
+ LOG.warn(String.format("Repo version %s is not installed on host %s",
+ repositoryVersion, hostName));
+ worstState = getWorstState(worstState, RepositoryVersionState.OUT_OF_SYNC);
+ } else {
+ worstState = getWorstState(worstState, hostVersion.getState());
+ }
}
}
if (worstState != clusterVersion.getState()) {
// Any mismatch will be catched while transitioning
- transitionClusterVersion(stackId, repositoryVersion, worstState);
+ transitionClusterVersion(stackId.getStackId(), repositoryVersion, worstState);
}
clusterVersionDAO.merge(clusterVersion);
@@ -1332,47 +1343,13 @@ public class ClusterImpl implements Cluster {
}
}
- /**
- * Create a cluster version for the given stack and version, whose initial state must either
- * be either {@link org.apache.ambari.server.state.RepositoryVersionState#CURRENT} (if no other cluster version exists) or
- * {@link org.apache.ambari.server.state.RepositoryVersionState#INSTALLING} (if at exactly one CURRENT cluster version already exists).
- * @param stack Stack name
- * @param version Stack version
- * @param userName User performing the operation
- * @param state Initial state
- * @throws AmbariException
- */
@Override
public void createClusterVersion(String stack, String version, String userName, RepositoryVersionState state) throws AmbariException {
clusterGlobalLock.readLock().lock();
try {
readWriteLock.writeLock().lock();
try {
- Set<RepositoryVersionState> allowedStates = new HashSet<RepositoryVersionState>();
- Collection<ClusterVersionEntity> allClusterVersions = getAllClusterVersions();
- if (allClusterVersions == null || allClusterVersions.isEmpty()) {
- allowedStates.add(RepositoryVersionState.CURRENT);
- } else {
- allowedStates.add(RepositoryVersionState.INSTALLING);
- }
-
- if (! allowedStates.contains(state)) {
- throw new AmbariException("The allowed state for a new cluster version must be within " + allowedStates);
- }
-
- ClusterVersionEntity existing = clusterVersionDAO.findByClusterAndStackAndVersion(this.getClusterName(), stack, version);
- if (existing != null) {
- throw new DuplicateResourceException("Duplicate item, a cluster version with stack=" + stack + ", version=" +
- version + " for cluster " + this.getClusterName() + " already exists");
- }
-
- RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackAndVersion(stack, version);
- if (repositoryVersionEntity == null) {
- throw new AmbariException("Could not find repository version for stack=" + stack + ", version=" + version );
- }
-
- ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(this.clusterEntity, repositoryVersionEntity, state, System.currentTimeMillis(), System.currentTimeMillis(), userName);
- clusterVersionDAO.create(clusterVersionEntity);
+ createClusterVersionInternal(stack, version, userName, state);
} finally {
readWriteLock.writeLock().unlock();
}
@@ -1382,6 +1359,40 @@ public class ClusterImpl implements Cluster {
}
/**
+ * See {@link #createClusterVersion}
+ *
+ * This method is intended to be called only when cluster lock is already acquired.
+ */
+ private void createClusterVersionInternal(String stack, String version, String userName, RepositoryVersionState state) throws AmbariException {
+ Set<RepositoryVersionState> allowedStates = new HashSet<RepositoryVersionState>();
+ Collection<ClusterVersionEntity> allClusterVersions = getAllClusterVersions();
+ if (allClusterVersions == null || allClusterVersions.isEmpty()) {
+ allowedStates.add(RepositoryVersionState.CURRENT);
+ allowedStates.add(RepositoryVersionState.UPGRADING);
+ } else {
+ allowedStates.add(RepositoryVersionState.INSTALLING);
+ }
+
+ if (! allowedStates.contains(state)) {
+ throw new AmbariException("The allowed state for a new cluster version must be within " + allowedStates);
+ }
+
+ ClusterVersionEntity existing = clusterVersionDAO.findByClusterAndStackAndVersion(this.getClusterName(), stack, version);
+ if (existing != null) {
+ throw new DuplicateResourceException("Duplicate item, a cluster version with stack=" + stack + ", version=" +
+ version + " for cluster " + this.getClusterName() + " already exists");
+ }
+
+ RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackAndVersion(stack, version);
+ if (repositoryVersionEntity == null) {
+ throw new AmbariException("Could not find repository version for stack=" + stack + ", version=" + version );
+ }
+
+ ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(this.clusterEntity, repositoryVersionEntity, state, System.currentTimeMillis(), System.currentTimeMillis(), userName);
+ clusterVersionDAO.create(clusterVersionEntity);
+ }
+
+ /**
* Transition an existing cluster version from one state to another.
* @param stack Stack name
* @param version Stack version
@@ -1428,6 +1439,9 @@ public class ClusterImpl implements Cluster {
case UPGRADING:
allowedStates.add(RepositoryVersionState.UPGRADED);
allowedStates.add(RepositoryVersionState.UPGRADE_FAILED);
+ if (clusterVersionDAO.findByClusterAndStateCurrent(getClusterName()) == null) {
+ allowedStates.add(RepositoryVersionState.CURRENT);
+ }
break;
case UPGRADED:
allowedStates.add(RepositoryVersionState.CURRENT);
@@ -1441,15 +1455,13 @@ public class ClusterImpl implements Cluster {
throw new AmbariException("Invalid cluster version transition from " + existingClusterVersion.getState() + " to " + state);
}
- // There must be exactly one cluster version whose state is CURRENT at all times.
+ // There must be at most one cluster version whose state is CURRENT at all times.
if (state == RepositoryVersionState.CURRENT) {
ClusterVersionEntity currentVersion = clusterVersionDAO.findByClusterAndStateCurrent(this.getClusterName());
- if (currentVersion == null) {
- throw new AmbariException("Unable to find CURRENT cluster version for cluster " + this.getClusterName());
+ if (currentVersion != null) {
+ currentVersion.setState(RepositoryVersionState.INSTALLED);
+ clusterVersionDAO.merge(currentVersion);
}
-
- currentVersion.setState(RepositoryVersionState.INSTALLED);
- clusterVersionDAO.merge(currentVersion);
}
existingClusterVersion.setState(state);
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index 9ec8c36..01148a8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -516,7 +516,6 @@ public class ClustersImpl implements Clusters {
}
mapHostClusterEntities(hostname, cluster.getClusterId());
- cluster.mapHostVersions(Sets.newHashSet(hostname), currentClusterVersion, RepositoryVersionState.CURRENT);
host.refresh();
cluster.refresh();
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 31606ca..3593eb3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -33,6 +33,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.agent.AlertDefinitionCommand;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.ServiceComponentHostResponse;
import org.apache.ambari.server.events.AlertHashInvalidationEvent;
import org.apache.ambari.server.events.MaintenanceModeEvent;
@@ -70,6 +71,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.ServiceComponentHostEvent;
import org.apache.ambari.server.state.ServiceComponentHostEventType;
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.UpgradeState;
import org.apache.ambari.server.state.alert.AlertDefinitionHash;
@@ -78,7 +80,9 @@ import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.fsm.SingleArcTransition;
import org.apache.ambari.server.state.fsm.StateMachine;
import org.apache.ambari.server.state.fsm.StateMachineFactory;
+import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -123,6 +127,10 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
Clusters clusters;
@Inject
ConfigHelper helper;
+ @Inject
+ AmbariMetaInfo ambariMetaInfo;
+ @Inject
+ RepositoryVersionHelper repositoryVersionHelper;
/**
* Used for creating commands to send to the agents when alert definitions are
@@ -1708,6 +1716,10 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
@Override
public void recalculateHostVersionState() throws AmbariException {
final String version = getVersion();
+ if (version.equals("UNKNOWN")) {
+ // recalculate only if some particular version is set
+ return;
+ }
final String hostName = getHostName();
final HostEntity host = hostDAO.findByName(hostName);
final Set<Cluster> clustersForHost = clusters.getClustersForHost(hostName);
@@ -1716,27 +1728,37 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
}
final Cluster cluster = clustersForHost.iterator().next();
final StackId stack = cluster.getDesiredStackVersion();
- final RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stack.getStackId(), version);
+ final StackInfo stackInfo = ambariMetaInfo.getStack(stack.getStackName(), stack.getStackVersion());
+ RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stack.getStackId(), version);
if (repositoryVersion == null) {
- LOG.debug("Repository version for stack " + stack.getStackId() + " for version " + version + " was not found");
- return;
+ LOG.info("Creating new repository version " + stack.getStackName() + "-" + version);
+ repositoryVersion = repositoryVersionDAO.create(stack.getStackId(), version, stack.getStackName() + "-" + version,
+ repositoryVersionHelper.getUpgradePackageNameSafe(stack.getStackName(), stack.getStackVersion(), version),
+ repositoryVersionHelper.serializeOperatingSystems(stackInfo.getRepositories()));
}
- final HostVersionEntity hostVersionEntity = hostVersionDAO.findByClusterStackVersionAndHost(cluster.getClusterName(), repositoryVersion.getStack(), repositoryVersion.getVersion(), hostName);
+ HostVersionEntity hostVersionEntity = hostVersionDAO.findByClusterStackVersionAndHost(cluster.getClusterName(), repositoryVersion.getStack(), repositoryVersion.getVersion(), hostName);
if (hostVersionEntity == null) {
- LOG.debug(String.format("Host version version for host %s on cluster %s with stack %s and repository version %s was not found",
- hostName, cluster.getClusterName(), repositoryVersion.getStack(), repositoryVersion.getVersion()));
- return;
+ // there is no host version but we have a component on the host of that version. It implies that we have some repo version installed on that host
+ // and we can treat the host as being upgrading to that version
+ hostVersionEntity = new HostVersionEntity(hostName, repositoryVersion, RepositoryVersionState.UPGRADING);
+ hostVersionEntity.setHostEntity(host);
+ hostVersionDAO.create(hostVersionEntity);
}
final Collection<HostComponentStateEntity> allHostComponents = host.getHostComponentStateEntities();
final Collection<HostComponentStateEntity> upgradedHostComponents = new HashSet<HostComponentStateEntity>();
+ final Collection<HostComponentStateEntity> versionedHostComponents = new HashSet<HostComponentStateEntity>();
for (HostComponentStateEntity hostComponentStateEntity: allHostComponents) {
- if (hostComponentStateEntity.getUpgradeState().equals(UpgradeState.COMPLETE) && !hostComponentStateEntity.getVersion().equals("UNKNOWN")) {
- upgradedHostComponents.add(hostComponentStateEntity);
+ if (!hostComponentStateEntity.getVersion().equals("UNKNOWN")) {
+ versionedHostComponents.add(hostComponentStateEntity);
+ if (hostComponentStateEntity.getUpgradeState().equals(UpgradeState.COMPLETE) ) {
+ upgradedHostComponents.add(hostComponentStateEntity);
+ }
}
}
// ZKFC is special because it is does not receive a RESTART action during a Rolling Upgrade.
+ @SuppressWarnings("unchecked")
final Collection<HostComponentStateEntity> nonUpgradedHostComponents = CollectionUtils.subtract(allHostComponents, upgradedHostComponents);
for (HostComponentStateEntity hostComponentStateEntity: nonUpgradedHostComponents) {
if (hostComponentStateEntity.getComponentName().equalsIgnoreCase("ZKFC")) {
@@ -1744,17 +1766,41 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
}
}
- if (allHostComponents.size() == upgradedHostComponents.size() &&
+ if (allHostComponents.size() == upgradedHostComponents.size() && // all components are upgraded
+ haveSameVersion(upgradedHostComponents) && //have the same version
(hostVersionEntity.getState().equals(RepositoryVersionState.INSTALLED) || hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING))) {
hostVersionEntity.setState(RepositoryVersionState.UPGRADED);
hostVersionDAO.merge(hostVersionEntity);
- }
-
- if (!upgradedHostComponents.isEmpty() && upgradedHostComponents.size() < allHostComponents.size()) {
+ } else if (allHostComponents.size() == versionedHostComponents.size() && haveSameVersion(versionedHostComponents) && //all components have same version
+ hostVersionDAO.findByHostAndStateCurrent(cluster.getClusterName(), hostName) == null) { //and no CURRENT version exists
+ hostVersionEntity.setState(RepositoryVersionState.CURRENT);
+ hostVersionDAO.merge(hostVersionEntity);
+ } else if (!upgradedHostComponents.isEmpty() && upgradedHostComponents.size() < allHostComponents.size()) {
hostVersionEntity.setState(RepositoryVersionState.UPGRADING);
hostVersionDAO.merge(hostVersionEntity);
}
cluster.recalculateClusterVersionState(version);
}
+
+ /**
+ * Checks that every component has the same version.
+ *
+ * @param hostComponents host components
+ * @return true if components have the same version
+ */
+ private boolean haveSameVersion(Collection<HostComponentStateEntity> hostComponents) {
+ if (hostComponents.isEmpty()) {
+ // should never happen
+ // but just in case: no components passed -> do not change host version
+ return false;
+ }
+ final String version = hostComponents.iterator().next().getVersion();
+ for (HostComponentStateEntity hostComponent : hostComponents) {
+ if (!StringUtils.equals(version, hostComponent.getVersion())) {
+ return false;
+ }
+ }
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fe3f405f/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 57c0223..04b4f81 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
@@ -981,12 +981,12 @@ public class ClusterTest {
assertNotNull(entityHDP2);
List<HostVersionEntity> hostVersionsH1Before = hostVersionDAO.findByClusterAndHost("c1", "h1");
- assertEquals(1, hostVersionsH1Before.size());
+ assertEquals(0, hostVersionsH1Before.size());
c1.inferHostVersions(entityHDP2);
List<HostVersionEntity> hostVersionsH1After = hostVersionDAO.findByClusterAndHost("c1", "h1");
- assertEquals(2, hostVersionsH1After.size());
+ assertEquals(1, hostVersionsH1After.size());
boolean checked = false;
for (HostVersionEntity entity : hostVersionsH1After) {
@@ -1003,7 +1003,7 @@ public class ClusterTest {
c1.inferHostVersions(entityHDP2);
hostVersionsH1After = hostVersionDAO.findByClusterAndHost("c1", "h1");
- assertEquals(2, hostVersionsH1After.size());
+ assertEquals(1, hostVersionsH1After.size());
checked = false;
for (HostVersionEntity entity : hostVersionsH1After) {