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.serveraction.upgrades; import java.text.MessageFormat; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeSet; import java.util.concurrent.ConcurrentMap; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.HostRoleStatus; import org.apache.ambari.server.actionmanager.ServiceComponentHostEventWrapper; import org.apache.ambari.server.agent.CommandReport; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.UpgradeDAO; import org.apache.ambari.server.orm.entities.HostRoleCommandEntity; import org.apache.ambari.server.orm.entities.UpgradeGroupEntity; import org.apache.ambari.server.orm.entities.UpgradeItemEntity; import org.apache.ambari.server.serveraction.AbstractServerAction; import org.apache.ambari.server.state.ServiceComponentHostEvent; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.inject.Inject; /** * The {@link AutoSkipFailedSummaryAction} is used to check if any * {@link HostRoleCommand}s were skipped automatically after they failed during * an upgrade. This will be automatically marked as * {@link HostRoleStatus#COMPLETED} if there are no skipped failures. Otherwise * it will be placed into {@link HostRoleStatus#HOLDING}. */ public class AutoSkipFailedSummaryAction extends AbstractServerAction { /** * Logger. */ private static final Logger LOG = LoggerFactory.getLogger(AutoSkipFailedSummaryAction.class); /** * The standard output template message. */ private static final String FAILURE_STD_OUT_TEMPLATE = "There were {0} skipped failure(s) that must be addressed before you can proceed. Please resolve each failure before continuing with the upgrade."; /** * ... */ private static final String MIDDLE_ELLIPSIZE_MARKER = "\n\u2026\n"; /** * Used to lookup the {@link UpgradeGroupEntity}. */ @Inject private UpgradeDAO m_upgradeDAO; /** * Used to lookup the tasks that need to be checked for * {@link HostRoleStatus#SKIPPED_FAILED}. */ @Inject private HostRoleCommandDAO m_hostRoleCommandDAO; /** * Used for writing structured out. */ @Inject private Gson m_gson; /** * A mapping of host -> Map<key,info> for each failure. */ private Map<String, Map<String, Object>> m_structuredFailures = new HashMap<>(); /** * {@inheritDoc} */ @Override public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext) throws AmbariException, InterruptedException { HostRoleCommand hostRoleCommand = getHostRoleCommand(); long requestId = hostRoleCommand.getRequestId(); long stageId = hostRoleCommand.getStageId(); // use the host role command to get to the parent upgrade group UpgradeItemEntity upgradeItem = m_upgradeDAO.findUpgradeItemByRequestAndStage(requestId, stageId); UpgradeGroupEntity upgradeGroup = upgradeItem.getGroupEntity(); // find all of the stages in this group long upgradeGroupId = upgradeGroup.getId(); UpgradeGroupEntity upgradeGroupEntity = m_upgradeDAO.findUpgradeGroup(upgradeGroupId); List<UpgradeItemEntity> groupUpgradeItems = upgradeGroupEntity.getItems(); TreeSet<Long> stageIds = new TreeSet<>(); for (UpgradeItemEntity groupUpgradeItem : groupUpgradeItems) { stageIds.add(groupUpgradeItem.getStageId()); } // for every stage, find all tasks that have been SKIPPED_FAILED - we use a // bit of trickery here since within any given request, the stage ID are // always sequential. This allows us to make a simple query instead of some // overly complex IN or NESTED SELECT query long minStageId = stageIds.first(); long maxStageId = stageIds.last(); List<HostRoleCommandEntity> skippedTasks = m_hostRoleCommandDAO.findByStatusBetweenStages( hostRoleCommand.getRequestId(), HostRoleStatus.SKIPPED_FAILED, minStageId, maxStageId); if (skippedTasks.isEmpty()) { return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", "There were no skipped failures", null); } StringBuilder buffer = new StringBuilder("The following steps failed and were automatically skipped:\n"); for (HostRoleCommandEntity skippedTask : skippedTasks) { try { ServiceComponentHostEventWrapper eventWrapper = new ServiceComponentHostEventWrapper( skippedTask.getEvent()); ServiceComponentHostEvent event = eventWrapper.getEvent(); String hostName = skippedTask.getHostName(); if (null != hostName) { Map<String, Object> failures = m_structuredFailures.get(hostName); if (null == failures) { failures = new HashMap<>(); m_structuredFailures.put(hostName, failures); } failures.put("id", skippedTask.getTaskId()); failures.put("exit_code", skippedTask.getExitcode()); failures.put("output_log", skippedTask.getOutputLog()); failures.put("error_log", skippedTask.getErrorLog()); String stdOut = StringUtils.abbreviateMiddle(new String(skippedTask.getStdOut()), MIDDLE_ELLIPSIZE_MARKER, 1000); String stderr = StringUtils.abbreviateMiddle(new String(skippedTask.getStdError()), MIDDLE_ELLIPSIZE_MARKER, 1000); failures.put("stdout", stdOut); failures.put("stderr", stderr); } buffer.append(event.getServiceComponentName()); if (null != event.getHostName()) { buffer.append(" on "); buffer.append(event.getHostName()); } buffer.append(": "); buffer.append(skippedTask.getCommandDetail()); buffer.append("\n"); } catch (Exception exception) { LOG.warn("Unable to extract failure information for {}", skippedTask); buffer.append(": "); buffer.append(skippedTask); } } String structuredOutput = m_gson.toJson(m_structuredFailures); String standardOutput = MessageFormat.format(FAILURE_STD_OUT_TEMPLATE, skippedTasks.size()); String standardError = buffer.toString(); return createCommandReport(0, HostRoleStatus.HOLDING, structuredOutput, standardOutput, standardError); } }