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 2015/04/25 01:01:18 UTC
[2/2] ambari git commit: AMBARI-10736 - Downgrade must manage
cross-stack configuration sets (jonathanhurley)
AMBARI-10736 - Downgrade must manage cross-stack configuration sets (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ac6fd63f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ac6fd63f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ac6fd63f
Branch: refs/heads/trunk
Commit: ac6fd63f95a38130ef707a5b872c0c51ec23573d
Parents: c06571f
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Apr 24 16:02:11 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Apr 24 19:01:10 2015 -0400
----------------------------------------------------------------------
.../internal/UpgradeResourceProvider.java | 127 +++++++--
.../ambari/server/orm/dao/ClusterDAO.java | 75 +++++-
.../ambari/server/orm/dao/ServiceConfigDAO.java | 59 ++++
.../orm/entities/ClusterConfigEntity.java | 5 +-
.../entities/ClusterConfigMappingEntity.java | 88 +++++-
.../orm/entities/ServiceConfigEntity.java | 52 +++-
.../upgrades/FinalizeUpgradeAction.java | 42 ++-
.../org/apache/ambari/server/state/Cluster.java | 133 +++++----
.../ambari/server/state/UpgradeContext.java | 70 ++++-
.../server/state/cluster/ClusterImpl.java | 147 +++++++++-
.../server/orm/dao/ServiceConfigDAOTest.java | 54 +++-
.../upgrades/UpgradeActionTest.java | 267 ++++++++++++++-----
.../ambari/server/state/UpgradeHelperTest.java | 38 +--
13 files changed, 956 insertions(+), 201 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/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 7de7348..b973d98 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
@@ -142,6 +142,20 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
private static final String COMMAND_PARAM_TASKS = "tasks";
private static final String COMMAND_PARAM_STRUCT_OUT = "structured_out";
+ /**
+ * The original "current" stack of the cluster before the upgrade started.
+ * This is the same regardless of whether the current direction is
+ * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE}.
+ */
+ private static final String COMMAND_PARAM_ORIGINAL_STACK = "original_stack";
+
+ /**
+ * The target upgrade stack before the upgrade started. This is the same
+ * regardless of whether the current direction is {@link Direction#UPGRADE} or
+ * {@link Direction#DOWNGRADE}.
+ */
+ private static final String COMMAND_PARAM_TARGET_STACK = "target_stack";
+
private static final String DEFAULT_REASON_TEMPLATE = "Aborting upgrade %s";
private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>();
@@ -514,10 +528,27 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
// the version being upgraded or downgraded to (ie hdp-2.2.1.0-1234)
final String version = (String) requestMap.get(UPGRADE_VERSION);
- MasterHostResolver resolver = direction.isUpgrade() ?
- new MasterHostResolver(configHelper, cluster) : new MasterHostResolver(configHelper, cluster, version);
+ MasterHostResolver resolver = direction.isUpgrade() ? new MasterHostResolver(
+ configHelper, cluster) : new MasterHostResolver(configHelper, cluster,
+ version);
+
+ StackId sourceStackId = null;
+ StackId targetStackId = null;
- UpgradeContext ctx = new UpgradeContext(resolver, version, direction);
+ switch( direction ){
+ case UPGRADE:
+ sourceStackId = cluster.getCurrentStackVersion();
+
+ RepositoryVersionEntity targetRepositoryVersion = s_repoVersionDAO.findMaxByVersion(version);
+ targetStackId = targetRepositoryVersion.getStackId();
+ break;
+ case DOWNGRADE:
+ sourceStackId = cluster.getCurrentStackVersion();
+ targetStackId = cluster.getDesiredStackVersion();
+ break;
+ }
+
+ UpgradeContext ctx = new UpgradeContext(resolver, sourceStackId, targetStackId, version, direction);
List<UpgradeGroupHolder> groups = s_upgradeHelper.createSequence(pack, ctx);
@@ -571,9 +602,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
groupEntity.setItems(itemEntities);
-
groupEntities.add(groupEntity);
-
}
UpgradeEntity entity = new UpgradeEntity();
@@ -588,7 +617,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
entity.setRequestId(req.getId());
// !!! in case persist() starts creating tasks right away, square away the configs
- createConfigs(cluster, version, direction);
+ processConfigurations(cluster, version, direction);
req.persist();
@@ -598,13 +627,31 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
/**
- * Merges and creates configs for the new stack. No-op when the target stack version
- * is the same as the cluster's current stack version.
- * @param cluster the cluster
- * @param version the version
+ * Handles the creation or resetting of configurations based on whether an
+ * upgrade or downgrade is occurring. This method will not do anything when
+ * the target stack version is the same as the cluster's current stack version
+ * since, by definition, no new configurations are automatically created when
+ * upgrading with the same stack (ie HDP 2.2.0.0 -> HDP 2.2.1.0).
+ * <p/>
+ * When upgrading or downgrade between stacks (HDP 2.2.0.0 -> HDP 2.3.0.0)
+ * then this will perform the following:
+ * <ul>
+ * <li>Upgrade: Create new configurations that are a merge between the current
+ * stack and the desired stack.</li>
+ * <li>Downgrade: Reset the latest configurations from the cluster's original
+ * stack. The new configurations that were created on upgrade must be left
+ * intact until all components have been reverted, otherwise heartbeats will
+ * fail due to missing configurations.</li>
+ * </ul>
+ *
+ *
+ * @param cluster
+ * the cluster
+ * @param version
+ * the version
* @throws AmbariException
*/
- private void createConfigs(Cluster cluster, String version, Direction direction) throws AmbariException {
+ private void processConfigurations(Cluster cluster, String version, Direction direction) throws AmbariException {
RepositoryVersionEntity targetRve = s_repoVersionDAO.findMaxByVersion(version);
if (null == targetRve) {
LOG.info("Could not find version entity for {}; not setting new configs",
@@ -612,24 +659,37 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
return;
}
- StackEntity oldStack = cluster.getCurrentClusterVersion().getRepositoryVersion().getStack();
- StackEntity newStack = targetRve.getStack();
-
- if (oldStack.equals(newStack)) {
- return;
+ // if the current and target stacks are the same (ie HDP 2.2.0.0 -> 2.2.1.0)
+ // then we should never do anything with configs on either upgrade or
+ // downgrade; however if we are going across stacks, we have to do the stack
+ // checks differently depending on whether this is an upgrade or downgrade
+ StackEntity targetStack = targetRve.getStack();
+ StackId currentStackId = cluster.getCurrentStackVersion();
+ StackId desiredStackId = cluster.getDesiredStackVersion();
+ StackId targetStackId = new StackId(targetStack);
+ switch (direction) {
+ case UPGRADE:
+ if (currentStackId.equals(targetStackId)) {
+ return;
+ }
+ break;
+ case DOWNGRADE:
+ if (desiredStackId.equals(targetStackId)) {
+ return;
+ }
+ break;
}
- ConfigHelper configHelper = getManagementController().getConfigHelper();
Map<String, Map<String, String>> clusterConfigs = null;
+ ConfigHelper configHelper = getManagementController().getConfigHelper();
if (direction == Direction.UPGRADE) {
-
clusterConfigs = new HashMap<String, Map<String, String>>();
// !!! stack
- Set<org.apache.ambari.server.state.PropertyInfo> pi = s_metaProvider.get().getStackProperties(newStack.getStackName(),
- newStack.getStackVersion());
+ Set<org.apache.ambari.server.state.PropertyInfo> pi = s_metaProvider.get().getStackProperties(
+ targetStack.getStackName(), targetStack.getStackVersion());
for (PropertyInfo stackProperty : pi) {
String type = ConfigHelper.fileNameToConfigType(stackProperty.getFilename());
@@ -644,8 +704,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
// !!! by service
for (String serviceName : cluster.getServices().keySet()) {
- pi = s_metaProvider.get().getServiceProperties(newStack.getStackName(),
- newStack.getStackVersion(), serviceName);
+ pi = s_metaProvider.get().getServiceProperties(
+ targetStack.getStackName(), targetStack.getStackVersion(),
+ serviceName);
// !!! use new stack as the basis
for (PropertyInfo stackProperty : pi) {
@@ -668,12 +729,13 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
}
} else {
- // !!! remove configs
+ // downgrade
+ cluster.applyLatestConfigurations(cluster.getCurrentStackVersion());
}
// !!! update the stack
- cluster.setDesiredStackVersion(
- new StackId(newStack.getStackName(), newStack.getStackVersion()), true);
+ cluster.setDesiredStackVersion(new StackId(targetStack.getStackName(),
+ targetStack.getStackVersion()), true);
// !!! configs must be created after setting the stack version
if (null != clusterConfigs) {
@@ -681,7 +743,6 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
clusterConfigs, getManagementController().getAuthName(),
"Configuration created for Upgrade");
}
-
}
@@ -734,6 +795,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
params.put(COMMAND_PARAM_TASKS, entity.getTasks());
params.put(COMMAND_PARAM_VERSION, context.getVersion());
params.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
+ params.put(COMMAND_PARAM_ORIGINAL_STACK, context.getOriginalStackId().getStackId());
+ params.put(COMMAND_PARAM_TARGET_STACK, context.getTargetStackId().getStackId());
// Because custom task may end up calling a script/function inside a service, it is necessary to set the
// service_package_folder and hooks_folder params.
@@ -806,6 +869,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
restartCommandParams.put(COMMAND_PARAM_RESTART_TYPE, "rolling_upgrade");
restartCommandParams.put(COMMAND_PARAM_VERSION, context.getVersion());
restartCommandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
+ restartCommandParams.put(COMMAND_PARAM_ORIGINAL_STACK,
+ context.getOriginalStackId().getStackId());
+ restartCommandParams.put(COMMAND_PARAM_TARGET_STACK,
+ context.getTargetStackId().getStackId());
ActionExecutionContext actionContext = new ActionExecutionContext(
cluster.getClusterName(), "RESTART",
@@ -858,6 +925,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
Map<String, String> commandParams = new HashMap<String, String>();
commandParams.put(COMMAND_PARAM_VERSION, context.getVersion());
commandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
+ commandParams.put(COMMAND_PARAM_ORIGINAL_STACK,
+ context.getOriginalStackId().getStackId());
+ commandParams.put(COMMAND_PARAM_TARGET_STACK,
+ context.getTargetStackId().getStackId());
ActionExecutionContext actionContext = new ActionExecutionContext(
cluster.getClusterName(), "SERVICE_CHECK",
@@ -904,6 +975,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
commandParams.put(COMMAND_PARAM_CLUSTER_NAME, cluster.getClusterName());
commandParams.put(COMMAND_PARAM_VERSION, context.getVersion());
commandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase());
+ commandParams.put(COMMAND_PARAM_ORIGINAL_STACK,
+ context.getOriginalStackId().getStackId());
+ commandParams.put(COMMAND_PARAM_TARGET_STACK,
+ context.getTargetStackId().getStackId());
String itemDetail = entity.getText();
String stageText = StringUtils.abbreviate(entity.getText(), 255);
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
index 7df1e2b..d3c4bd4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
@@ -30,7 +30,10 @@ import javax.persistence.criteria.Root;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
+import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.StackId;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -41,9 +44,13 @@ import com.google.inject.persist.Transactional;
public class ClusterDAO {
@Inject
- Provider<EntityManager> entityManagerProvider;
+ private Provider<EntityManager> entityManagerProvider;
+
+ @Inject
+ private DaoUtils daoUtils;
+
@Inject
- DaoUtils daoUtils;
+ private StackDAO stackDAO;
/**
* Looks for Cluster by ID
@@ -143,6 +150,58 @@ public class ClusterDAO {
}
/**
+ * Get all configurations for the specified cluster and stack. This will
+ * return different versions of the same configuration type (cluster-env v1
+ * and cluster-env v2) if they exist.
+ *
+ * @param clusterId
+ * the cluster (not {@code null}).
+ * @param stackId
+ * the stack (not {@code null}).
+ * @return all service configurations for the cluster and stack.
+ */
+ @RequiresSession
+ public List<ClusterConfigEntity> getAllConfigurations(Long clusterId,
+ StackId stackId) {
+
+ StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
+ stackId.getStackVersion());
+
+ TypedQuery<ClusterConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+ "ClusterConfigEntity.findAllConfigsByStack", ClusterConfigEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+ query.setParameter("stack", stackEntity);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Gets the latest configurations for a given stack for all of the
+ * configurations of the specified cluster.
+ *
+ * @param clusterId
+ * the cluster that the service is a part of.
+ * @param stackId
+ * the stack to get the latest configurations for (not {@code null}).
+ * @return the latest configurations for the specified cluster and stack.
+ */
+ public List<ClusterConfigEntity> getLatestConfigurations(long clusterId,
+ StackId stackId) {
+ StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
+ stackId.getStackVersion());
+
+ TypedQuery<ClusterConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+ "ClusterConfigEntity.findLatestConfigsByStack",
+ ClusterConfigEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+ query.setParameter("stack", stackEntity);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Create Cluster entity in Database
* @param clusterEntity entity to create
*/
@@ -168,8 +227,18 @@ public class ClusterDAO {
}
/**
+ * Remove a cluster configuration mapping from the DB.
+ */
+ @Transactional
+ public void removeConfigMapping(ClusterConfigMappingEntity entity) {
+ entityManagerProvider.get().remove(entity);
+ }
+
+ /**
* Retrieve entity data from DB
- * @param clusterEntity entity to refresh
+ *
+ * @param clusterEntity
+ * entity to refresh
*/
@Transactional
public void refresh(ClusterEntity clusterEntity) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
index fbaec3e..8f8e196 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceConfigDAO.java
@@ -32,6 +32,8 @@ import javax.persistence.criteria.Root;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.StackId;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -44,6 +46,9 @@ public class ServiceConfigDAO {
private Provider<EntityManager> entityManagerProvider;
@Inject
+ private StackDAO stackDAO;
+
+ @Inject
private DaoUtils daoUtils;
@RequiresSession
@@ -110,6 +115,60 @@ public class ServiceConfigDAO {
return daoUtils.selectList(query, clusterId);
}
+ /**
+ * Get all service configurations for the specified cluster and stack. This
+ * will return different versions of the same configuration (HDFS v1 and v2)
+ * if they exist.
+ *
+ * @param clusterId
+ * the cluster (not {@code null}).
+ * @param stackId
+ * the stack (not {@code null}).
+ * @return all service configurations for the cluster and stack.
+ */
+ @RequiresSession
+ public List<ServiceConfigEntity> getAllServiceConfigs(Long clusterId,
+ StackId stackId) {
+
+ StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
+ stackId.getStackVersion());
+
+ TypedQuery<ServiceConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+ "ServiceConfigEntity.findAllServiceConfigsByStack",
+ ServiceConfigEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+ query.setParameter("stack", stackEntity);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Gets the latest service configurations for the specified cluster and stack.
+ *
+ * @param clusterId
+ * the cluster (not {@code null}).
+ * @param stackId
+ * the stack (not {@code null}).
+ * @return the latest service configurations for the cluster and stack.
+ */
+ @RequiresSession
+ public List<ServiceConfigEntity> getLatestServiceConfigs(Long clusterId,
+ StackId stackId) {
+
+ StackEntity stackEntity = stackDAO.find(stackId.getStackName(),
+ stackId.getStackVersion());
+
+ TypedQuery<ServiceConfigEntity> query = entityManagerProvider.get().createNamedQuery(
+ "ServiceConfigEntity.findLatestServiceConfigsByStack",
+ ServiceConfigEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+ query.setParameter("stack", stackEntity);
+
+ return daoUtils.selectList(query);
+ }
+
@RequiresSession
public ServiceConfigEntity getLastServiceConfig(Long clusterId, String serviceName) {
TypedQuery<ServiceConfigEntity> query = entityManagerProvider.get().
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
index 8d304c0..67f804c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
@@ -48,7 +48,10 @@ import javax.persistence.UniqueConstraint;
, pkColumnValue = "config_id_seq"
, initialValue = 1
)
-@NamedQueries({ @NamedQuery(name = "ClusterConfigEntity.findNextConfigVersion", query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId") })
+@NamedQueries({
+ @NamedQuery(name = "ClusterConfigEntity.findNextConfigVersion", query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId"),
+ @NamedQuery(name = "ClusterConfigEntity.findAllConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.stack=:stack"),
+ @NamedQuery(name = "ClusterConfigEntity.findLatestConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.timestamp = (SELECT MAX(clusterConfig2.timestamp) FROM ClusterConfigEntity clusterConfig2 WHERE clusterConfig2.clusterId=:clusterId AND clusterConfig2.stack=:stack AND clusterConfig2.type = clusterConfig.type)") })
public class ClusterConfigEntity {
@Id
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
index fa48399..5e18014 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigMappingEntity.java
@@ -19,14 +19,11 @@ package org.apache.ambari.server.orm.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
-import javax.persistence.TableGenerator;
/**
* Entity that maps to a cluster config mapping.
@@ -53,22 +50,22 @@ public class ClusterConfigMappingEntity {
@Column(name = "selected", insertable = true, updatable = true, nullable = false)
private int selectedInd = 0;
-
+
@Column(name = "user_name", insertable = true, updatable = true, nullable = false)
private String user;
@ManyToOne
@JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
private ClusterEntity clusterEntity;
-
+
public Long getClusterId() {
return clusterId;
}
-
+
public void setClusterId(Long id) {
clusterId = id;
}
-
+
public String getType() {
return typeName;
}
@@ -83,15 +80,15 @@ public class ClusterConfigMappingEntity {
public void setCreateTimestamp(Long timestamp) {
createTimestamp = timestamp;
}
-
+
public String getTag() {
return tag;
}
-
+
public void setTag(String version) {
tag = version;
}
-
+
public int isSelected() {
return selectedInd;
}
@@ -99,21 +96,21 @@ public class ClusterConfigMappingEntity {
public void setSelected(int selected) {
selectedInd = selected;
}
-
+
/**
* @return the user
*/
public String getUser() {
return user;
}
-
+
/**
* @param userName the user
*/
public void setUser(String userName) {
user = userName;
}
-
+
public ClusterEntity getClusterEntity() {
return clusterEntity;
}
@@ -122,5 +119,70 @@ public class ClusterConfigMappingEntity {
clusterEntity = entity;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((clusterId == null) ? 0 : clusterId.hashCode());
+ result = prime * result + ((createTimestamp == null) ? 0 : createTimestamp.hashCode());
+ result = prime * result + ((tag == null) ? 0 : tag.hashCode());
+ result = prime * result + ((typeName == null) ? 0 : typeName.hashCode());
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ClusterConfigMappingEntity other = (ClusterConfigMappingEntity) obj;
+ if (clusterId == null) {
+ if (other.clusterId != null) {
+ return false;
+ }
+ } else if (!clusterId.equals(other.clusterId)) {
+ return false;
+ }
+
+ if (createTimestamp == null) {
+ if (other.createTimestamp != null) {
+ return false;
+ }
+ } else if (!createTimestamp.equals(other.createTimestamp)) {
+ return false;
+ }
+
+ if (tag == null) {
+ if (other.tag != null) {
+ return false;
+ }
+ } else if (!tag.equals(other.tag)) {
+ return false;
+ }
+
+ if (typeName == null) {
+ if (other.typeName != null) {
+ return false;
+ }
+ } else if (!typeName.equals(other.typeName)) {
+ return false;
+ }
+
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
index c8a74a6..f5bdbf9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceConfigEntity.java
@@ -21,6 +21,7 @@ package org.apache.ambari.server.orm.entities;
import java.util.List;
import javax.persistence.Basic;
+import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
@@ -45,7 +46,10 @@ import javax.persistence.TableGenerator;
, pkColumnValue = "service_config_id_seq"
, initialValue = 1
)
-@NamedQueries({ @NamedQuery(name = "ServiceConfigEntity.findNextServiceConfigVersion", query = "SELECT COALESCE(MAX(serviceConfig.version), 0) + 1 AS nextVersion FROM ServiceConfigEntity serviceConfig WHERE serviceConfig.serviceName=:serviceName AND serviceConfig.clusterId=:clusterId") })
+@NamedQueries({
+ @NamedQuery(name = "ServiceConfigEntity.findNextServiceConfigVersion", query = "SELECT COALESCE(MAX(serviceConfig.version), 0) + 1 AS nextVersion FROM ServiceConfigEntity serviceConfig WHERE serviceConfig.serviceName=:serviceName AND serviceConfig.clusterId=:clusterId"),
+ @NamedQuery(name = "ServiceConfigEntity.findAllServiceConfigsByStack", query = "SELECT serviceConfig FROM ServiceConfigEntity serviceConfig WHERE serviceConfig.clusterId=:clusterId AND serviceConfig.stack=:stack"),
+ @NamedQuery(name = "ServiceConfigEntity.findLatestServiceConfigsByStack", query = "SELECT serviceConfig FROM ServiceConfigEntity serviceConfig WHERE serviceConfig.clusterId = :clusterId AND serviceConfig.createTimestamp = (SELECT MAX(serviceConfig2.createTimestamp) FROM ServiceConfigEntity serviceConfig2 WHERE serviceConfig2.clusterId=:clusterId AND serviceConfig2.stack=:stack AND serviceConfig2.serviceName = serviceConfig.serviceName)") })
public class ServiceConfigEntity {
@Id
@Column(name = "service_config_id")
@@ -85,12 +89,12 @@ public class ServiceConfigEntity {
@Column(name = "host_id")
private List<Long> hostIds;
- @ManyToMany
@JoinTable(
name = "serviceconfigmapping",
joinColumns = {@JoinColumn(name = "service_config_id", referencedColumnName = "service_config_id")},
inverseJoinColumns = {@JoinColumn(name = "config_id", referencedColumnName = "config_id")}
)
+ @ManyToMany(cascade = { CascadeType.REMOVE })
private List<ClusterConfigEntity> clusterConfigEntities;
@ManyToOne
@@ -210,4 +214,46 @@ public class ServiceConfigEntity {
public void setStack(StackEntity stack) {
this.stack = stack;
}
-}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+
+ result = prime * result
+ + ((serviceConfigId == null) ? 0 : serviceConfigId.hashCode());
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ ServiceConfigEntity other = (ServiceConfigEntity) obj;
+ if (serviceConfigId == null) {
+ if (other.serviceConfigId != null) {
+ return false;
+ }
+ } else if (!serviceConfigId.equals(other.serviceConfigId)) {
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
index 49e241f..f1af7c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
@@ -49,6 +49,7 @@ import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.UpgradeState;
+import org.apache.ambari.server.state.stack.upgrade.Direction;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostSummary;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder;
@@ -65,6 +66,20 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
public static final String VERSION_KEY = "version";
/**
+ * The original "current" stack of the cluster before the upgrade started.
+ * This is the same regardless of whether the current direction is
+ * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE}.
+ */
+ public static final String ORIGINAL_STACK_KEY = "original_stack";
+
+ /**
+ * The target upgrade stack before the upgrade started. This is the same
+ * regardless of whether the current direction is {@link Direction#UPGRADE} or
+ * {@link Direction#DOWNGRADE}.
+ */
+ public static final String TARGET_STACK_KEY = "target_stack";
+
+ /**
* The Cluster that this ServerAction implementation is executing on
*/
@Inject
@@ -92,11 +107,14 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
"downgrade".equals(commandParams.get(UPGRADE_DIRECTION_KEY).toLowerCase());
String version = commandParams.get(VERSION_KEY);
+ StackId originalStackId = new StackId(commandParams.get(ORIGINAL_STACK_KEY));
+ StackId targetStackId = new StackId(commandParams.get(TARGET_STACK_KEY));
String clusterName = getExecutionCommand().getClusterName();
if (isDowngrade) {
- return executeDowngrade(clusterName, version);
+ return executeDowngrade(clusterName, originalStackId, targetStackId,
+ version);
} else {
return executeUpgrade(clusterName, version);
}
@@ -230,11 +248,17 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
/**
* Execution path for downgrade.
- * @param clusterName the name of the cluster the downgrade is for
- * @param version the target version of the downgrade
+ *
+ * @param clusterName
+ * the name of the cluster the downgrade is for
+ * @paran originalStackId the stack ID of the cluster before the upgrade.
+ * @paran targetStackId the stack ID that was desired for this upgrade.
+ * @param version
+ * the target version of the downgrade
* @return the command report
*/
- private CommandReport executeDowngrade(String clusterName, String version)
+ private CommandReport executeDowngrade(String clusterName,
+ StackId originalStackId, StackId targetStackId, String version)
throws AmbariException, InterruptedException {
StringBuilder out = new StringBuilder();
@@ -245,8 +269,16 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
StackId desiredClusterStackId = cluster.getDesiredStackVersion();
StackId currentClusterStackId = cluster.getCurrentStackVersion();
+ // this was a cross-stack upgrade, meaning that configurations were
+ // created that now need to be removed
+ if (!originalStackId.equals(targetStackId)) {
+ cluster.removeConfigurations(targetStackId);
+ }
+
// !!! find and make sure the cluster_version EXCEPT current are set back
- out.append(String.format("Searching for current version for %s\n", clusterName));
+ out.append(String.format("Searching for current version for %s\n",
+ clusterName));
+
ClusterVersionEntity clusterVersion = clusterVersionDAO.findByClusterAndStateCurrent(clusterName);
if (null == clusterVersion) {
throw new AmbariException("Could not find current cluster version");
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/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 209293f..19fe2dd 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
@@ -42,43 +42,43 @@ public interface Cluster {
/**
* Get the cluster ID
*/
- public long getClusterId();
+ long getClusterId();
/**
* Get the Cluster Name
*/
- public String getClusterName();
+ String getClusterName();
/**
* Set the Cluster Name
*/
- public void setClusterName(String clusterName);
+ void setClusterName(String clusterName);
/**
* Add a service to a cluster
* @param service
*/
- public void addService(Service service) throws AmbariException;
+ void addService(Service service) throws AmbariException;
/**
* Get a service
* @param serviceName
* @return
*/
- public Service getService(String serviceName) throws AmbariException;
+ Service getService(String serviceName) throws AmbariException;
/**
* Get all services
* @return
*/
- public Map<String, Service> getServices();
+ Map<String, Service> getServices();
/**
* Get all ServiceComponentHosts on a given host
* @param hostname
* @return
*/
- public List<ServiceComponentHost> getServiceComponentHosts(String hostname);
+ List<ServiceComponentHost> getServiceComponentHosts(String hostname);
/**
@@ -87,39 +87,40 @@ public interface Cluster {
* @param componentName
* @return
*/
- public Set<String> getHosts(String serviceName, String componentName);
+ Set<String> getHosts(String serviceName, String componentName);
/**
* Remove ServiceComponentHost from cluster
* @param svcCompHost
*/
- public void removeServiceComponentHost(ServiceComponentHost svcCompHost) throws AmbariException;
+ void removeServiceComponentHost(ServiceComponentHost svcCompHost)
+ throws AmbariException;
/**
* Get the ClusterVersionEntity object whose state is CURRENT.
* @return
*/
- public ClusterVersionEntity getCurrentClusterVersion();
+ ClusterVersionEntity getCurrentClusterVersion();
/**
* Get all of the ClusterVersionEntity objects for the cluster.
* @return
*/
- public Collection<ClusterVersionEntity> getAllClusterVersions();
+ Collection<ClusterVersionEntity> getAllClusterVersions();
/**
* Get desired stack version
* @return
*/
- public StackId getDesiredStackVersion();
+ StackId getDesiredStackVersion();
/**
* Set desired stack version
* @param stackVersion
*/
- public void setDesiredStackVersion(StackId stackVersion) throws AmbariException;
+ void setDesiredStackVersion(StackId stackVersion) throws AmbariException;
/**
* Sets the desired stack version, optionally setting all owned services,
@@ -134,13 +135,13 @@ public interface Cluster {
* Get current stack version
* @return
*/
- public StackId getCurrentStackVersion();
+ StackId getCurrentStackVersion();
/**
* Set current stack version
* @param stackVersion
*/
- public void setCurrentStackVersion(StackId stackVersion) throws AmbariException;
+ void setCurrentStackVersion(StackId stackVersion) throws AmbariException;
/**
* Create host versions for all of the hosts that don't already have the stack version.
@@ -149,7 +150,9 @@ public interface Cluster {
* @param desiredState Desired state must be {@link RepositoryVersionState#CURRENT} or {@link RepositoryVersionState#UPGRADING}
* @throws AmbariException
*/
- public void mapHostVersions(Set<String> hostNames, ClusterVersionEntity currentClusterVersion, RepositoryVersionState desiredState) throws AmbariException;
+ void mapHostVersions(Set<String> hostNames,
+ ClusterVersionEntity currentClusterVersion,
+ RepositoryVersionState desiredState) throws AmbariException;
/**
* Create/update host versions for all of the hosts within a cluster based on state of cluster stack version.
@@ -160,7 +163,8 @@ public interface Cluster {
* of a cluster version is {@link RepositoryVersionState#INSTALLING}
* @throws AmbariException
*/
- public void inferHostVersions(ClusterVersionEntity sourceClusterVersion) throws AmbariException;
+ void inferHostVersions(ClusterVersionEntity sourceClusterVersion)
+ throws AmbariException;
/**
* For a given host, will either either update an existing Host Version Entity for the given version, or create
@@ -172,7 +176,9 @@ public interface Cluster {
* @return Returns either the newly created or the updated Host Version Entity.
* @throws AmbariException
*/
- public HostVersionEntity transitionHostVersionState(HostEntity host, final RepositoryVersionEntity repositoryVersion, final StackId stack) throws AmbariException;
+ HostVersionEntity transitionHostVersionState(HostEntity host,
+ final RepositoryVersionEntity repositoryVersion, final StackId stack)
+ throws AmbariException;
/**
* Update state of a cluster stack version for cluster based on states of host versions and stackids.
@@ -186,7 +192,7 @@ public interface Cluster {
* Update state of all cluster stack versions for cluster based on states of host versions.
* @throws AmbariException
*/
- public void recalculateAllClusterVersionStates() throws AmbariException;
+ void recalculateAllClusterVersionStates() throws AmbariException;
/**
* Create a cluster version for the given stack and version, whose initial
@@ -204,7 +210,7 @@ public interface Cluster {
* Initial state
* @throws AmbariException
*/
- public void createClusterVersion(StackId stackId, String version,
+ void createClusterVersion(StackId stackId, String version,
String userName, RepositoryVersionState state) throws AmbariException;
/**
@@ -218,7 +224,7 @@ public interface Cluster {
* Desired state
* @throws AmbariException
*/
- public void transitionClusterVersion(StackId stackId, String version,
+ void transitionClusterVersion(StackId stackId, String version,
RepositoryVersionState state) throws AmbariException;
/**
@@ -228,7 +234,7 @@ public interface Cluster {
* @return either {@link State#INIT} or {@link State#INSTALLED}, never
* {@code null}.
*/
- public State getProvisioningState();
+ State getProvisioningState();
/**
* Sets the provisioning state of the cluster.
@@ -236,21 +242,21 @@ public interface Cluster {
* @param provisioningState
* the provisioning state, not {@code null}.
*/
- public void setProvisioningState(State provisioningState);
+ void setProvisioningState(State provisioningState);
/**
* Gets the cluster's security type.
*
* @return this Cluster's security type
*/
- public SecurityType getSecurityType();
+ SecurityType getSecurityType();
/**
* Sets this Cluster's security type.
*
* @param securityType a SecurityType to set
*/
- public void setSecurityType(SecurityType securityType);
+ void setSecurityType(SecurityType securityType);
/**
* Gets all configs that match the specified type. Result is not the
@@ -258,7 +264,7 @@ public interface Cluster {
* @param configType the config type to return
* @return a map of configuration objects that have been set for the given type
*/
- public Map<String, Config> getConfigsByType(String configType);
+ Map<String, Config> getConfigsByType(String configType);
/**
* Gets the specific config that matches the specified type and tag. This not
@@ -268,20 +274,20 @@ public interface Cluster {
* @return a {@link Config} object, or <code>null</code> if the specific type
* and version have not been set.
*/
- public Config getConfig(String configType, String versionTag);
+ Config getConfig(String configType, String versionTag);
/**
* Sets a specific config. NOTE: This is not a DESIRED configuration that
* applies to a cluster.
* @param config the config instance to add
*/
- public void addConfig(Config config);
+ void addConfig(Config config);
/**
* Gets all configurations defined for a cluster.
* @return the collection of all configs that have been defined.
*/
- public Collection<Config> getAllConfigs();
+ Collection<Config> getAllConfigs();
/**
* Adds and sets a DESIRED configuration to be applied to a cluster. There
@@ -291,7 +297,7 @@ public interface Cluster {
* @return <code>true</code> if the config was added, or <code>false</code>
* if the config is already set as the current
*/
- public ServiceConfigVersionResponse addDesiredConfig(String user, Set<Config> configs);
+ ServiceConfigVersionResponse addDesiredConfig(String user, Set<Config> configs);
/**
* Adds and sets a DESIRED configuration to be applied to a cluster. There
@@ -338,13 +344,13 @@ public interface Cluster {
* @return the {@link Config} instance, or <code>null</code> if the type has
* not been set.
*/
- public Config getDesiredConfigByType(String configType);
+ Config getDesiredConfigByType(String configType);
/**
* Gets the desired configurations for the cluster.
* @return a map of type-to-configuration information.
*/
- public Map<String, DesiredConfig> getDesiredConfigs();
+ Map<String, DesiredConfig> getDesiredConfigs();
/**
@@ -352,43 +358,43 @@ public interface Cluster {
* @return
* @throws AmbariException
*/
- public ClusterResponse convertToResponse() throws AmbariException;
+ ClusterResponse convertToResponse() throws AmbariException;
/**
* Refreshes the cluster details
*/
- public void refresh();
+ void refresh();
/**
* Creates a debug dump based on the current cluster state
* @param sb
*/
- public void debugDump(StringBuilder sb);
+ void debugDump(StringBuilder sb);
/**
* Delete all the services associated with this cluster
* @throws AmbariException
*/
- public void deleteAllServices() throws AmbariException;
+ void deleteAllServices() throws AmbariException;
/**
* Delete the named service associated with this cluster
* @param serviceName
* @throws AmbariException
*/
- public void deleteService(String serviceName) throws AmbariException;
+ void deleteService(String serviceName) throws AmbariException;
/**
* Gets if the cluster can be deleted
* @return
*/
- public boolean canBeRemoved();
+ boolean canBeRemoved();
/**
* Delete the cluster
* @throws AmbariException
*/
- public void delete() throws AmbariException;
+ void delete() throws AmbariException;
/**
* Add service to the cluster
@@ -423,47 +429,49 @@ public interface Cluster {
* @param configGroup
* @throws AmbariException
*/
- public void addConfigGroup(ConfigGroup configGroup) throws AmbariException;
+ void addConfigGroup(ConfigGroup configGroup) throws AmbariException;
/**
* Get config groups associated with this cluster
* @return unmodifiable map of config group id to config group. Will not return null.
*/
- public Map<Long, ConfigGroup> getConfigGroups();
+ Map<Long, ConfigGroup> getConfigGroups();
/**
* Delete this config group identified by the config group id
* @param id
* @throws AmbariException
*/
- public void deleteConfigGroup(Long id) throws AmbariException;
+ void deleteConfigGroup(Long id) throws AmbariException;
/**
* Find all config groups associated with the give hostname
* @param hostname
* @return Map of config group id to config group
*/
- public Map<Long, ConfigGroup> getConfigGroupsByHostname(String hostname) throws AmbariException;
+ Map<Long, ConfigGroup> getConfigGroupsByHostname(String hostname)
+ throws AmbariException;
/**
* Add a @RequestExecution to the cluster
* @param requestExecution
* @throws AmbariException
*/
- public void addRequestExecution(RequestExecution requestExecution) throws AmbariException;
+ void addRequestExecution(RequestExecution requestExecution)
+ throws AmbariException;
/**
* Get all @RequestExecution objects associated with the cluster
* @return
*/
- public Map<Long, RequestExecution> getAllRequestExecutions();
+ Map<Long, RequestExecution> getAllRequestExecutions();
/**
* Delete a @RequestExecution associated with the cluster
* @param id
* @throws AmbariException
*/
- public void deleteRequestExecution(Long id) throws AmbariException;
+ void deleteRequestExecution(Long id) throws AmbariException;
/**
* Get next version of specified config type
@@ -489,14 +497,14 @@ public interface Cluster {
*
* @return true if the access to this cluster is allowed
*/
- public boolean checkPermission(PrivilegeEntity privilegeEntity, boolean readOnly);
+ boolean checkPermission(PrivilegeEntity privilegeEntity, boolean readOnly);
/**
* Add the given map of attributes to the session for this cluster.
*
* @param attributes the session attributes
*/
- public void addSessionAttributes(Map<String, Object> attributes);
+ void addSessionAttributes(Map<String, Object> attributes);
/**
* Sets or adds an attribute in the session for this cluster
@@ -504,20 +512,43 @@ public interface Cluster {
* @param key the name of the key which identifies the attribute in the map
* @param value the value to set
*/
- public void setSessionAttribute(String key, Object value);
+ void setSessionAttribute(String key, Object value);
/**
* Removes an attribute from the session for this cluster
*
* @param key the name of the key which identifies the attribute in the map
*/
- public void removeSessionAttribute(String key);
+ void removeSessionAttribute(String key);
/**
* Get the map of session attributes for this cluster.
*
* @return the map of session attributes for this cluster; never null
*/
- public Map<String, Object> getSessionAttributes();
+ Map<String, Object> getSessionAttributes();
+ /**
+ * Makes the most recent configurations in the specified stack the current set
+ * of configurations. This method will first ensure that the cluster's current
+ * stack matches that of the configuration stack specified.
+ * <p/>
+ * When completed, all other configurations for any other stack will remain,
+ * but will not be marked as selected.
+ *
+ * @param stackId
+ * the stack to use when finding the latest configurations (not
+ * {@code null}).
+ */
+ void applyLatestConfigurations(StackId stackId);
+
+ /**
+ * Removes all cluster configurations and service configurations that belong
+ * to the specified stack.
+ *
+ * @param stackId
+ * the stack to use when finding the configurations to remove (not
+ * {@code null}).
+ */
+ void removeConfigurations(StackId stackId);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
index 6436e22..6dbde09 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
@@ -32,6 +32,21 @@ import org.apache.ambari.server.state.stack.upgrade.Direction;
public class UpgradeContext {
private String m_version;
+
+ /**
+ * The original "current" stack of the cluster before the upgrade started.
+ * This is the same regardless of whether the current direction is
+ * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE}.
+ */
+ private StackId m_originalStackId;
+
+ /**
+ * The target upgrade stack before the upgrade started. This is the same
+ * regardless of whether the current direction is {@link Direction#UPGRADE} or
+ * {@link Direction#DOWNGRADE}.
+ */
+ private StackId m_targetStackId;
+
private Direction m_direction;
private MasterHostResolver m_resolver;
private AmbariMetaInfo m_metaInfo;
@@ -41,13 +56,30 @@ public class UpgradeContext {
/**
* Constructor.
- * @param resolver the resolver that also references the required cluster
- * @param version the target version to upgrade to
- * @param direction the direction for the upgrade
+ *
+ * @param resolver
+ * the resolver that also references the required cluster
+ * @param sourceStackId
+ * the original "current" stack of the cluster before the upgrade
+ * started. This is the same regardless of whether the current
+ * direction is {@link Direction#UPGRADE} or
+ * {@link Direction#DOWNGRADE} (not {@code null}).
+ * @param targetStackId
+ * The target upgrade stack before the upgrade started. This is the
+ * same regardless of whether the current direction is
+ * {@link Direction#UPGRADE} or {@link Direction#DOWNGRADE} (not
+ * {@code null}).
+ * @param version
+ * the target version to upgrade to
+ * @param direction
+ * the direction for the upgrade
*/
- public UpgradeContext(MasterHostResolver resolver, String version,
+ public UpgradeContext(MasterHostResolver resolver, StackId sourceStackId,
+ StackId targetStackId, String version,
Direction direction) {
m_version = version;
+ m_originalStackId = sourceStackId;
+ m_targetStackId = targetStackId;
m_direction = direction;
m_resolver = resolver;
}
@@ -102,6 +134,36 @@ public class UpgradeContext {
}
/**
+ * @return the originalStackId
+ */
+ public StackId getOriginalStackId() {
+ return m_originalStackId;
+ }
+
+ /**
+ * @param originalStackId
+ * the originalStackId to set
+ */
+ public void setOriginalStackId(StackId originalStackId) {
+ m_originalStackId = originalStackId;
+ }
+
+ /**
+ * @return the targetStackId
+ */
+ public StackId getTargetStackId() {
+ return m_targetStackId;
+ }
+
+ /**
+ * @param targetStackId
+ * the targetStackId to set
+ */
+ public void setTargetStackId(StackId targetStackId) {
+ m_targetStackId = targetStackId;
+ }
+
+ /**
* @return a map of host to list of components.
*/
public Map<String, List<String>> getUnhealthy() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/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 bb6f6c1..39219a3 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
@@ -259,24 +259,13 @@ public class ClusterImpl implements Cluster {
serviceComponentHosts = new HashMap<String,
Map<String, Map<String, ServiceComponentHost>>>();
+
serviceComponentHostsByHost = new HashMap<String,
List<ServiceComponentHost>>();
desiredStackVersion = new StackId(clusterEntity.getDesiredStack());
- allConfigs = new HashMap<String, Map<String, Config>>();
- if (!clusterEntity.getClusterConfigEntities().isEmpty()) {
- for (ClusterConfigEntity entity : clusterEntity.getClusterConfigEntities()) {
-
- if (!allConfigs.containsKey(entity.getType())) {
- allConfigs.put(entity.getType(), new HashMap<String, Config>());
- }
-
- Config config = configFactory.createExisting(this, entity);
-
- allConfigs.get(entity.getType()).put(entity.getTag(), config);
- }
- }
+ cacheConfigurations();
if (desiredStackVersion != null && !StringUtils.isEmpty(desiredStackVersion.getStackName()) && !
StringUtils.isEmpty(desiredStackVersion.getStackVersion())) {
@@ -2677,4 +2666,136 @@ public class ClusterImpl implements Cluster {
private String getClusterSessionAttributeName() {
return CLUSTER_SESSION_ATTRIBUTES_PREFIX + getClusterName();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Transactional
+ public void applyLatestConfigurations(StackId stackId) {
+ clusterGlobalLock.writeLock().lock();
+ try {
+ Collection<ClusterConfigMappingEntity> configMappingEntities = clusterEntity.getConfigMappingEntities();
+
+ // disable previous config
+ for (ClusterConfigMappingEntity e : configMappingEntities) {
+ e.setSelected(0);
+ }
+
+ List<ClusterConfigEntity> clusterConfigsToMakeSelected = clusterDAO.getLatestConfigurations(
+ clusterEntity.getClusterId(), stackId);
+
+ for( ClusterConfigEntity clusterConfigToMakeSelected : clusterConfigsToMakeSelected ){
+ for (ClusterConfigMappingEntity configMappingEntity : configMappingEntities) {
+ String tag = configMappingEntity.getTag();
+ String type = configMappingEntity.getType();
+
+ if (clusterConfigToMakeSelected.getTag().equals(tag)
+ && clusterConfigToMakeSelected.getType().equals(type)) {
+ configMappingEntity.setSelected(1);
+ }
+ }
+ }
+
+ clusterDAO.merge(clusterEntity);
+
+ cacheConfigurations();
+ } finally {
+ clusterGlobalLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Transactional
+ public void removeConfigurations(StackId stackId) {
+ clusterGlobalLock.writeLock().lock();
+ try {
+ long clusterId = clusterEntity.getClusterId();
+
+ // this will keep track of cluster config mappings that need removal
+ // since there is no relationship between configs and their mappings, we
+ // have to do it manually
+ List<ClusterConfigEntity> removedClusterConfigs = new ArrayList<ClusterConfigEntity>(50);
+ Collection<ClusterConfigEntity> clusterConfigEntities = clusterEntity.getClusterConfigEntities();
+
+ List<ClusterConfigEntity> clusterConfigs = clusterDAO.getAllConfigurations(
+ clusterId, stackId);
+
+ // remove any lefover cluster configurations that don't have a service
+ // configuration (like cluster-env)
+ for (ClusterConfigEntity clusterConfig : clusterConfigs) {
+ clusterDAO.removeConfig(clusterConfig);
+ clusterConfigEntities.remove(clusterConfig);
+
+ removedClusterConfigs.add(clusterConfig);
+ }
+
+ clusterEntity = clusterDAO.merge(clusterEntity);
+
+ List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigs(
+ clusterId, stackId);
+
+ // remove all service configurations
+ Collection<ServiceConfigEntity> serviceConfigEntities = clusterEntity.getServiceConfigEntities();
+ for (ServiceConfigEntity serviceConfig : serviceConfigs) {
+ serviceConfigDAO.remove(serviceConfig);
+ serviceConfigEntities.remove(serviceConfig);
+ }
+
+ clusterEntity = clusterDAO.merge(clusterEntity);
+
+ // remove config mappings
+ Collection<ClusterConfigMappingEntity> configMappingEntities = clusterEntity.getConfigMappingEntities();
+ for (ClusterConfigEntity removedClusterConfig : removedClusterConfigs) {
+ String removedClusterConfigType = removedClusterConfig.getType();
+ String removedClusterConfigTag = removedClusterConfig.getTag();
+
+ Iterator<ClusterConfigMappingEntity> clusterConfigMappingIterator = configMappingEntities.iterator();
+ while (clusterConfigMappingIterator.hasNext()) {
+ ClusterConfigMappingEntity clusterConfigMapping = clusterConfigMappingIterator.next();
+ String mappingType = clusterConfigMapping.getType();
+ String mappingTag = clusterConfigMapping.getTag();
+
+ if (removedClusterConfigTag.equals(mappingTag)
+ && removedClusterConfigType.equals(mappingType)) {
+ clusterConfigMappingIterator.remove();
+ clusterDAO.removeConfigMapping(clusterConfigMapping);
+ }
+ }
+ }
+
+ clusterEntity = clusterDAO.merge(clusterEntity);
+
+ cacheConfigurations();
+ } finally {
+ clusterGlobalLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Caches all of the {@link ClusterConfigEntity}s in {@link #allConfigs}.
+ */
+ private void cacheConfigurations() {
+ if (null == allConfigs) {
+ allConfigs = new HashMap<String, Map<String, Config>>();
+ }
+
+ allConfigs.clear();
+
+ if (!clusterEntity.getClusterConfigEntities().isEmpty()) {
+ for (ClusterConfigEntity entity : clusterEntity.getClusterConfigEntities()) {
+
+ if (!allConfigs.containsKey(entity.getType())) {
+ allConfigs.put(entity.getType(), new HashMap<String, Config>());
+ }
+
+ Config config = configFactory.createExisting(this, entity);
+
+ allConfigs.get(entity.getType()).put(entity.getTag(), config);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
index e7a5185..3d93e4d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/ServiceConfigDAOTest.java
@@ -31,6 +31,7 @@ import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.StackId;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -40,6 +41,9 @@ import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
public class ServiceConfigDAOTest {
+ private static final StackId HDP_01 = new StackId("HDP", "0.1");
+ private static final StackId HDP_02 = new StackId("HDP", "0.2");
+
private Injector injector;
private ServiceConfigDAO serviceConfigDAO;
private ClusterDAO clusterDAO;
@@ -79,13 +83,14 @@ public class ServiceConfigDAOTest {
resourceTypeEntity = resourceTypeDAO.merge(resourceTypeEntity);
}
- StackEntity stackEntity = stackDAO.find("HDP", "0.1");
-
ResourceEntity resourceEntity = new ResourceEntity();
resourceEntity.setResourceType(resourceTypeEntity);
ClusterEntity clusterEntity = clusterDAO.findByName("c1");
if (clusterEntity == null) {
+ StackEntity stackEntity = stackDAO.find(HDP_01.getStackName(),
+ HDP_01.getStackVersion());
+
clusterEntity = new ClusterEntity();
clusterEntity.setClusterName("c1");
clusterEntity.setResource(resourceEntity);
@@ -283,4 +288,49 @@ public class ServiceConfigDAOTest {
}
}
+ @Test
+ public void testGetAllServiceConfigs() throws Exception {
+ ServiceConfigEntity serviceConfigEntity = null;
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 1L, 1L, 10L, null);
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 2L, 2L, 20L, null);
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 3L, 3L, 30L, null);
+ serviceConfigEntity = createServiceConfig("YARN", "admin", 1L, 4L, 40L, null);
+
+ long clusterId = serviceConfigEntity.getClusterId();
+
+ List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getAllServiceConfigs(clusterId, HDP_01);
+ Assert.assertEquals(4, serviceConfigs.size());
+
+ serviceConfigs = serviceConfigDAO.getAllServiceConfigs(clusterId, HDP_02);
+ Assert.assertEquals(0, serviceConfigs.size());
+ }
+
+ @Test
+ public void testGetLatestServiceConfigs() throws Exception {
+ ServiceConfigEntity serviceConfigEntity = null;
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 1L, 1L, 10L, null);
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 2L, 2L, 20L, null);
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 3L, 3L, 30L, null);
+ serviceConfigEntity = createServiceConfig("YARN", "admin", 1L, 4L, 40L, null);
+
+ StackEntity stackEntity = stackDAO.find(HDP_02.getStackName(),
+ HDP_02.getStackVersion());
+
+ ClusterEntity clusterEntity = serviceConfigEntity.getClusterEntity();
+ clusterEntity.setDesiredStack(stackEntity);
+ clusterDAO.merge(clusterEntity);
+
+ // create some for HDP 0.2
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 4L, 5L, 50L, null);
+ serviceConfigEntity = createServiceConfig("HDFS", "admin", 5L, 6L, 60L, null);
+ serviceConfigEntity = createServiceConfig("YARN", "admin", 2L, 7L, 70L, null);
+
+ long clusterId = serviceConfigEntity.getClusterId();
+
+ List<ServiceConfigEntity> serviceConfigs = serviceConfigDAO.getLatestServiceConfigs(clusterId, HDP_01);
+ Assert.assertEquals(2, serviceConfigs.size());
+
+ serviceConfigs = serviceConfigDAO.getLatestServiceConfigs(clusterId, HDP_02);
+ Assert.assertEquals(2, serviceConfigs.size());
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac6fd63f/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
index fc86c7a..e03c2f5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/UpgradeActionTest.java
@@ -21,10 +21,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ServiceComponentNotFoundException;
+import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
import org.apache.ambari.server.actionmanager.HostRoleCommand;
import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
@@ -46,11 +50,21 @@ import org.apache.ambari.server.orm.entities.HostVersionEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigImpl;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.RepositoryInfo;
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.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -76,7 +90,7 @@ public class UpgradeActionTest {
private Injector m_injector;
@Inject
- private OrmTestHelper helper;
+ private OrmTestHelper m_helper;
@Inject
private RepositoryVersionDAO repoVersionDAO;
@@ -93,18 +107,20 @@ public class UpgradeActionTest {
@Inject
private HostRoleCommandFactory hostRoleCommandFactory;
+ @Inject
+ private ServiceFactory serviceFactory;
+
+ @Inject
+ private ServiceComponentFactory serviceComponentFactory;
+
+ @Inject
+ private ServiceComponentHostFactory serviceComponentHostFactory;
+
@Before
public void setup() throws Exception {
m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
m_injector.getInstance(GuiceJpaInitializer.class);
-
- helper = m_injector.getInstance(OrmTestHelper.class);
-
- repoVersionDAO = m_injector.getInstance(RepositoryVersionDAO.class);
- clusterVersionDAO = m_injector.getInstance(ClusterVersionDAO.class);
- hostVersionDAO = m_injector.getInstance(HostVersionDAO.class);
- hostDAO = m_injector.getInstance(HostDAO.class);
- hostRoleCommandFactory = m_injector.getInstance(HostRoleCommandFactory.class);
+ m_injector.injectMembers(this);
}
@After
@@ -132,8 +148,8 @@ public class UpgradeActionTest {
host.setHostAttributes(hostAttributes);
host.persist();
- helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
- helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_1_0);
+ m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
+ m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_1_0);
c.createClusterVersion(HDP_21_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
c.createClusterVersion(HDP_21_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
@@ -147,8 +163,7 @@ public class UpgradeActionTest {
HostVersionEntity entity = new HostVersionEntity();
entity.setHostEntity(hostDAO.findByName(hostName));
- entity.setRepositoryVersion(
- repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
+ entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
entity.setState(RepositoryVersionState.UPGRADING);
hostVersionDAO.create(entity);
}
@@ -180,14 +195,13 @@ public class UpgradeActionTest {
host.setHostAttributes(hostAttributes);
host.persist();
- String urlInfo = "[{'repositories':[" +
- "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}" +
- "], 'OperatingSystems/os_type':'redhat6'}]";
+ String urlInfo = "[{'repositories':["
+ + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}"
+ + "], 'OperatingSystems/os_type':'redhat6'}]";
- helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
- repoVersionDAO.create(stackEntity, HDP_2_2_1_0,
- String.valueOf(System.currentTimeMillis()), "pack",
- urlInfo);
+ m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_2_0_0);
+ repoVersionDAO.create(stackEntity, HDP_2_2_1_0, String.valueOf(System.currentTimeMillis()),
+ "pack", urlInfo);
c.createClusterVersion(HDP_21_STACK, HDP_2_2_0_0, "admin", RepositoryVersionState.UPGRADING);
c.createClusterVersion(HDP_21_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
@@ -205,8 +219,7 @@ public class UpgradeActionTest {
HostVersionEntity entity = new HostVersionEntity();
entity.setHostEntity(hostDAO.findByName(hostName));
- entity.setRepositoryVersion(
- repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
+ entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_21_STACK, HDP_2_2_1_0));
entity.setState(RepositoryVersionState.UPGRADED);
hostVersionDAO.create(entity);
}
@@ -230,7 +243,6 @@ public class UpgradeActionTest {
// add a host component
clusters.addHost(hostName);
-
Host host = clusters.getHost(hostName);
Map<String, String> hostAttributes = new HashMap<String, String>();
@@ -239,16 +251,17 @@ public class UpgradeActionTest {
host.setHostAttributes(hostAttributes);
host.persist();
- String urlInfo = "[{'repositories':[" +
- "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}" +
- "], 'OperatingSystems/os_type':'redhat6'}]";
+ clusters.mapHostToCluster(hostName, clusterName);
+
+ String urlInfo = "[{'repositories':["
+ + "{'Repositories/base_url':'http://foo1','Repositories/repo_name':'HDP','Repositories/repo_id':'HDP-2.1.1'}"
+ + "], 'OperatingSystems/os_type':'redhat6'}]";
- helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_1_1_0);
- helper.getOrCreateRepositoryVersion(HDP_22_STACK, HDP_2_2_1_0);
+ m_helper.getOrCreateRepositoryVersion(HDP_21_STACK, HDP_2_1_1_0);
+ m_helper.getOrCreateRepositoryVersion(HDP_22_STACK, HDP_2_2_1_0);
- repoVersionDAO.create(stackEntity, HDP_2_2_1_0,
- String.valueOf(System.currentTimeMillis()), "pack",
- urlInfo);
+ repoVersionDAO.create(stackEntity, HDP_2_2_1_0, String.valueOf(System.currentTimeMillis()),
+ "pack", urlInfo);
c.createClusterVersion(HDP_21_STACK, HDP_2_1_1_0, "admin", RepositoryVersionState.UPGRADING);
c.createClusterVersion(HDP_22_STACK, HDP_2_2_1_0, "admin", RepositoryVersionState.INSTALLING);
@@ -265,29 +278,25 @@ public class UpgradeActionTest {
HostVersionEntity entity = new HostVersionEntity();
entity.setHostEntity(hostDAO.findByName(hostName));
- entity.setRepositoryVersion(
- repoVersionDAO.findByStackAndVersion(HDP_22_STACK, HDP_2_2_1_0));
+ entity.setRepositoryVersion(repoVersionDAO.findByStackAndVersion(HDP_22_STACK, HDP_2_2_1_0));
entity.setState(RepositoryVersionState.UPGRADED);
hostVersionDAO.create(entity);
}
-
@Test
public void testFinalizeDowngrade() throws Exception {
makeDowngradeCluster();
Map<String, String> commandParams = new HashMap<String, String>();
- commandParams.put("upgrade_direction", "downgrade");
- commandParams.put("version", HDP_2_2_0_0);
+ commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
+ commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_0_0);
ExecutionCommand executionCommand = new ExecutionCommand();
executionCommand.setCommandParams(commandParams);
executionCommand.setClusterName("c1");
- HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null,
- null, null);
- hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(
- executionCommand));
+ HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
+ hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
FinalizeUpgradeAction action = m_injector.getInstance(FinalizeUpgradeAction.class);
action.setExecutionCommand(executionCommand);
@@ -297,12 +306,10 @@ public class UpgradeActionTest {
assertNotNull(report);
assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus());
- for (HostVersionEntity entity : hostVersionDAO.findByClusterAndHost("c1",
- "h1")) {
+ for (HostVersionEntity entity : hostVersionDAO.findByClusterAndHost("c1", "h1")) {
if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_0_0)) {
assertEquals(RepositoryVersionState.CURRENT, entity.getState());
- } else if (entity.getRepositoryVersion().getVersion().equals(
-HDP_2_2_1_0)) {
+ } else if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_1_0)) {
assertEquals(RepositoryVersionState.INSTALLED, entity.getState());
}
}
@@ -310,8 +317,7 @@ HDP_2_2_1_0)) {
for (ClusterVersionEntity entity : clusterVersionDAO.findByCluster("c1")) {
if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_0_0)) {
assertEquals(RepositoryVersionState.CURRENT, entity.getState());
- } else if (entity.getRepositoryVersion().getVersion().equals(
-HDP_2_2_1_0)) {
+ } else if (entity.getRepositoryVersion().getVersion().equals(HDP_2_2_1_0)) {
assertEquals(RepositoryVersionState.INSTALLED, entity.getState());
}
}
@@ -322,17 +328,15 @@ HDP_2_2_1_0)) {
makeUpgradeCluster();
Map<String, String> commandParams = new HashMap<String, String>();
- commandParams.put("upgrade_direction", "upgrade");
- commandParams.put("version", HDP_2_2_1_0);
+ commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
+ commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_1_0);
ExecutionCommand executionCommand = new ExecutionCommand();
executionCommand.setCommandParams(commandParams);
executionCommand.setClusterName("c1");
- HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null,
- null, null);
- hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(
- executionCommand));
+ HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
+ hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
FinalizeUpgradeAction action = m_injector.getInstance(FinalizeUpgradeAction.class);
action.setExecutionCommand(executionCommand);
@@ -345,10 +349,8 @@ HDP_2_2_1_0)) {
// !!! verify the metainfo url has not been updated, but an output command
// has
AmbariMetaInfo metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
- RepositoryInfo repo = metaInfo.getRepository("HDP", "2.1.1", "redhat6",
- "HDP-2.1.1");
- assertEquals(
- "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.1.1.0-118",
+ RepositoryInfo repo = metaInfo.getRepository("HDP", "2.1.1", "redhat6", "HDP-2.1.1");
+ assertEquals("http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.1.1.0-118",
repo.getBaseUrl());
// !!! verify that a command will return the correct host info
@@ -384,18 +386,18 @@ HDP_2_2_1_0)) {
cluster.setDesiredStackVersion(HDP_22_STACK);
Map<String, String> commandParams = new HashMap<String, String>();
- commandParams.put("upgrade_direction", "upgrade");
- commandParams.put("version", HDP_2_2_1_0);
+ commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "upgrade");
+ commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_2_1_0);
+ commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, HDP_21_STACK.getStackId());
+ commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, HDP_22_STACK.getStackId());
ExecutionCommand executionCommand = new ExecutionCommand();
executionCommand.setCommandParams(commandParams);
executionCommand.setClusterName("c1");
- HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null,
- null, null);
+ HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
- hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(
- executionCommand));
+ hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
FinalizeUpgradeAction action = m_injector.getInstance(FinalizeUpgradeAction.class);
action.setExecutionCommand(executionCommand);
@@ -408,8 +410,149 @@ HDP_2_2_1_0)) {
StackId currentStackId = cluster.getCurrentStackVersion();
StackId desiredStackId = cluster.getDesiredStackVersion();
+ // verify current/desired stacks are updated to the new stack
assertEquals(desiredStackId, currentStackId);
assertEquals(HDP_22_STACK, currentStackId);
assertEquals(HDP_22_STACK, desiredStackId);
}
+
+ /**
+ * Tests some of the action items are completed when finalizing downgrade
+ * across stacks (HDP 2.2 -> HDP 2.3).
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFinalizeDowngradeAcrossStacks() throws Exception {
+ makeCrossStackUpgradeCluster();
+
+ Clusters clusters = m_injector.getInstance(Clusters.class);
+ Cluster cluster = clusters.getCluster("c1");
+
+ // install HDFS with some components
+ Service service = installService(cluster, "HDFS");
+ addServiceComponent(cluster, service, "NAMENODE");
+ addServiceComponent(cluster, service, "DATANODE");
+ createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", "h1");
+ createNewServiceComponentHost(cluster, "HDFS", "DATANODE", "h1");
+
+ // create some configs
+ createConfigs(cluster);
+
+ // setup the cluster for the upgrade across stacks
+ cluster.setCurrentStackVersion(HDP_21_STACK);
+ cluster.setDesiredStackVersion(HDP_22_STACK);
+
+ // now that the desired version is set, we can create some new configs in
+ // the new stack version
+ createConfigs(cluster);
+
+ // verify we have configs in both HDP stacks
+ cluster = clusters.getCluster("c1");
+ Collection<Config> configs = cluster.getAllConfigs();
+ assertEquals(6, configs.size());
+
+ Map<String, String> commandParams = new HashMap<String, String>();
+ commandParams.put(FinalizeUpgradeAction.UPGRADE_DIRECTION_KEY, "downgrade");
+ commandParams.put(FinalizeUpgradeAction.VERSION_KEY, HDP_2_1_1_0);
+ commandParams.put(FinalizeUpgradeAction.ORIGINAL_STACK_KEY, HDP_21_STACK.getStackId());
+ commandParams.put(FinalizeUpgradeAction.TARGET_STACK_KEY, HDP_22_STACK.getStackId());
+
+ ExecutionCommand executionCommand = new ExecutionCommand();
+ executionCommand.setCommandParams(commandParams);
+ executionCommand.setClusterName("c1");
+
+ HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, null, null);
+
+ hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper(executionCommand));
+
+ FinalizeUpgradeAction action = m_injector.getInstance(FinalizeUpgradeAction.class);
+ action.setExecutionCommand(executionCommand);
+ action.setHostRoleCommand(hostRoleCommand);
+
+ CommandReport report = action.execute(null);
+ assertNotNull(report);
+ assertEquals(HostRoleStatus.COMPLETED.name(), report.getStatus());
+
+ StackId currentStackId = cluster.getCurrentStackVersion();
+ StackId desiredStackId = cluster.getDesiredStackVersion();
+
+ // verify current/desired stacks are back to normal
+ assertEquals(desiredStackId, currentStackId);
+ assertEquals(HDP_21_STACK, currentStackId);
+ assertEquals(HDP_21_STACK, desiredStackId);
+
+ // verify we have configs in only 1 stack
+ cluster = clusters.getCluster("c1");
+ configs = cluster.getAllConfigs();
+ assertEquals(3, configs.size());
+ }
+
+ private ServiceComponentHost createNewServiceComponentHost(Cluster cluster, String svc,
+ String svcComponent, String hostName) throws AmbariException {
+ Assert.assertNotNull(cluster.getConfigGroups());
+ Service s = installService(cluster, svc);
+ ServiceComponent sc = addServiceComponent(cluster, s, svcComponent);
+
+ ServiceComponentHost sch = serviceComponentHostFactory.createNew(sc, hostName);
+
+ sc.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(cluster.getDesiredStackVersion());
+ sch.setStackVersion(cluster.getCurrentStackVersion());
+
+ sch.persist();
+ return sch;
+ }
+
+ private Service installService(Cluster cluster, String serviceName) throws AmbariException {
+ Service service = null;
+
+ try {
+ service = cluster.getService(serviceName);
+ } catch (ServiceNotFoundException e) {
+ service = serviceFactory.createNew(cluster, serviceName);
+ cluster.addService(service);
+ service.persist();
+ }
+
+ return service;
+ }
+
+ private ServiceComponent addServiceComponent(Cluster cluster, Service service,
+ String componentName) throws AmbariException {
+ ServiceComponent serviceComponent = null;
+ try {
+ serviceComponent = service.getServiceComponent(componentName);
+ } catch (ServiceComponentNotFoundException e) {
+ serviceComponent = serviceComponentFactory.createNew(service, componentName);
+ service.addServiceComponent(serviceComponent);
+ serviceComponent.setDesiredState(State.INSTALLED);
+ serviceComponent.persist();
+ }
+
+ return serviceComponent;
+ }
+
+ private void createConfigs(Cluster cluster) {
+ Map<String, String> properties = new HashMap<String, String>();
+ Map<String, Map<String, String>> propertiesAttributes = new HashMap<String, Map<String, String>>();
+ properties.put("a", "a1");
+ properties.put("b", "b1");
+
+ Config c1 = new ConfigImpl(cluster, "hdfs-site", properties, propertiesAttributes, m_injector);
+ properties.put("c", "c1");
+ properties.put("d", "d1");
+
+ Config c2 = new ConfigImpl(cluster, "core-site", properties, propertiesAttributes, m_injector);
+ Config c3 = new ConfigImpl(cluster, "foo-site", properties, propertiesAttributes, m_injector);
+
+ cluster.addConfig(c1);
+ cluster.addConfig(c2);
+ cluster.addConfig(c3);
+ c1.persist();
+ c2.persist();
+ c3.persist();
+ }
}