You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/10/12 14:21:32 UTC
[7/8] ambari git commit: AMBARI-13378. Stop-and-Start Upgrade: Merge
feature branch to trunk. (dgrinenko via dlysnichenko)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/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 e9ac429..6fe074d 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
@@ -78,6 +78,7 @@ import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
import org.apache.ambari.server.stack.MasterHostResolver;
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.ConfigHelper;
import org.apache.ambari.server.state.DesiredConfig;
@@ -87,6 +88,7 @@ import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.UpgradeContext;
import org.apache.ambari.server.state.UpgradeHelper;
import org.apache.ambari.server.state.UpgradeHelper.UpgradeGroupHolder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
import org.apache.ambari.server.state.stack.PrereqCheckStatus;
import org.apache.ambari.server.state.stack.UpgradePack;
import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
@@ -97,6 +99,8 @@ import org.apache.ambari.server.state.stack.upgrade.ServerSideActionTask;
import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
import org.apache.ambari.server.state.stack.upgrade.Task;
import org.apache.ambari.server.state.stack.upgrade.TaskWrapper;
+import org.apache.ambari.server.state.stack.upgrade.UpdateStackGrouping;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostServerActionEvent;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
@@ -114,6 +118,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
protected static final String UPGRADE_CLUSTER_NAME = "Upgrade/cluster_name";
protected static final String UPGRADE_VERSION = "Upgrade/repository_version";
+ protected static final String UPGRADE_TYPE = "Upgrade/type";
+ protected static final String UPGRADE_PACK = "Upgrade/pack";
protected static final String UPGRADE_REQUEST_ID = "Upgrade/request_id";
protected static final String UPGRADE_FROM_VERSION = "Upgrade/from_version";
protected static final String UPGRADE_TO_VERSION = "Upgrade/to_version";
@@ -153,6 +159,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
private static final String COMMAND_PARAM_VERSION = VERSION;
private static final String COMMAND_PARAM_CLUSTER_NAME = "clusterName";
private static final String COMMAND_PARAM_DIRECTION = "upgrade_direction";
+ // TODO AMBARI-12698, change this variable name since it is no longer always a restart. Possible values are rolling_upgrade or nonrolling_upgrade
+ // This will involve changing Script.py
private static final String COMMAND_PARAM_RESTART_TYPE = "restart_type";
private static final String COMMAND_PARAM_TASKS = "tasks";
private static final String COMMAND_PARAM_STRUCT_OUT = "structured_out";
@@ -192,6 +200,9 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
private static Provider<StageFactory> s_stageFactory;
@Inject
+ private static Provider<Clusters> clusters = null;
+
+ @Inject
private static Provider<AmbariActionExecutionHelper> s_actionExecutionHelper;
@Inject
@@ -216,6 +227,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
// properties
PROPERTY_IDS.add(UPGRADE_CLUSTER_NAME);
PROPERTY_IDS.add(UPGRADE_VERSION);
+ PROPERTY_IDS.add(UPGRADE_TYPE);
+ PROPERTY_IDS.add(UPGRADE_PACK);
PROPERTY_IDS.add(UPGRADE_REQUEST_ID);
PROPERTY_IDS.add(UPGRADE_FROM_VERSION);
PROPERTY_IDS.add(UPGRADE_TO_VERSION);
@@ -437,6 +450,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
ResourceImpl resource = new ResourceImpl(Resource.Type.Upgrade);
setResourceProperty(resource, UPGRADE_CLUSTER_NAME, clusterName, requestedIds);
+ setResourceProperty(resource, UPGRADE_TYPE, entity.getUpgradeType().toString(), requestedIds);
+ setResourceProperty(resource, UPGRADE_PACK, entity.getUpgradePackage(), requestedIds);
setResourceProperty(resource, UPGRADE_REQUEST_ID, entity.getRequestId(), requestedIds);
setResourceProperty(resource, UPGRADE_FROM_VERSION, entity.getFromVersion(), requestedIds);
setResourceProperty(resource, UPGRADE_TO_VERSION, entity.getToVersion(), requestedIds);
@@ -458,8 +473,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
String clusterName = (String) requestMap.get(UPGRADE_CLUSTER_NAME);
String version = (String) requestMap.get(UPGRADE_VERSION);
String versionForUpgradePack = (String) requestMap.get(UPGRADE_FROM_VERSION);
- boolean skipPrereqChecks = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_PREREQUISITE_CHECKS));
- boolean failOnCheckWarnings = Boolean.parseBoolean((String) requestMap.get(UPGRADE_FAIL_ON_CHECK_WARNINGS));
+
+ // Default to ROLLING upgrade, but attempt to read from properties.
+ final UpgradeType upgradeType = requestMap.containsKey(UPGRADE_TYPE) ?
+ UpgradeType.valueOf((String) requestMap.get(UPGRADE_TYPE)) : UpgradeType.ROLLING;
if (null == clusterName) {
throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME));
@@ -469,60 +486,41 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
throw new AmbariException(String.format("%s is required", UPGRADE_VERSION));
}
- Cluster cluster = getManagementController().getClusters().getCluster(clusterName);
-
- // !!! find upgrade packs based on current stack. This is where to upgrade
- // from.
- StackId stack = cluster.getCurrentStackVersion();
-
- String repoVersion = version;
-
- if (direction.isDowngrade() && null != versionForUpgradePack) {
- repoVersion = versionForUpgradePack;
- }
-
- RepositoryVersionEntity versionEntity = s_repoVersionDAO.findByStackNameAndVersion(stack.getStackName(), repoVersion);
-
- if (null == versionEntity) {
- throw new AmbariException(String.format("Repository version %s was not found", repoVersion));
- }
-
- Map<String, UpgradePack> packs = s_metaProvider.get().getUpgradePacks(stack.getStackName(),
- stack.getStackVersion());
+ // Do not insert here additional checks! Wrap them to separate functions.
+ // Pre-req checks, function generate exceptions if something going wrong
+ validatePreRequest(clusterName, direction, version, requestMap);
- UpgradePack up = packs.get(versionEntity.getUpgradePackage());
+ return s_upgradeHelper.suggestUpgradePack(clusterName, versionForUpgradePack, version, direction, upgradeType);
+ }
- if (null == up) {
- // !!! in case there is an upgrade pack that doesn't match the name
- String repoStackId = versionEntity.getStackId().getStackId();
- for (UpgradePack upgradePack : packs.values()) {
- if (null != upgradePack.getTargetStack()
- && upgradePack.getTargetStack().equals(repoStackId)) {
- up = upgradePack;
- break;
- }
- }
- }
+ /**
+ * Pre-req checks
+ * @param clusterName Name of the cluster
+ * @param direction Direction of upgrade
+ * @param repoVersion target repository version
+ * @param requestMap request arguments
+ * @throws AmbariException
+ */
+ private void validatePreRequest(String clusterName, Direction direction, String repoVersion, Map<String, Object> requestMap)
+ throws AmbariException{
- if (null == up) {
- throw new AmbariException(
- String.format("Unable to perform %s. Could not locate upgrade pack %s for version %s",
- direction.getText(false), versionEntity.getUpgradePackage(), repoVersion));
- }
+ Cluster cluster = clusters.get().getCluster(clusterName);
+ boolean skipPrereqChecks = Boolean.parseBoolean((String) requestMap.get(UPGRADE_SKIP_PREREQUISITE_CHECKS));
+ boolean failOnCheckWarnings = Boolean.parseBoolean((String) requestMap.get(UPGRADE_FAIL_ON_CHECK_WARNINGS));
// Validate there isn't an direction == upgrade/downgrade already in progress.
List<UpgradeEntity> upgrades = s_upgradeDAO.findUpgrades(cluster.getClusterId());
for (UpgradeEntity entity : upgrades) {
if(entity.getDirection() == direction) {
Map<Long, HostRoleCommandStatusSummaryDTO> summary = s_hostRoleCommandDAO.findAggregateCounts(
- entity.getRequestId());
+ entity.getRequestId());
CalculatedStatus calc = CalculatedStatus.statusFromStageSummary(summary, summary.keySet());
HostRoleStatus status = calc.getStatus();
if(!HostRoleStatus.getCompletedStates().contains(status)) {
throw new AmbariException(
- String.format("Unable to perform %s as another %s is in progress. %s %d is in %s",
- direction.getText(false), direction.getText(false), direction.getText(true),
- entity.getRequestId().longValue(), status)
+ String.format("Unable to perform %s as another %s is in progress. %s %d is in %s",
+ direction.getText(false), direction.getText(false), direction.getText(true),
+ entity.getRequestId().longValue(), status)
);
}
}
@@ -531,29 +529,29 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
if(direction.isUpgrade() && !skipPrereqChecks) {
// Validate pre-req checks pass
PreUpgradeCheckResourceProvider preUpgradeCheckResourceProvider = (PreUpgradeCheckResourceProvider)
- getResourceProvider(Resource.Type.PreUpgradeCheck);
+ getResourceProvider(Resource.Type.PreUpgradeCheck);
Predicate preUpgradeCheckPredicate = new PredicateBuilder().property(
- PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID).equals(clusterName).and().property(
- PreUpgradeCheckResourceProvider.UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).equals(repoVersion).toPredicate();
+ PreUpgradeCheckResourceProvider.UPGRADE_CHECK_CLUSTER_NAME_PROPERTY_ID).equals(clusterName).and().property(
+ PreUpgradeCheckResourceProvider.UPGRADE_CHECK_REPOSITORY_VERSION_PROPERTY_ID).equals(repoVersion).toPredicate();
Request preUpgradeCheckRequest = PropertyHelper.getReadRequest();
Set<Resource> preUpgradeCheckResources;
try {
preUpgradeCheckResources = preUpgradeCheckResourceProvider.getResources(
- preUpgradeCheckRequest, preUpgradeCheckPredicate);
- } catch (NoSuchResourceException e) {
+ preUpgradeCheckRequest, preUpgradeCheckPredicate);
+ } catch (NoSuchResourceException|SystemException|UnsupportedPropertyException|NoSuchParentResourceException e) {
throw new AmbariException(
- String.format("Unable to perform %s. Prerequisite checks could not be run",
- direction.getText(false)));
+ String.format("Unable to perform %s. Prerequisite checks could not be run",
+ direction.getText(false)));
}
List<Resource> failedResources = new LinkedList<Resource>();
if (preUpgradeCheckResources != null) {
for(Resource res : preUpgradeCheckResources) {
String id = (String) res.getPropertyValue((PreUpgradeCheckResourceProvider.UPGRADE_CHECK_ID_PROPERTY_ID));
PrereqCheckStatus prereqCheckStatus = (PrereqCheckStatus) res.getPropertyValue(
- PreUpgradeCheckResourceProvider.UPGRADE_CHECK_STATUS_PROPERTY_ID);
+ PreUpgradeCheckResourceProvider.UPGRADE_CHECK_STATUS_PROPERTY_ID);
if(prereqCheckStatus == PrereqCheckStatus.FAIL
- || (failOnCheckWarnings && prereqCheckStatus == PrereqCheckStatus.WARNING)) {
+ || (failOnCheckWarnings && prereqCheckStatus == PrereqCheckStatus.WARNING)) {
failedResources.add(res);
}
}
@@ -561,12 +559,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
if(!failedResources.isEmpty()) {
Gson gson = new Gson();
throw new AmbariException(
- String.format("Unable to perform %s. Prerequisite checks failed %s",
- direction.getText(false), gson.toJson(failedResources)));
+ String.format("Unable to perform %s. Prerequisite checks failed %s",
+ direction.getText(false), gson.toJson(failedResources)));
}
}
-
- return up;
}
/**
@@ -642,7 +638,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
UpgradeContext ctx = new UpgradeContext(resolver, sourceStackId, targetStackId, version,
- direction);
+ direction, pack.getType());
if (direction.isDowngrade()) {
if (requestMap.containsKey(UPGRADE_FROM_VERSION)) {
@@ -682,9 +678,39 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
List<UpgradeGroupEntity> groupEntities = new ArrayList<UpgradeGroupEntity>();
RequestStageContainer req = createRequest(direction, version);
- // desired configs must be set before creating stages because the config tag
- // names are read and set on the command for filling in later
- processConfigurations(targetStackId.getStackName(), cluster, version, direction, pack);
+ /**
+ During a Rolling Upgrade, change the desired Stack Id if jumping across
+ major stack versions (e.g., HDP 2.2 -> 2.3), and then set config changes
+ so they are applied on the newer stack.
+
+ During a {@link UpgradeType.NON_ROLLING} upgrade, the stack is applied during the middle of the upgrade (after
+ stopping all services), and the configs are applied immediately before starting the services.
+ The Upgrade Pack is responsible for calling {@link org.apache.ambari.server.serveraction.upgrades.UpdateDesiredStackAction}
+ at the appropriate moment during the orchestration.
+ **/
+ if (pack.getType() == UpgradeType.ROLLING) {
+ // Desired configs must be set before creating stages because the config tag
+ // names are read and set on the command for filling in later
+ applyStackAndProcessConfigurations(targetStackId.getStackName(), cluster, version, direction, pack);
+ }
+
+ // Resolve or build a proper config upgrade pack
+ List<UpgradePack.IntermediateStack> intermediateStacks = pack.getIntermediateStacks();
+ ConfigUpgradePack configUpgradePack;
+ if (intermediateStacks == null || intermediateStacks.isEmpty()) { // No intermediate stacks
+ configUpgradePack = s_metaProvider.get().getConfigUpgradePack(
+ targetStackId.getStackName(), targetStackId.getStackVersion());
+ } else {
+ // For cross-stack upgrade, follow all major stacks and merge a new config upgrade pack from all
+ // target stacks involved into upgrade
+ ArrayList<ConfigUpgradePack> intermediateConfigUpgradePacks = new ArrayList<>();
+ for (UpgradePack.IntermediateStack intermediateStack : intermediateStacks) {
+ ConfigUpgradePack intermediateConfigUpgradePack = s_metaProvider.get().getConfigUpgradePack(
+ targetStackId.getStackName(), intermediateStack.version);
+ intermediateConfigUpgradePacks.add(intermediateConfigUpgradePack);
+ }
+ configUpgradePack = ConfigUpgradePack.merge(intermediateConfigUpgradePacks);
+ }
for (UpgradeGroupHolder group : groups) {
UpgradeGroupEntity groupEntity = new UpgradeGroupEntity();
@@ -707,11 +733,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
itemEntity.setTasks(wrapper.getTasksJson());
itemEntity.setHosts(wrapper.getHostsJson());
itemEntities.add(itemEntity);
+
+ // At this point, need to change the effective Stack Id so that subsequent tasks run on the newer value.
+ // TODO AMBARI-12698, check if this works during a Stop-the-World Downgrade.
+ if (UpdateStackGrouping.class.equals(group.groupClass)) {
+ ctx.setEffectiveStackId(ctx.getTargetStackId());
+ }
injectVariables(configHelper, cluster, itemEntity);
makeServerSideStage(ctx, req, itemEntity, (ServerSideActionTask) task, skippable,
- allowRetry);
+ allowRetry, configUpgradePack);
}
}
} else {
@@ -736,8 +768,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion());
entity.setToVersion(version);
entity.setUpgradeGroups(groupEntities);
- entity.setClusterId(Long.valueOf(cluster.getClusterId()));
+ entity.setClusterId(cluster.getClusterId());
entity.setDirection(direction);
+ entity.setUpgradePackage(pack.getName());
+ entity.setUpgradeType(pack.getType());
req.getRequestStatusResponse();
@@ -784,7 +818,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
* which services are effected.
* @throws AmbariException
*/
- void processConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
+ void applyStackAndProcessConfigurations(String stackName, Cluster cluster, String version, Direction direction, UpgradePack upgradePack)
throws AmbariException {
RepositoryVersionEntity targetRve = s_repoVersionDAO.findByStackNameAndVersion(stackName, version);
if (null == targetRve) {
@@ -816,6 +850,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
Map<String, Map<String, String>> newConfigurationsByType = null;
ConfigHelper configHelper = getManagementController().getConfigHelper();
+ // TODO AMBARI-12698, handle jumping across several stacks
if (direction == Direction.UPGRADE) {
// populate a map of default configurations for the old stack (this is
// used when determining if a property has been customized and should be
@@ -884,7 +919,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
continue;
}
- // NPE sanity, althought shouldn't even happen since we are iterating
+ // NPE sanity, although shouldn't even happen since we are iterating
// over the desired configs to start with
Config currentClusterConfig = cluster.getDesiredConfigByType(configurationType);
if (null == currentClusterConfig) {
@@ -971,8 +1006,10 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
throws AmbariException {
switch (wrapper.getType()) {
+ case START:
+ case STOP:
case RESTART:
- makeRestartStage(context, request, entity, wrapper, skippable, allowRetry);
+ makeCommandStage(context, request, entity, wrapper, skippable, allowRetry);
break;
case RU_TASKS:
makeActionStage(context, request, entity, wrapper, skippable, allowRetry);
@@ -1012,7 +1049,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
// service, it is necessary to set the
// service_package_folder and hooks_folder params.
AmbariMetaInfo ambariMetaInfo = s_metaProvider.get();
- StackId stackId = cluster.getDesiredStackVersion();
+ StackId stackId = context.getEffectiveStackId();
StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(),
stackId.getStackVersion());
@@ -1035,7 +1072,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster);
+ cluster, context.getEffectiveStackId());
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1064,7 +1101,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
request.addStages(Collections.singletonList(stage));
}
- private void makeRestartStage(UpgradeContext context, RequestStageContainer request,
+ /**
+ * Used to create a stage for restart, start, or stop.
+ * @param context Upgrade Context
+ * @param request Container for stage
+ * @param entity Upgrade Item
+ * @param wrapper Stage
+ * @param skippable Whether the item can be skipped
+ * @param allowRetry Whether the item is allowed to be retried
+ * @throws AmbariException
+ */
+ private void makeCommandStage(UpgradeContext context, RequestStageContainer request,
UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry)
throws AmbariException {
@@ -1078,23 +1125,43 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
new ArrayList<String>(tw.getHosts())));
}
- Map<String, String> restartCommandParams = getNewParameterMap();
- 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());
- restartCommandParams.put(COMMAND_DOWNGRADE_FROM_VERSION, context.getDowngradeFromVersion());
+ String function = null;
+ switch (wrapper.getType()) {
+ case START:
+ case STOP:
+ case RESTART:
+ function = wrapper.getType().name();
+ break;
+ default:
+ function = "UNKNOWN";
+ break;
+ }
+
+ Map<String, String> commandParams = getNewParameterMap();
+
+ // TODO AMBARI-12698, change COMMAND_PARAM_RESTART_TYPE to something that isn't "RESTART" specific.
+ if (context.getType() == UpgradeType.ROLLING) {
+ commandParams.put(COMMAND_PARAM_RESTART_TYPE, "rolling_upgrade");
+ }
+ if (context.getType() == UpgradeType.NON_ROLLING) {
+ commandParams.put(COMMAND_PARAM_RESTART_TYPE, "nonrolling_upgrade");
+ }
+
+ 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());
+ commandParams.put(COMMAND_DOWNGRADE_FROM_VERSION, context.getDowngradeFromVersion());
ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(),
- "RESTART", filters, restartCommandParams);
+ function, filters, commandParams);
actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false)));
actionContext.setIgnoreMaintenance(true);
actionContext.setRetryAllowed(allowRetry);
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster);
+ cluster, context.getEffectiveStackId());
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1112,7 +1179,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
entity.setStageId(Long.valueOf(stageId));
Map<String, String> requestParams = new HashMap<String, String>();
- requestParams.put("command", "RESTART");
+ requestParams.put("command", function);
s_commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams);
@@ -1147,7 +1214,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setAutoSkipFailures(context.isServiceCheckFailureAutoSkipped());
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster);
+ cluster, context.getEffectiveStackId());
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), entity.getText(),
@@ -1170,8 +1237,22 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
request.addStages(Collections.singletonList(stage));
}
+ /**
+ * Creates a stage consisting of server side actions
+ * @param context upgrade context
+ * @param request upgrade request
+ * @param entity a single of upgrade
+ * @param task server-side task (if any)
+ * @param skippable if user can skip stage on failure
+ * @param allowRetry if user can retry running stage on failure
+ * @param configUpgradePack a runtime-generated config upgrade pack that
+ * contains all config change definitions from all stacks involved into
+ * upgrade
+ * @throws AmbariException
+ */
private void makeServerSideStage(UpgradeContext context, RequestStageContainer request,
- UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable, boolean allowRetry)
+ UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable, boolean allowRetry,
+ ConfigUpgradePack configUpgradePack)
throws AmbariException {
Cluster cluster = context.getCluster();
@@ -1204,7 +1285,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
}
case CONFIGURE: {
ConfigureTask ct = (ConfigureTask) task;
- Map<String, String> configurationChanges = ct.getConfigurationChanges(cluster);
+ Map<String, String> configurationChanges =
+ ct.getConfigurationChanges(cluster, configUpgradePack);
// add all configuration changes to the command params
commandParams.putAll(configurationChanges);
@@ -1241,7 +1323,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
- cluster);
+ cluster, context.getEffectiveStackId());
Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getClusterHostInfo(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
index e821827..f5642a0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metadata/ActionMetadata.java
@@ -58,8 +58,10 @@ public class ActionMetadata {
private void fillHostComponentCommands() {
//Standart commands for any host component
- // TODO: Add START/STOP/INSTALL commands
defaultHostComponentCommands.add("RESTART");
+ defaultHostComponentCommands.add("START");
+ defaultHostComponentCommands.add("STOP");
+ defaultHostComponentCommands.add("INSTALL");
defaultHostComponentCommands.add("CONFIGURE");
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
index d3326b1..8d4c5ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterVersionDAO.java
@@ -23,8 +23,11 @@ import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.TypedQuery;
+import com.google.inject.persist.Transactional;
import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.StackId;
@@ -153,4 +156,24 @@ public class ClusterVersionDAO extends CrudDAO<ClusterVersionEntity, Long>{
return daoUtils.selectList(query);
}
+
+ /**
+ * Construct a Cluster Version and return it. This is primarily used to be able to construct the object and mock
+ * the function call.
+ * @param cluster Cluster
+ * @param repositoryVersion Repository Version
+ * @param state Initial State
+ * @param startTime Start Time
+ * @param endTime End Time
+ * @param userName Username, such as "admin"
+ * @return Return new ClusterVersion object.
+ */
+ @Transactional
+ public ClusterVersionEntity create(ClusterEntity cluster, RepositoryVersionEntity repositoryVersion,
+ RepositoryVersionState state, long startTime, long endTime, String userName) {
+ ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(cluster,
+ repositoryVersion, state, startTime, endTime, userName);
+ this.create(clusterVersionEntity);
+ return clusterVersionEntity;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
index 4382f59..ed0a931 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/CrudDAO.java
@@ -73,6 +73,21 @@ public class CrudDAO<E, K> {
}
/**
+ * Retrieves the maximum ID from the entities.
+ *
+ * @param idColName name of the column that corresponds to the ID.
+ * @return maximum ID, or 0 if none exist.
+ */
+ @RequiresSession
+ public Long findMaxId(String idColName) {
+ final TypedQuery<Long> query = entityManagerProvider.get().createQuery("SELECT MAX(entity." + idColName + ") FROM "
+ + entityClass.getSimpleName() + " entity", Long.class);
+ // May be null if no results.
+ Long result = daoUtils.selectOne(query);
+ return result == null ? 0 : result;
+ }
+
+ /**
* Creates entity.
*
* @param entity entity to create
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/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 a2ff211..ad617af 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
@@ -43,21 +43,17 @@ import com.google.inject.persist.Transactional;
* {@link org.apache.ambari.server.state.RepositoryVersionState#UPGRADING}.
*/
@Singleton
-public class HostVersionDAO {
+public class HostVersionDAO extends CrudDAO<HostVersionEntity, Long> {
@Inject
Provider<EntityManager> entityManagerProvider;
@Inject
DaoUtils daoUtils;
/**
- * Get the object with the given id.
- *
- * @param id Primary key id
- * @return Return the object with the given primary key
+ * Constructor.
*/
- @RequiresSession
- public HostVersionEntity findByPK(long id) {
- return entityManagerProvider.get().find(HostVersionEntity.class, id);
+ public HostVersionDAO() {
+ super(HostVersionEntity.class);
}
/**
@@ -189,31 +185,6 @@ public class HostVersionDAO {
return daoUtils.selectSingle(query);
}
- @RequiresSession
- public List<HostVersionEntity> findAll() {
- return daoUtils.selectAll(entityManagerProvider.get(), HostVersionEntity.class);
- }
-
- @Transactional
- public void refresh(HostVersionEntity hostVersionEntity) {
- entityManagerProvider.get().refresh(hostVersionEntity);
- }
-
- @Transactional
- public void create(HostVersionEntity hostVersionEntity) {
- entityManagerProvider.get().persist(hostVersionEntity);
- }
-
- @Transactional
- public HostVersionEntity merge(HostVersionEntity hostVersionEntity) {
- return entityManagerProvider.get().merge(hostVersionEntity);
- }
-
- @Transactional
- public void remove(HostVersionEntity hostVersionEntity) {
- entityManagerProvider.get().remove(merge(hostVersionEntity));
- }
-
@Transactional
public void removeByHostName(String hostName) {
Collection<HostVersionEntity> hostVersions = this.findByHost(hostName);
@@ -221,9 +192,4 @@ public class HostVersionDAO {
this.remove(hostVersion);
}
}
-
- @Transactional
- public void removeByPK(long id) {
- remove(findByPK(id));
- }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
index 4ac1314..9f5f6f1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
@@ -129,15 +129,13 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
* @param stackEntity Stack entity.
* @param version Stack version, e.g., 2.2 or 2.2.0.1-885
* @param displayName Unique display name
- * @param upgradePack Optional upgrade pack, e.g, upgrade-2.2
* @param operatingSystems JSON structure of repository URLs for each OS
* @return Returns the object created if successful, and throws an exception otherwise.
* @throws AmbariException
*/
@Transactional
public RepositoryVersionEntity create(StackEntity stackEntity,
- String version, String displayName, String upgradePack,
- String operatingSystems) throws AmbariException {
+ String version, String displayName, String operatingSystems) throws AmbariException {
if (stackEntity == null || version == null || version.isEmpty()
|| displayName == null || displayName.isEmpty()) {
@@ -164,7 +162,7 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
}
RepositoryVersionEntity newEntity = new RepositoryVersionEntity(
- stackEntity, version, displayName, upgradePack, operatingSystems);
+ stackEntity, version, displayName, operatingSystems);
this.create(newEntity);
return newEntity;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
index bc0652c..06f6ac1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UpgradeDAO.java
@@ -48,6 +48,18 @@ public class UpgradeDAO {
private DaoUtils daoUtils;
/**
+ * Get all items.
+ * @return List of all of the UpgradeEntity items.
+ */
+ @RequiresSession
+ public List<UpgradeEntity> findAll() {
+ TypedQuery<UpgradeEntity> query = entityManagerProvider.get().createNamedQuery(
+ "UpgradeEntity.findAll", UpgradeEntity.class);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* @param clusterId the cluster id
* @return the list of upgrades initiated for the cluster
*/
@@ -157,8 +169,7 @@ public class UpgradeDAO {
}
/**
- * @param requestId the request id
- * @param stageId the stage id
+ * @param clusterId the cluster id
* @return the upgrade entity, or {@code null} if not found
*/
@RequiresSession
@@ -174,4 +185,8 @@ public class UpgradeDAO {
return daoUtils.selectSingle(query);
}
+ @Transactional
+ public UpgradeEntity merge(UpgradeEntity upgradeEntity) {
+ return entityManagerProvider.get().merge(upgradeEntity);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
index dafd4b2..4296077 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
@@ -90,9 +90,6 @@ public class RepositoryVersionEntity {
@Column(name = "display_name")
private String displayName;
- @Column(name = "upgrade_package")
- private String upgradePackage;
-
@Lob
@Column(name = "repositories")
private String operatingSystems;
@@ -110,11 +107,10 @@ public class RepositoryVersionEntity {
}
public RepositoryVersionEntity(StackEntity stack, String version,
- String displayName, String upgradePackage, String operatingSystems) {
+ String displayName, String operatingSystems) {
this.stack = stack;
this.version = version;
this.displayName = displayName;
- this.upgradePackage = upgradePackage;
this.operatingSystems = operatingSystems;
}
@@ -161,14 +157,6 @@ public class RepositoryVersionEntity {
this.displayName = displayName;
}
- public String getUpgradePackage() {
- return upgradePackage;
- }
-
- public void setUpgradePackage(String upgradePackage) {
- this.upgradePackage = upgradePackage;
- }
-
public String getOperatingSystemsJson() {
return operatingSystems;
}
@@ -233,9 +221,6 @@ public class RepositoryVersionEntity {
if (displayName != null ? !displayName.equals(that.displayName) : that.displayName != null) {
return false;
}
- if (upgradePackage != null ? !upgradePackage.equals(that.upgradePackage) : that.upgradePackage != null) {
- return false;
- }
if (operatingSystems != null ? !operatingSystems.equals(that.operatingSystems) : that.operatingSystems != null) {
return false;
}
@@ -249,7 +234,6 @@ public class RepositoryVersionEntity {
result = 31 * result + (stack != null ? stack.hashCode() : 0);
result = 31 * result + (version != null ? version.hashCode() : 0);
result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
- result = 31 * result + (upgradePackage != null ? upgradePackage.hashCode() : 0);
result = 31 * result + (operatingSystems != null ? operatingSystems.hashCode() : 0);
return result;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
index 802ea03..ad9073a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeEntity.java
@@ -34,6 +34,7 @@ import javax.persistence.Table;
import javax.persistence.TableGenerator;
import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
/**
* Models the data representation of an upgrade
@@ -44,6 +45,8 @@ import org.apache.ambari.server.state.stack.upgrade.Direction;
table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value",
pkColumnValue = "upgrade_id_seq", initialValue = 0)
@NamedQueries({
+ @NamedQuery(name = "UpgradeEntity.findAll",
+ query = "SELECT u FROM UpgradeEntity u"),
@NamedQuery(name = "UpgradeEntity.findAllForCluster",
query = "SELECT u FROM UpgradeEntity u WHERE u.clusterId = :clusterId"),
@NamedQuery(name = "UpgradeEntity.findUpgrade",
@@ -74,6 +77,13 @@ public class UpgradeEntity {
@Enumerated(value = EnumType.STRING)
private Direction direction = Direction.UPGRADE;
+ @Column(name="upgrade_package", nullable = false)
+ private String upgradePackage;
+
+ @Column(name="upgrade_type", nullable = false)
+ @Enumerated(value = EnumType.STRING)
+ private UpgradeType upgradeType;
+
@OneToMany(mappedBy = "upgradeEntity", cascade = { CascadeType.ALL })
private List<UpgradeGroupEntity> upgradeGroupEntities;
@@ -179,5 +189,84 @@ public class UpgradeEntity {
this.direction = direction;
}
+ /**
+ * @return the upgrade type, such as rolling or non_rolling
+ */
+ public UpgradeType getUpgradeType() {
+ return upgradeType;
+ }
+
+ /**
+ * @param upgradeType the upgrade type to set
+ */
+ public void setUpgradeType(UpgradeType upgradeType) {
+ this.upgradeType = upgradeType;
+ }
+
+ /**
+ * @return the upgrade package name, without the extension.
+ */
+ public String getUpgradePackage() {
+ return upgradePackage;
+ }
+
+ /**
+ * @param upgradePackage the upgrade pack to set
+ */
+ public void setUpgradePackage(String upgradePackage) {
+ this.upgradePackage = upgradePackage;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ UpgradeEntity that = (UpgradeEntity) o;
+
+ if (upgradeId != null ? !upgradeId.equals(that.upgradeId) : that.upgradeId != null) {
+ return false;
+ }
+ if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) {
+ return false;
+ }
+ if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) {
+ return false;
+ }
+ if (fromVersion != null ? !fromVersion.equals(that.fromVersion) : that.fromVersion != null) {
+ return false;
+ }
+ if (toVersion != null ? !toVersion.equals(that.toVersion) : that.toVersion != null) {
+ return false;
+ }
+ if (direction != null ? !direction.equals(that.direction) : that.direction != null) {
+ return false;
+ }
+ if (upgradeType != null ? !upgradeType.equals(that.upgradeType) : that.upgradeType != null) {
+ return false;
+ }
+ if (upgradePackage != null ? !upgradePackage.equals(that.upgradePackage) : that.upgradePackage != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = upgradeId != null ? upgradeId.hashCode() : 0;
+ result = 31 * result + (clusterId != null ? clusterId.hashCode() : 0);
+ result = 31 * result + (requestId != null ? requestId.hashCode() : 0);
+ result = 31 * result + (fromVersion != null ? fromVersion.hashCode() : 0);
+ result = 31 * result + (toVersion != null ? toVersion.hashCode() : 0);
+ result = 31 * result + (direction != null ? direction.hashCode() : 0);
+ result = 31 * result + (upgradeType != null ? upgradeType.hashCode() : 0);
+ result = 31 * result + (upgradePackage != null ? upgradePackage.hashCode() : 0);
+ return result;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
index c717582..ef21a2a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java
@@ -46,7 +46,10 @@ import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.stack.upgrade.ConfigureTask;
-import org.apache.ambari.server.state.stack.upgrade.ConfigureTask.ConfigurationKeyValue;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.ConfigurationKeyValue;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Transfer;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Replace;
+import org.apache.ambari.server.state.stack.upgrade.ConfigUpgradeChangeDefinition.Masked;
import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
@@ -176,27 +179,27 @@ public class ConfigureAction extends AbstractServerAction {
String configType = commandParameters.get(ConfigureTask.PARAMETER_CONFIG_TYPE);
// extract transfers
- List<ConfigureTask.ConfigurationKeyValue> keyValuePairs = Collections.emptyList();
+ List<ConfigurationKeyValue> keyValuePairs = Collections.emptyList();
String keyValuePairJson = commandParameters.get(ConfigureTask.PARAMETER_KEY_VALUE_PAIRS);
if (null != keyValuePairJson) {
keyValuePairs = m_gson.fromJson(
- keyValuePairJson, new TypeToken<List<ConfigureTask.ConfigurationKeyValue>>(){}.getType());
+ keyValuePairJson, new TypeToken<List<ConfigurationKeyValue>>(){}.getType());
}
// extract transfers
- List<ConfigureTask.Transfer> transfers = Collections.emptyList();
+ List<Transfer> transfers = Collections.emptyList();
String transferJson = commandParameters.get(ConfigureTask.PARAMETER_TRANSFERS);
if (null != transferJson) {
transfers = m_gson.fromJson(
- transferJson, new TypeToken<List<ConfigureTask.Transfer>>(){}.getType());
+ transferJson, new TypeToken<List<Transfer>>(){}.getType());
}
// extract replacements
- List<ConfigureTask.Replace> replacements = Collections.emptyList();
+ List<Replace> replacements = Collections.emptyList();
String replaceJson = commandParameters.get(ConfigureTask.PARAMETER_REPLACEMENTS);
if (null != replaceJson) {
replacements = m_gson.fromJson(
- replaceJson, new TypeToken<List<ConfigureTask.Replace>>(){}.getType());
+ replaceJson, new TypeToken<List<Replace>>(){}.getType());
}
// if there is nothing to do, then skip the task
@@ -240,7 +243,7 @@ public class ConfigureAction extends AbstractServerAction {
// !!! do transfers first before setting defined values
StringBuilder outputBuffer = new StringBuilder(250);
- for (ConfigureTask.Transfer transfer : transfers) {
+ for (Transfer transfer : transfers) {
switch (transfer.operation) {
case COPY:
String valueToCopy = null;
@@ -400,7 +403,7 @@ public class ConfigureAction extends AbstractServerAction {
}
// !!! string replacements happen only on the new values.
- for (ConfigureTask.Replace replacement : replacements) {
+ for (Replace replacement : replacements) {
if (newValues.containsKey(replacement.key)) {
String toReplace = newValues.get(replacement.key);
@@ -534,7 +537,7 @@ public class ConfigureAction extends AbstractServerAction {
return result;
}
- private static String mask(ConfigureTask.Masked mask, String value) {
+ private static String mask(Masked mask, String value) {
if (mask.mask) {
return StringUtils.repeat("*", value.length());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
new file mode 100644
index 0000000..b676c9b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpdateDesiredStackAction.java
@@ -0,0 +1,139 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.serveraction.upgrades;
+
+import com.google.inject.Inject;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.serveraction.AbstractServerAction;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Action that represents updating the Desired Stack Id during the middle of a stack upgrade (typically NonRolling).
+ * In a {@link org.apache.ambari.server.state.stack.upgrade.UpgradeType#NON_ROLLING}, the effective Stack Id is
+ * actually changed half-way through calculating the Actions, and this serves to update the database to make it
+ * evident to the user at which point it changed.
+ */
+public class UpdateDesiredStackAction extends AbstractServerAction {
+
+ /**
+ * The original "current" stack of the cluster before the upgrade started.
+ * This is the same regardless of whether the current direction is
+ * {@link org.apache.ambari.server.state.stack.upgrade.Direction#UPGRADE} or {@link org.apache.ambari.server.state.stack.upgrade.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 org.apache.ambari.server.state.stack.upgrade.Direction#UPGRADE} or
+ * {@link org.apache.ambari.server.state.stack.upgrade.Direction#DOWNGRADE}.
+ */
+ public static final String TARGET_STACK_KEY = "target_stack";
+
+ /**
+ * The Cluster that this ServerAction implementation is executing on.
+ */
+ @Inject
+ private Clusters clusters;
+
+ @Inject
+ private AmbariMetaInfo ambariMetaInfo;
+
+ @Override
+ public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+ throws AmbariException, InterruptedException {
+ Map<String, String> commandParams = getExecutionCommand().getCommandParams();
+
+ StackId originalStackId = new StackId(commandParams.get(ORIGINAL_STACK_KEY));
+ StackId targetStackId = new StackId(commandParams.get(TARGET_STACK_KEY));
+ String clusterName = getExecutionCommand().getClusterName();
+
+ return updateDesiredStack(clusterName, originalStackId, targetStackId);
+ }
+
+ /**
+ * Set the cluster's Desired Stack Id during an upgrade.
+ *
+ * @param clusterName the name of the cluster the action is meant for
+ * @paran originalStackId the stack Id of the cluster before the upgrade.
+ * @paran targetStackId the stack Id that was desired for this upgrade.
+ * @return the command report to return
+ */
+ private CommandReport updateDesiredStack(String clusterName, StackId originalStackId, StackId targetStackId)
+ throws AmbariException, InterruptedException {
+ StringBuilder out = new StringBuilder();
+ StringBuilder err = new StringBuilder();
+
+ try {
+ Cluster cluster = clusters.getCluster(clusterName);
+ StackId currentClusterStackId = cluster.getCurrentStackVersion();
+
+ out.append(String.format("Checking if can update the Desired Stack Id to %s. The cluster's current Stack Id is %s\n", targetStackId.getStackId(), currentClusterStackId.getStackId()));
+
+ // Ensure that the target stack id exist
+ StackInfo desiredClusterStackInfo = ambariMetaInfo.getStack(targetStackId.getStackName(), targetStackId.getStackVersion());
+ if (null == desiredClusterStackInfo) {
+ String message = String.format("Parameter %s has an invalid value: %s. That Stack Id does not exist.\n",
+ TARGET_STACK_KEY, targetStackId.getStackId());
+ err.append(message);
+ out.append(message);
+ return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+ }
+
+ // Ensure that the current Stack Id coincides with the parameter that the user passed in.
+ if (!currentClusterStackId.equals(originalStackId)) {
+ String message = String.format("Parameter %s has invalid value: %s. " +
+ "The cluster is currently on stack %s, " + currentClusterStackId.getStackId() +
+ ", yet the parameter to this function indicates a different value.\n", ORIGINAL_STACK_KEY, targetStackId.getStackId(), currentClusterStackId.getStackId());
+ err.append(message);
+ out.append(message);
+ return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+ }
+
+ // Check for a no-op
+ if (currentClusterStackId.equals(targetStackId)) {
+ String message = String.format("Success! The cluster's Desired Stack Id was already set to %s\n", targetStackId.getStackId());
+ out.append(message);
+ return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());
+ }
+
+ cluster.setDesiredStackVersion(targetStackId, true);
+ String message = String.format("Success! Set cluster's %s Desired Stack Id to %s.\n", clusterName, targetStackId.getStackId());
+ out.append(message);
+
+ return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", out.toString(), err.toString());
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ err.append(sw.toString());
+
+ return createCommandReport(-1, HostRoleStatus.FAILED, "{}", out.toString(), err.toString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
index aa8e17b..9e2f997 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.stack;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
import org.apache.ambari.server.state.stack.ConfigurationXml;
import org.apache.ambari.server.state.stack.RepositoryXml;
import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
@@ -63,12 +64,13 @@ class ModuleFileUnmarshaller {
try {
// three classes define the top-level element "metainfo", so we need 3 contexts.
JAXBContext ctx = JAXBContext.newInstance(StackMetainfoXml.class, RepositoryXml.class,
- ConfigurationXml.class, UpgradePack.class);
+ ConfigurationXml.class, UpgradePack.class, ConfigUpgradePack.class);
jaxbContexts.put(StackMetainfoXml.class, ctx);
jaxbContexts.put(RepositoryXml.class, ctx);
jaxbContexts.put(ConfigurationXml.class, ctx);
jaxbContexts.put(UpgradePack.class, ctx);
+ jaxbContexts.put(ConfigUpgradePack.class, ctx);
jaxbContexts.put(ServiceMetainfoXml.class, JAXBContext.newInstance(ServiceMetainfoXml.class));
} catch (JAXBException e) {
throw new RuntimeException (e);
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
index 8f81b5a..c739211 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDefinitionDirectory.java
@@ -37,6 +37,8 @@ public abstract class StackDefinitionDirectory {
}
};
+ protected static final String CONFIG_UPGRADE_XML_FILENAME_PREFIX = "config-upgrade.xml";
+
/**
* underlying directory
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
index b849e88..90b8f10 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
@@ -23,6 +23,7 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.state.stack.RepositoryXml;
import org.apache.ambari.server.state.stack.StackMetainfoXml;
import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
import org.apache.ambari.server.state.stack.UpgradePack;
import org.apache.commons.io.FilenameUtils;
import org.codehaus.jackson.map.ObjectMapper;
@@ -95,10 +96,14 @@ public class StackDirectory extends StackDefinitionDirectory {
/**
* map of upgrade pack name to upgrade pack
*/
- //todo: should be a collection but upgrade pack doesn't have a name attribute
private Map<String, UpgradePack> upgradePacks;
/**
+ * Config delta from prev stack
+ */
+ private ConfigUpgradePack configUpgradePack;
+
+ /**
* metainfo file representation
*/
private StackMetainfoXml metaInfoXml;
@@ -255,6 +260,13 @@ public class StackDirectory extends StackDefinitionDirectory {
}
/**
+ * @return Config delta from prev stack or null if no config upgrade patches available
+ */
+ public ConfigUpgradePack getConfigUpgradePack() {
+ return configUpgradePack;
+ }
+
+ /**
* Obtain the object representation of the stack role_command_order.json file
*
* @return object representation of the stack role_command_order.json file
@@ -409,18 +421,35 @@ public class StackDirectory extends StackDefinitionDirectory {
* @throws AmbariException if unable to parse stack upgrade file
*/
private void parseUpgradePacks(Collection<String> subDirs) throws AmbariException {
- Map<String, UpgradePack> upgradeMap = new HashMap<String, UpgradePack>();
+ Map<String, UpgradePack> upgradeMap = new HashMap<>();
+ ConfigUpgradePack configUpgradePack = null;
if (subDirs.contains(UPGRADE_PACK_FOLDER_NAME)) {
File f = new File(getAbsolutePath() + File.separator + UPGRADE_PACK_FOLDER_NAME);
if (f.isDirectory()) {
upgradesDir = f.getAbsolutePath();
for (File upgradeFile : f.listFiles(XML_FILENAME_FILTER)) {
- try {
- upgradeMap.put(FilenameUtils.removeExtension(upgradeFile.getName()),
- unmarshaller.unmarshal(UpgradePack.class, upgradeFile));
- } catch (JAXBException e) {
- throw new AmbariException("Unable to parse stack upgrade file at location: " +
- upgradeFile.getAbsolutePath(), e);
+ if (upgradeFile.getName().toLowerCase().startsWith(CONFIG_UPGRADE_XML_FILENAME_PREFIX)) {
+ try { // Parse config upgrade pack
+ if (configUpgradePack == null) {
+ configUpgradePack = unmarshaller.unmarshal(ConfigUpgradePack.class, upgradeFile);
+ } else { // If user messed things up with lower/upper case filenames
+ throw new AmbariException(String.format("There are multiple files with name like %s" +
+ upgradeFile.getAbsolutePath()));
+ }
+ } catch (JAXBException e) {
+ throw new AmbariException("Unable to parse stack upgrade file at location: " +
+ upgradeFile.getAbsolutePath(), e);
+ }
+ } else {
+ try {
+ String upgradePackName = FilenameUtils.removeExtension(upgradeFile.getName());
+ UpgradePack pack = unmarshaller.unmarshal(UpgradePack.class, upgradeFile);
+ pack.setName(upgradePackName);
+ upgradeMap.put(upgradePackName, pack);
+ } catch (JAXBException e) {
+ throw new AmbariException("Unable to parse stack upgrade file at location: " +
+ upgradeFile.getAbsolutePath(), e);
+ }
}
}
}
@@ -433,6 +462,13 @@ public class StackDirectory extends StackDefinitionDirectory {
if (! upgradeMap.isEmpty()) {
upgradePacks = upgradeMap;
}
+
+ if (configUpgradePack != null) {
+ this.configUpgradePack = configUpgradePack;
+ } else {
+ LOG.info("Stack '{}' doesn't contain config upgrade pack file", getPath());
+ }
+
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 4fe7ed7..def33f0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -422,6 +421,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
stackInfo.setWidgetsDescriptorFileLocation(stackDirectory.getWidgetsDescriptorFilePath());
stackInfo.setUpgradesFolder(stackDirectory.getUpgradesDir());
stackInfo.setUpgradePacks(stackDirectory.getUpgradePacks());
+ stackInfo.setConfigUpgradePack(stackDirectory.getConfigUpgradePack());
stackInfo.setRoleCommandOrder(stackDirectory.getRoleCommandOrder());
populateConfigurationModules();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index 8e9d092..e3ac3e0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -31,6 +31,7 @@ import java.util.Set;
import org.apache.ambari.server.controller.StackVersionResponse;
import org.apache.ambari.server.stack.Validable;
import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
+import org.apache.ambari.server.state.stack.ConfigUpgradePack;
import org.apache.ambari.server.state.stack.UpgradePack;
public class StackInfo implements Comparable<StackInfo>, Validable{
@@ -67,6 +68,7 @@ public class StackInfo implements Comparable<StackInfo>, Validable{
private List<PropertyInfo> properties;
private Map<String, Map<String, Map<String, String>>> configTypes;
private Map<String, UpgradePack> upgradePacks;
+ private ConfigUpgradePack configUpgradePack;
private StackRoleCommandOrder roleCommandOrder;
private boolean valid = true;
@@ -373,23 +375,40 @@ public class StackInfo implements Comparable<StackInfo>, Validable{
}
/**
+ * Obtain all stack upgrade packs.
+ *
+ * @return map of upgrade pack name to upgrade pack or {@code null} if no packs
+ */
+ public Map<String, UpgradePack> getUpgradePacks() {
+ return upgradePacks;
+ }
+
+ /**
* Set upgrade packs.
*
- * @param upgradePacks map of upgrade packs
+ * @param upgradePacks map of upgrade packs
*/
public void setUpgradePacks(Map<String, UpgradePack> upgradePacks) {
this.upgradePacks = upgradePacks;
}
/**
- * Obtain all stack upgrade packs.
- *
- * @return map of upgrade pack name to upgrade pack or {@code null} of no packs
+ * Get config upgrade pack for stack
+ * @return config upgrade pack for stack or null if it is
+ * not defined
*/
- public Map<String, UpgradePack> getUpgradePacks() {
- return upgradePacks;
+ public ConfigUpgradePack getConfigUpgradePack() {
+ return configUpgradePack;
}
+ /**
+ * Set config upgrade pack for stack
+ * @param configUpgradePack config upgrade pack for stack or null if it is
+ * not defined
+ */
+ public void setConfigUpgradePack(ConfigUpgradePack configUpgradePack) {
+ this.configUpgradePack = configUpgradePack;
+ }
@Override
public int compareTo(StackInfo o) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/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 b10db9e..7f307cf 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
@@ -25,6 +25,7 @@ import java.util.Map;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.stack.MasterHostResolver;
import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
/**
* Used to hold various helper objects required to process an upgrade pack.
@@ -41,6 +42,14 @@ public class UpgradeContext {
private StackId m_originalStackId;
/**
+ * The stack currently used to start/restart services during an upgrade.This is the same
+ * During a {@link UpgradeType#ROLLING} upgrade, this is always the {@link this.m_targetStackId},
+ * During a {@link UpgradeType#NON_ROLLING} upgrade, this is initially the {@link this.m_sourceStackId} while
+ * stopping services, and then changes to the {@link this.m_targetStackId} when starting services.
+ */
+ private StackId m_effectiveStackId;
+
+ /**
* 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}.
@@ -54,6 +63,7 @@ public class UpgradeContext {
private Map<String, String> m_serviceNames = new HashMap<String, String>();
private Map<String, String> m_componentNames = new HashMap<String, String>();
private String m_downgradeFromVersion = null;
+ private UpgradeType m_type = null;
/**
* {@code true} if slave/client component failures should be automatically
@@ -88,15 +98,31 @@ public class UpgradeContext {
* the target version to upgrade to
* @param direction
* the direction for the upgrade
+ * @param type
+ * the type of upgrade, either rolling or non_rolling
*/
public UpgradeContext(MasterHostResolver resolver, StackId sourceStackId,
StackId targetStackId, String version,
- Direction direction) {
+ Direction direction, UpgradeType type) {
m_version = version;
m_originalStackId = sourceStackId;
+
+ switch (type) {
+ case ROLLING:
+ m_effectiveStackId = targetStackId;
+ break;
+ case NON_ROLLING:
+ m_effectiveStackId = sourceStackId;
+ break;
+ default:
+ m_effectiveStackId = targetStackId;
+ break;
+ }
+
m_targetStackId = targetStackId;
m_direction = direction;
m_resolver = resolver;
+ m_type = type;
}
/**
@@ -121,6 +147,13 @@ public class UpgradeContext {
}
/**
+ * @return the type of upgrade.
+ */
+ public UpgradeType getType() {
+ return m_type;
+ }
+
+ /**
* @return the resolver
*/
public MasterHostResolver getResolver() {
@@ -164,6 +197,21 @@ public class UpgradeContext {
}
/**
+ * @return the effectiveStackId that is currently in use.
+ */
+ public StackId getEffectiveStackId() {
+ return m_effectiveStackId;
+ }
+
+ /**
+ * @param effectiveStackId the effectiveStackId to set
+ */
+ public void setEffectiveStackId(StackId effectiveStackId) {
+ m_effectiveStackId = effectiveStackId;
+ }
+
+
+ /**
* @return the targetStackId
*/
public StackId getTargetStackId() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/c58162fe/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
index 75c04da..f0b383c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeHelper.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.state;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
@@ -42,6 +43,8 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.stack.HostsType;
import org.apache.ambari.server.stack.MasterHostResolver;
import org.apache.ambari.server.state.stack.UpgradePack;
@@ -49,11 +52,18 @@ import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent;
import org.apache.ambari.server.state.stack.upgrade.Direction;
import org.apache.ambari.server.state.stack.upgrade.Grouping;
import org.apache.ambari.server.state.stack.upgrade.ManualTask;
+import org.apache.ambari.server.state.stack.upgrade.RestartGrouping;
+import org.apache.ambari.server.state.stack.upgrade.RestartTask;
import org.apache.ambari.server.state.stack.upgrade.StageWrapper;
import org.apache.ambari.server.state.stack.upgrade.StageWrapperBuilder;
+import org.apache.ambari.server.state.stack.upgrade.StartGrouping;
+import org.apache.ambari.server.state.stack.upgrade.StartTask;
+import org.apache.ambari.server.state.stack.upgrade.StopGrouping;
+import org.apache.ambari.server.state.stack.upgrade.StopTask;
import org.apache.ambari.server.state.stack.upgrade.Task;
import org.apache.ambari.server.state.stack.upgrade.Task.Type;
import org.apache.ambari.server.state.stack.upgrade.TaskWrapper;
+import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -171,6 +181,68 @@ public class UpgradeHelper {
@Inject
private Provider<AmbariMetaInfo> m_ambariMetaInfo;
+ @Inject
+ private Provider<Clusters> clusters;
+
+ @Inject
+ private Provider<RepositoryVersionDAO> s_repoVersionDAO;
+
+
+ /**
+ * Get right Upgrade Pack, depends on stack, direction and upgrade type information
+ * @param clusterName The name of the cluster
+ * @param upgradeFromVersion Current stack version
+ * @param upgradeToVersion Target stack version
+ * @param direction {@code Direction} of the upgrade
+ * @param upgradeType The {@code UpgradeType}
+ * @return {@code UpgradeType} object
+ * @throws AmbariException
+ */
+ public UpgradePack suggestUpgradePack(String clusterName, String upgradeFromVersion, String upgradeToVersion,
+ Direction direction, UpgradeType upgradeType) throws AmbariException {
+
+ // !!! find upgrade packs based on current stack. This is where to upgrade from
+ Cluster cluster = clusters.get().getCluster(clusterName);
+ StackId stack = cluster.getCurrentStackVersion();
+
+ String repoVersion = upgradeToVersion;
+
+ // ToDo: AMBARI-12706. Here we need to check, how this would work with SWU Downgrade
+ if (direction.isDowngrade() && null != upgradeFromVersion) {
+ repoVersion = upgradeFromVersion;
+ }
+
+ RepositoryVersionEntity versionEntity = s_repoVersionDAO.get().findByStackNameAndVersion(stack.getStackName(), repoVersion);
+
+ if (versionEntity == null) {
+ throw new AmbariException(String.format("Repository version %s was not found", repoVersion));
+ }
+
+ Map<String, UpgradePack> packs = m_ambariMetaInfo.get().getUpgradePacks(stack.getStackName(), stack.getStackVersion());
+ UpgradePack pack = null;
+
+ String repoStackId = versionEntity.getStackId().getStackId();
+ for (UpgradePack upgradePack : packs.values()) {
+ if (upgradePack.getTargetStack() != null && upgradePack.getTargetStack().equals(repoStackId) &&
+ upgradeType == upgradePack.getType()) {
+ if (pack == null) {
+ pack = upgradePack;
+ } else {
+ throw new AmbariException(
+ String.format("Found multiple upgrade packs for type %s and target version %s",
+ upgradeType.toString(), repoVersion));
+ }
+ }
+ }
+
+ if (pack == null) {
+ throw new AmbariException(String.format("No upgrade pack found for type %s and target version %s",
+ upgradeType.toString(),repoVersion));
+ }
+
+ return pack;
+ }
+
/**
* Generates a list of UpgradeGroupHolder items that are used to execute either
@@ -189,14 +261,16 @@ public class UpgradeHelper {
Cluster cluster = context.getCluster();
MasterHostResolver mhr = context.getResolver();
+ // Note, only a Rolling Upgrade uses processing tasks.
Map<String, Map<String, ProcessingComponent>> allTasks = upgradePack.getTasks();
- List<UpgradeGroupHolder> groups = new ArrayList<UpgradeGroupHolder>();
+ List<UpgradeGroupHolder> groups = new ArrayList<>();
for (Grouping group : upgradePack.getGroups(context.getDirection())) {
UpgradeGroupHolder groupHolder = new UpgradeGroupHolder();
groupHolder.name = group.name;
groupHolder.title = group.title;
+ groupHolder.groupClass = group.getClass();
groupHolder.skippable = group.skippable;
groupHolder.allowRetry = group.allowRetry;
@@ -205,29 +279,52 @@ public class UpgradeHelper {
groupHolder.skippable = true;
}
+ // NonRolling defaults to not performing service checks on a group.
+ // Of course, a Service Check Group does indeed run them.
+ if (upgradePack.getType() == UpgradeType.NON_ROLLING) {
+ group.performServiceCheck = false;
+ }
+
StageWrapperBuilder builder = group.getBuilder();
List<UpgradePack.OrderService> services = group.services;
- if (context.getDirection().isDowngrade() && !services.isEmpty()) {
- List<UpgradePack.OrderService> reverse = new ArrayList<UpgradePack.OrderService>(services);
- Collections.reverse(reverse);
- services = reverse;
+ // Rolling Downgrade must reverse the order of services.
+ if (upgradePack.getType() == UpgradeType.ROLLING) {
+ if (context.getDirection().isDowngrade() && !services.isEmpty()) {
+ List<UpgradePack.OrderService> reverse = new ArrayList<>(services);
+ Collections.reverse(reverse);
+ services = reverse;
+ }
}
// !!! cluster and service checks are empty here
for (UpgradePack.OrderService service : services) {
- if (!allTasks.containsKey(service.serviceName)) {
+ if (upgradePack.getType() == UpgradeType.ROLLING && !allTasks.containsKey(service.serviceName)) {
continue;
}
+
+ // Attempt to get the function of the group, during a NonRolling Upgrade
+ Task.Type functionName = null;
+
+ if (RestartGrouping.class.isInstance(group)) {
+ functionName = ((RestartGrouping) group).getFunction();
+ }
+ if (StartGrouping.class.isInstance(group)) {
+ functionName = ((StartGrouping) group).getFunction();
+ }
+ if (StopGrouping.class.isInstance(group)) {
+ functionName = ((StopGrouping) group).getFunction();
+ }
for (String component : service.components) {
- if (!allTasks.get(service.serviceName).containsKey(component)) {
+ if (upgradePack.getType() == UpgradeType.ROLLING && !allTasks.get(service.serviceName).containsKey(component)) {
continue;
}
-
+
HostsType hostsType = mhr.getMasterAndHosts(service.serviceName, component);
+ // TODO AMBARI-12698, how does this impact SECONDARY NAMENODE if there's no NameNode HA?
if (null == hostsType) {
continue;
}
@@ -237,7 +334,31 @@ public class UpgradeHelper {
}
Service svc = cluster.getService(service.serviceName);
- ProcessingComponent pc = allTasks.get(service.serviceName).get(component);
+
+ ProcessingComponent pc = null;
+ if (upgradePack.getType() == UpgradeType.ROLLING) {
+ pc = allTasks.get(service.serviceName).get(component);
+ } else if (upgradePack.getType() == UpgradeType.NON_ROLLING) {
+ // Construct a processing task on-the-fly
+ if (null != functionName) {
+ pc = new ProcessingComponent();
+ pc.name = component;
+ pc.tasks = new ArrayList<>();
+
+ if (functionName == Type.START) {
+ pc.tasks.add(new StartTask());
+ } else if (functionName == Type.STOP) {
+ pc.tasks.add(new StopTask());
+ } else if (functionName == Type.RESTART) {
+ pc.tasks.add(new RestartTask());
+ }
+ }
+ }
+
+ if (pc == null) {
+ LOG.error(MessageFormat.format("Couldn't create a processing component for service {0} and component {1}.", service.serviceName, component));
+ continue;
+ }
setDisplayNames(context, service.serviceName, component);
@@ -246,7 +367,7 @@ public class UpgradeHelper {
// !!! revisit if needed
if (!hostsType.hosts.isEmpty() && hostsType.master != null && hostsType.secondary != null) {
// The order is important, first do the standby, then the active namenode.
- LinkedHashSet<String> order = new LinkedHashSet<String>();
+ LinkedHashSet<String> order = new LinkedHashSet<>();
order.add(hostsType.secondary);
order.add(hostsType.master);
@@ -342,7 +463,7 @@ public class UpgradeHelper {
String result = source;
- List<String> tokens = new ArrayList<String>(5);
+ List<String> tokens = new ArrayList<>(5);
Matcher matcher = PLACEHOLDER_REGEX.matcher(source);
while (matcher.find()) {
tokens.add(matcher.group(1));
@@ -424,6 +545,9 @@ public class UpgradeHelper {
*/
public String title;
+
+ public Class<? extends Grouping> groupClass;
+
/**
* Indicate whether retry is allowed for the stages in this group.
*/
@@ -438,7 +562,7 @@ public class UpgradeHelper {
/**
* List of stages for the group
*/
- public List<StageWrapper> items = new ArrayList<StageWrapper>();
+ public List<StageWrapper> items = new ArrayList<>();
/**
* {@inheritDoc}
@@ -521,8 +645,5 @@ public class UpgradeHelper {
} catch (AmbariException e) {
LOG.debug("Could not get service detail", e);
}
-
-
}
-
}