Java tutorial
/** * 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.controller.internal; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER; import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.Role; import org.apache.ambari.server.RoleCommand; import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.actionmanager.StageFactory; import org.apache.ambari.server.api.resources.UpgradeResourceDefinition; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.ActionExecutionContext; import org.apache.ambari.server.controller.AmbariActionExecutionHelper; import org.apache.ambari.server.controller.AmbariCustomCommandExecutionHelper; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.ExecuteCommandJson; import org.apache.ambari.server.controller.spi.NoSuchParentResourceException; import org.apache.ambari.server.controller.spi.NoSuchResourceException; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.orm.dao.RequestDAO; import org.apache.ambari.server.orm.dao.UpgradeDAO; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.orm.entities.RequestEntity; import org.apache.ambari.server.orm.entities.UpgradeEntity; 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.ConfigHelper; import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackId; 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.UpgradePack; import org.apache.ambari.server.state.stack.upgrade.ConfigureTask; import org.apache.ambari.server.state.stack.upgrade.Direction; import org.apache.ambari.server.state.stack.upgrade.ManualTask; 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.svccomphost.ServiceComponentHostServerActionEvent; import org.apache.ambari.server.utils.StageUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; import com.google.inject.Provider; /** * Manages the ability to start and get status of upgrades. */ @StaticallyInject 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_REQUEST_ID = "Upgrade/request_id"; // TODO : Get rid of the UPGRADE_FORCE_DOWNGRADE property... should use downgrade create directive protected static final String UPGRADE_FORCE_DOWNGRADE = "Upgrade/force_downgrade"; protected static final String UPGRADE_FROM_VERSION = "Upgrade/from_version"; protected static final String UPGRADE_TO_VERSION = "Upgrade/to_version"; protected static final String UPGRADE_DIRECTION = "Upgrade/direction"; protected static final String UPGRADE_REQUEST_STATUS = "Upgrade/request_status"; protected static final String UPGRADE_ABORT_REASON = "Upgrade/abort_reason"; /* * Lifted from RequestResourceProvider */ private static final String REQUEST_CONTEXT_ID = "Upgrade/request_context"; private static final String REQUEST_TYPE_ID = "Upgrade/type"; private static final String REQUEST_CREATE_TIME_ID = "Upgrade/create_time"; private static final String REQUEST_START_TIME_ID = "Upgrade/start_time"; private static final String REQUEST_END_TIME_ID = "Upgrade/end_time"; private static final String REQUEST_EXCLUSIVE_ID = "Upgrade/exclusive"; private static final String REQUEST_PROGRESS_PERCENT_ID = "Upgrade/progress_percent"; private static final String REQUEST_STATUS_PROPERTY_ID = "Upgrade/request_status"; private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>( Arrays.asList(UPGRADE_REQUEST_ID, UPGRADE_CLUSTER_NAME)); private static final Set<String> PROPERTY_IDS = new HashSet<String>(); 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"; 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"; 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>(); @Inject private static UpgradeDAO s_upgradeDAO = null; @Inject private static Provider<AmbariMetaInfo> s_metaProvider = null; @Inject private static RepositoryVersionDAO s_repoVersionDAO = null; @Inject private static Provider<RequestFactory> s_requestFactory; @Inject private static Provider<StageFactory> s_stageFactory; @Inject private static Provider<AmbariActionExecutionHelper> s_actionExecutionHelper; @Inject private static Provider<AmbariCustomCommandExecutionHelper> s_commandExecutionHelper; @Inject private static RequestDAO s_requestDAO = null; @Inject private static HostRoleCommandDAO s_hostRoleCommandDAO = null; /** * Used to generated the correct tasks and stages during an upgrade. */ @Inject private static UpgradeHelper s_upgradeHelper; @Inject private static Configuration s_configuration; static { // properties PROPERTY_IDS.add(UPGRADE_CLUSTER_NAME); PROPERTY_IDS.add(UPGRADE_VERSION); PROPERTY_IDS.add(UPGRADE_REQUEST_ID); PROPERTY_IDS.add(UPGRADE_FORCE_DOWNGRADE); PROPERTY_IDS.add(UPGRADE_FROM_VERSION); PROPERTY_IDS.add(UPGRADE_TO_VERSION); PROPERTY_IDS.add(UPGRADE_DIRECTION); PROPERTY_IDS.add(REQUEST_CONTEXT_ID); PROPERTY_IDS.add(REQUEST_CREATE_TIME_ID); PROPERTY_IDS.add(REQUEST_END_TIME_ID); PROPERTY_IDS.add(REQUEST_EXCLUSIVE_ID); PROPERTY_IDS.add(REQUEST_PROGRESS_PERCENT_ID); PROPERTY_IDS.add(REQUEST_START_TIME_ID); PROPERTY_IDS.add(REQUEST_STATUS_PROPERTY_ID); PROPERTY_IDS.add(REQUEST_TYPE_ID); // keys KEY_PROPERTY_IDS.put(Resource.Type.Upgrade, UPGRADE_REQUEST_ID); KEY_PROPERTY_IDS.put(Resource.Type.Cluster, UPGRADE_CLUSTER_NAME); } private static final Logger LOG = LoggerFactory.getLogger(UpgradeResourceProvider.class); /** * Constructor. * * @param controller the controller */ UpgradeResourceProvider(AmbariManagementController controller) { super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller); } @Override public RequestStatus createResources(final Request request) throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException { Set<Map<String, Object>> requestMaps = request.getProperties(); if (requestMaps.size() > 1) { throw new SystemException("Can only initiate one upgrade per request."); } // !!! above check ensures only one final Map<String, Object> requestMap = requestMaps.iterator().next(); final Map<String, String> requestInfoProps = request.getRequestInfoProperties(); UpgradeEntity entity = createResources(new Command<UpgradeEntity>() { @Override public UpgradeEntity invoke() throws AmbariException { String forceDowngrade = requestInfoProps.get(UpgradeResourceDefinition.DOWNGRADE_DIRECTIVE); // check the property if the directive is not specified... if (forceDowngrade == null) { forceDowngrade = (String) requestMap.get(UPGRADE_FORCE_DOWNGRADE); } Direction direction = Boolean.parseBoolean(forceDowngrade) ? Direction.DOWNGRADE : Direction.UPGRADE; UpgradePack up = validateRequest(direction, requestMap); return createUpgrade(direction, up, requestMap); } }); if (null == entity) { throw new SystemException("Could not load upgrade"); } notifyCreate(Resource.Type.Upgrade, request); Resource res = new ResourceImpl(Resource.Type.Upgrade); res.setProperty(UPGRADE_REQUEST_ID, entity.getRequestId()); return new RequestStatusImpl(null, Collections.singleton(res)); } @Override public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { Set<Resource> results = new HashSet<Resource>(); Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate); for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) { String clusterName = (String) propertyMap.get(UPGRADE_CLUSTER_NAME); if (null == clusterName || clusterName.isEmpty()) { throw new IllegalArgumentException("The cluster name is required when querying for upgrades"); } Cluster cluster; try { cluster = getManagementController().getClusters().getCluster(clusterName); } catch (AmbariException e) { throw new NoSuchResourceException(String.format("Cluster %s could not be loaded", clusterName)); } List<UpgradeEntity> upgrades = new ArrayList<UpgradeEntity>(); String upgradeIdStr = (String) propertyMap.get(UPGRADE_REQUEST_ID); if (null != upgradeIdStr) { UpgradeEntity upgrade = s_upgradeDAO.findUpgradeByRequestId(Long.valueOf(upgradeIdStr)); if (null != upgrade) { upgrades.add(upgrade); } } else { upgrades = s_upgradeDAO.findUpgrades(cluster.getClusterId()); } for (UpgradeEntity entity : upgrades) { Resource r = toResource(entity, clusterName, requestPropertyIds); results.add(r); RequestEntity rentity = s_requestDAO.findByPK(entity.getRequestId()); setResourceProperty(r, REQUEST_CONTEXT_ID, rentity.getRequestContext(), requestPropertyIds); setResourceProperty(r, REQUEST_TYPE_ID, rentity.getRequestType(), requestPropertyIds); setResourceProperty(r, REQUEST_CREATE_TIME_ID, rentity.getCreateTime(), requestPropertyIds); setResourceProperty(r, REQUEST_START_TIME_ID, rentity.getStartTime(), requestPropertyIds); setResourceProperty(r, REQUEST_END_TIME_ID, rentity.getEndTime(), requestPropertyIds); setResourceProperty(r, REQUEST_EXCLUSIVE_ID, rentity.isExclusive(), requestPropertyIds); Map<Long, HostRoleCommandStatusSummaryDTO> summary = s_hostRoleCommandDAO .findAggregateCounts(entity.getRequestId()); CalculatedStatus calc = CalculatedStatus.statusFromStageSummary(summary, summary.keySet()); setResourceProperty(r, REQUEST_STATUS_PROPERTY_ID, calc.getStatus(), requestPropertyIds); setResourceProperty(r, REQUEST_PROGRESS_PERCENT_ID, calc.getPercent(), requestPropertyIds); } } return results; } @Override public RequestStatus updateResources(final Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { Set<Map<String, Object>> requestMaps = request.getProperties(); if (requestMaps.size() > 1) { throw new SystemException("Can only update one upgrade per request."); } // !!! above check ensures only one final Map<String, Object> propertyMap = requestMaps.iterator().next(); String requestId = (String) propertyMap.get(UPGRADE_REQUEST_ID); if (null == requestId) { throw new IllegalArgumentException(String.format("%s is required", UPGRADE_REQUEST_ID)); } String requestStatus = (String) propertyMap.get(UPGRADE_REQUEST_STATUS); if (null == requestStatus) { throw new IllegalArgumentException(String.format("%s is required", UPGRADE_REQUEST_STATUS)); } HostRoleStatus status = HostRoleStatus.valueOf(requestStatus); if (status != HostRoleStatus.ABORTED) { throw new IllegalArgumentException( String.format("Cannot set status %s, only %s is allowed", status, HostRoleStatus.ABORTED)); } String reason = (String) propertyMap.get(UPGRADE_ABORT_REASON); if (null == reason) { reason = String.format(DEFAULT_REASON_TEMPLATE, requestId); } ActionManager actionManager = getManagementController().getActionManager(); List<org.apache.ambari.server.actionmanager.Request> requests = actionManager .getRequests(Collections.singletonList(Long.valueOf(requestId))); org.apache.ambari.server.actionmanager.Request internalRequest = requests.get(0); HostRoleStatus internalStatus = CalculatedStatus.statusFromStages(internalRequest.getStages()).getStatus(); if (!internalStatus.isCompletedState()) { actionManager.cancelRequest(internalRequest.getRequestId(), reason); } return getRequestStatus(null); } @Override public RequestStatus deleteResources(Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { throw new SystemException("Cannot delete Upgrades"); } @Override protected Set<String> getPKPropertyIds() { return PK_PROPERTY_IDS; } private Resource toResource(UpgradeEntity entity, String clusterName, Set<String> requestedIds) { ResourceImpl resource = new ResourceImpl(Resource.Type.Upgrade); setResourceProperty(resource, UPGRADE_CLUSTER_NAME, clusterName, 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); setResourceProperty(resource, UPGRADE_DIRECTION, entity.getDirection(), requestedIds); return resource; } /** * Validates a singular API request. * * @param requestMap the map of properties * @return the validated upgrade pack * @throws AmbariException */ private UpgradePack validateRequest(Direction direction, Map<String, Object> requestMap) throws AmbariException { String clusterName = (String) requestMap.get(UPGRADE_CLUSTER_NAME); String version = (String) requestMap.get(UPGRADE_VERSION); String versionForUpgradePack = (String) requestMap.get(UPGRADE_FROM_VERSION); if (null == clusterName) { throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME)); } if (null == version) { throw new AmbariException(String.format("%s is required", UPGRADE_VERSION)); } Cluster cluster = getManagementController().getClusters().getCluster(clusterName); StackId stack = cluster.getDesiredStackVersion(); String repoVersion = version; if (direction.isDowngrade() && null != versionForUpgradePack) { repoVersion = versionForUpgradePack; } RepositoryVersionEntity versionEntity = s_repoVersionDAO.findByStackAndVersion(stack.getStackId(), repoVersion); if (null == versionEntity) { throw new AmbariException( String.format("Version %s for stack %s was not found", repoVersion, stack.getStackVersion())); } Map<String, UpgradePack> packs = s_metaProvider.get().getUpgradePacks(stack.getStackName(), stack.getStackVersion()); UpgradePack up = packs.get(versionEntity.getUpgradePackage()); 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)); } // !!! validate all hosts have the version installed return up; } /** * Inject variables into the {@link org.apache.ambari.server.orm.entities.UpgradeItemEntity}, whose * tasks may use strings like {{configType/propertyName}} that need to be retrieved from the properties. * @param configHelper Configuration Helper * @param cluster Cluster * @param upgradeItem the item whose tasks will be injected. */ private void injectVariables(ConfigHelper configHelper, Cluster cluster, UpgradeItemEntity upgradeItem) { final String regexp = "(\\{\\{.*?\\}\\})"; String task = upgradeItem.getTasks(); if (task != null && !task.isEmpty()) { Matcher m = Pattern.compile(regexp).matcher(task); while (m.find()) { String origVar = m.group(1); String configValue = configHelper.getPlaceholderValueFromDesiredConfigurations(cluster, origVar); if (null != configValue) { task = task.replace(origVar, configValue); } else { LOG.error("Unable to retrieve value for {}", origVar); } } upgradeItem.setTasks(task); } } private UpgradeEntity createUpgrade(Direction direction, UpgradePack pack, Map<String, Object> requestMap) throws AmbariException { String clusterName = (String) requestMap.get(UPGRADE_CLUSTER_NAME); if (null == clusterName) { throw new AmbariException(String.format("%s is required", UPGRADE_CLUSTER_NAME)); } Cluster cluster = getManagementController().getClusters().getCluster(clusterName); ConfigHelper configHelper = getManagementController().getConfigHelper(); // 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); UpgradeContext ctx = new UpgradeContext(resolver, version, direction); List<UpgradeGroupHolder> groups = s_upgradeHelper.createSequence(pack, ctx); if (groups.isEmpty()) { throw new AmbariException("There are no groupings available"); } List<UpgradeGroupEntity> groupEntities = new ArrayList<UpgradeGroupEntity>(); RequestStageContainer req = createRequest(direction, version); for (UpgradeGroupHolder group : groups) { UpgradeGroupEntity groupEntity = new UpgradeGroupEntity(); groupEntity.setName(group.name); groupEntity.setTitle(group.title); boolean skippable = group.skippable; boolean allowRetry = group.allowRetry; List<UpgradeItemEntity> itemEntities = new ArrayList<UpgradeItemEntity>(); for (StageWrapper wrapper : group.items) { if (wrapper.getType() == StageWrapper.Type.SERVER_SIDE_ACTION) { // !!! each stage is guaranteed to be of one type. but because there // is a bug that prevents one stage with multiple tasks assigned for the same host, // break them out into individual stages. for (TaskWrapper taskWrapper : wrapper.getTasks()) { for (Task task : taskWrapper.getTasks()) { UpgradeItemEntity itemEntity = new UpgradeItemEntity(); itemEntity.setText(wrapper.getText()); itemEntity.setTasks(wrapper.getTasksJson()); itemEntity.setHosts(wrapper.getHostsJson()); itemEntities.add(itemEntity); injectVariables(configHelper, cluster, itemEntity); makeServerSideStage(ctx, req, itemEntity, (ServerSideActionTask) task, skippable, allowRetry); } } } else { UpgradeItemEntity itemEntity = new UpgradeItemEntity(); itemEntity.setText(wrapper.getText()); itemEntity.setTasks(wrapper.getTasksJson()); itemEntity.setHosts(wrapper.getHostsJson()); itemEntities.add(itemEntity); injectVariables(configHelper, cluster, itemEntity); // upgrade items match a stage createStage(ctx, req, itemEntity, wrapper, skippable, allowRetry); } } groupEntity.setItems(itemEntities); groupEntities.add(groupEntity); } UpgradeEntity entity = new UpgradeEntity(); entity.setFromVersion(cluster.getCurrentClusterVersion().getRepositoryVersion().getVersion()); entity.setToVersion(version); entity.setUpgradeGroups(groupEntities); entity.setClusterId(Long.valueOf(cluster.getClusterId())); entity.setDirection(direction); req.getRequestStatusResponse(); entity.setRequestId(req.getId()); req.persist(); s_upgradeDAO.create(entity); return entity; } private RequestStageContainer createRequest(Direction direction, String version) { ActionManager actionManager = getManagementController().getActionManager(); RequestStageContainer requestStages = new RequestStageContainer(actionManager.getNextRequestId(), null, s_requestFactory.get(), actionManager); requestStages.setRequestContext(String.format("%s to %s", direction.getVerb(true), version)); return requestStages; } private void createStage(UpgradeContext context, RequestStageContainer request, UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry) throws AmbariException { switch (wrapper.getType()) { case RESTART: makeRestartStage(context, request, entity, wrapper, skippable, allowRetry); break; case RU_TASKS: makeActionStage(context, request, entity, wrapper, skippable, allowRetry); break; case SERVICE_CHECK: makeServiceCheckStage(context, request, entity, wrapper, skippable, allowRetry); break; default: break; } } private void makeActionStage(UpgradeContext context, RequestStageContainer request, UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry) throws AmbariException { if (0 == wrapper.getHosts().size()) { throw new AmbariException( String.format("Cannot create action for '%s' with no hosts", wrapper.getText())); } Cluster cluster = context.getCluster(); // add each host to this stage RequestResourceFilter filter = new RequestResourceFilter("", "", new ArrayList<String>(wrapper.getHosts())); Map<String, String> params = new HashMap<String, String>(); params.put(COMMAND_PARAM_TASKS, entity.getTasks()); params.put(COMMAND_PARAM_VERSION, context.getVersion()); params.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase()); // 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. AmbariMetaInfo ambariMetaInfo = s_metaProvider.get(); StackId stackId = cluster.getDesiredStackVersion(); StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); if (wrapper.getTasks() != null && wrapper.getTasks().size() > 0) { String serviceName = wrapper.getTasks().get(0).getService(); ServiceInfo serviceInfo = ambariMetaInfo.getService(stackId.getStackName(), stackId.getStackVersion(), serviceName); params.put(SERVICE_PACKAGE_FOLDER, serviceInfo.getServicePackageFolder()); params.put(HOOKS_FOLDER, stackInfo.getStackHooksFolder()); } ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(), "ru_execute_tasks", Collections.singletonList(filter), params); actionContext.setIgnoreMaintenance(true); actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false))); Map<String, String> hostLevelParams = new HashMap<String, String>(); hostLevelParams.put(JDK_LOCATION, getManagementController().getJdkResourceUrl()); ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext, cluster); Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari", cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getClusterHostInfo(), jsons.getCommandParamsForStage(), jsons.getHostParamsForStage()); stage.setSkippable(skippable); long stageId = request.getLastStageId() + 1; if (0L == stageId) { stageId = 1L; } stage.setStageId(stageId); entity.setStageId(Long.valueOf(stageId)); s_actionExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, allowRetry); // need to set meaningful text on the command for (Map<String, HostRoleCommand> map : stage.getHostRoleCommands().values()) { for (HostRoleCommand hrc : map.values()) { hrc.setCommandDetail(entity.getText()); } } request.addStages(Collections.singletonList(stage)); } private void makeRestartStage(UpgradeContext context, RequestStageContainer request, UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry) throws AmbariException { Cluster cluster = context.getCluster(); List<RequestResourceFilter> filters = new ArrayList<RequestResourceFilter>(); for (TaskWrapper tw : wrapper.getTasks()) { // add each host to this stage filters.add(new RequestResourceFilter(tw.getService(), tw.getComponent(), new ArrayList<String>(tw.getHosts()))); } Map<String, String> restartCommandParams = new HashMap<String, String>(); restartCommandParams.put(COMMAND_PARAM_RESTART_TYPE, "rolling_upgrade"); restartCommandParams.put(COMMAND_PARAM_VERSION, context.getVersion()); restartCommandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase()); ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(), "RESTART", filters, restartCommandParams); actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false))); actionContext.setIgnoreMaintenance(true); ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext, cluster); Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari", cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getClusterHostInfo(), jsons.getCommandParamsForStage(), jsons.getHostParamsForStage()); stage.setSkippable(skippable); long stageId = request.getLastStageId() + 1; if (0L == stageId) { stageId = 1L; } stage.setStageId(stageId); entity.setStageId(Long.valueOf(stageId)); Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("command", "RESTART"); s_commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams, allowRetry); request.addStages(Collections.singletonList(stage)); } private void makeServiceCheckStage(UpgradeContext context, RequestStageContainer request, UpgradeItemEntity entity, StageWrapper wrapper, boolean skippable, boolean allowRetry) throws AmbariException { List<RequestResourceFilter> filters = new ArrayList<RequestResourceFilter>(); for (TaskWrapper tw : wrapper.getTasks()) { filters.add(new RequestResourceFilter(tw.getService(), "", Collections.<String>emptyList())); } Cluster cluster = context.getCluster(); Map<String, String> commandParams = new HashMap<String, String>(); commandParams.put(COMMAND_PARAM_VERSION, context.getVersion()); commandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase()); ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(), "SERVICE_CHECK", filters, commandParams); actionContext.setTimeout(Short.valueOf(s_configuration.getDefaultAgentTaskTimeout(false))); actionContext.setIgnoreMaintenance(true); ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext, cluster); Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari", cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getClusterHostInfo(), jsons.getCommandParamsForStage(), jsons.getHostParamsForStage()); stage.setSkippable(skippable); long stageId = request.getLastStageId() + 1; if (0L == stageId) { stageId = 1L; } stage.setStageId(stageId); entity.setStageId(Long.valueOf(stageId)); Map<String, String> requestParams = new HashMap<String, String>(); s_commandExecutionHelper.get().addExecutionCommandsToStage(actionContext, stage, requestParams, allowRetry); request.addStages(Collections.singletonList(stage)); } private void makeServerSideStage(UpgradeContext context, RequestStageContainer request, UpgradeItemEntity entity, ServerSideActionTask task, boolean skippable, boolean allowRtery) throws AmbariException { Cluster cluster = context.getCluster(); Map<String, String> commandParams = new HashMap<String, String>(); commandParams.put(COMMAND_PARAM_CLUSTER_NAME, cluster.getClusterName()); commandParams.put(COMMAND_PARAM_VERSION, context.getVersion()); commandParams.put(COMMAND_PARAM_DIRECTION, context.getDirection().name().toLowerCase()); String itemDetail = entity.getText(); String stageText = StringUtils.abbreviate(entity.getText(), 255); switch (task.getType()) { case MANUAL: { ManualTask mt = (ManualTask) task; itemDetail = mt.message; if (null != mt.summary) { stageText = mt.summary; } entity.setText(itemDetail); if (null != mt.structuredOut) { commandParams.put(COMMAND_PARAM_STRUCT_OUT, mt.structuredOut); } break; } case CONFIGURE: { ConfigureTask ct = (ConfigureTask) task; Map<String, String> configProperties = ct.getConfigurationProperties(cluster); // if the properties are empty it means that the conditions in the // task did not pass; if (configProperties.isEmpty()) { stageText = "No conditions were met for this configuration task."; itemDetail = stageText; } else { commandParams.putAll(configProperties); // extract the config type, key and value to use to build the // summary and detail String configType = configProperties.get(ConfigureTask.PARAMETER_CONFIG_TYPE); String key = configProperties.get(ConfigureTask.PARAMETER_KEY); String value = configProperties.get(ConfigureTask.PARAMETER_VALUE); itemDetail = String.format("Updating config %s/%s to %s", configType, key, value); if (null != ct.summary) { stageText = ct.summary; } else { stageText = String.format("Updating Config %s", configType); } } entity.setText(itemDetail); break; } default: break; } ActionExecutionContext actionContext = new ActionExecutionContext(cluster.getClusterName(), Role.AMBARI_SERVER_ACTION.toString(), Collections.<RequestResourceFilter>emptyList(), commandParams); actionContext.setTimeout(Short.valueOf((short) -1)); actionContext.setIgnoreMaintenance(true); ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext, cluster); Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari", cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getClusterHostInfo(), jsons.getCommandParamsForStage(), jsons.getHostParamsForStage()); stage.setSkippable(skippable); long stageId = request.getLastStageId() + 1; if (0L == stageId) { stageId = 1L; } stage.setStageId(stageId); entity.setStageId(Long.valueOf(stageId)); // !!! hack hack hack String host = cluster.getAllHostsDesiredConfigs().keySet().iterator().next(); stage.addServerActionCommand(task.getImplementationClass(), getManagementController().getAuthName(), Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE, cluster.getClusterName(), host, new ServiceComponentHostServerActionEvent(StageUtils.getHostName(), System.currentTimeMillis()), commandParams, itemDetail, null, Integer.valueOf(1200), allowRtery); request.addStages(Collections.singletonList(stage)); } }