/** * 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.state.stack.upgrade; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.ambari.server.configuration.Configuration; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Objects; import com.google.gson.Gson; /** * */ public class StageWrapper { private static final Logger LOG = LoggerFactory.getLogger(StageWrapper.class); private static Gson gson = new Gson(); private String text; private Type type; private Map<String, String> params; private List<TaskWrapper> tasks; /** * Wrapper for a stage that encapsulates its text and tasks. * @param type Type of stage * @param text Text to display * @param tasks List of tasks to add to the stage */ public StageWrapper(Type type, String text, TaskWrapper... tasks) { this(type, text, null, Arrays.asList(tasks)); } /** * Wrapper for a stage that encapsulates its text, params, and tasks. * @param type Type of stage * @param text Text to display * @param params Command parameters * @param tasks List of tasks to add to the stage */ public StageWrapper(Type type, String text, Map<String, String> params, TaskWrapper... tasks) { this(type, text, params, Arrays.asList(tasks)); } /** * Wrapper for a stage that encapsulates its text, params, and tasks. * @param type Type of stage * @param text Text to display * @param params Command parameters * @param tasks List of tasks to add to the stage */ public StageWrapper(Type type, String text, Map<String, String> params, List<TaskWrapper> tasks) { this.type = type; this.text = text; this.params = (params == null ? Collections.<String, String>emptyMap() : params); this.tasks = tasks; } /** * Gets the hosts json. */ public String getHostsJson() { return gson.toJson(getHosts()); } /** * Gets the tasks json. */ public String getTasksJson() { List<Task> realTasks = new ArrayList<>(); for (TaskWrapper tw : tasks) { realTasks.addAll(tw.getTasks()); } return gson.toJson(realTasks); } /** * @return the set of hosts for all tasks */ public Set<String> getHosts() { Set<String> hosts = new HashSet<>(); for (TaskWrapper tw : tasks) { hosts.addAll(tw.getHosts()); } return hosts; } /** * @return the additional command parameters */ public Map<String, String> getParams() { return params; } /** * @return the wrapped tasks for this stage */ public List<TaskWrapper> getTasks() { return tasks; } /** * @return the text for this stage */ public String getText() { return text; } /** * @param newText the new text for the stage */ public void setText(String newText) { text = newText; } /** * Gets the type of stage. All tasks defined for the stage execute this type. * @return the type */ public Type getType() { return type; } /** * Indicates the type of wrapper. */ public enum Type { SERVER_SIDE_ACTION, RESTART, RU_TASKS, SERVICE_CHECK, STOP, START, CONFIGURE } /** * {@inheritDoc} */ @Override public String toString() { return Objects.toStringHelper(this).add("type", type) .add("text",text) .omitNullValues().toString(); } /** * Gets the maximum timeout for any task that this {@code StageWrapper} encapsulates. TaskWrappers * are homogeneous across the stage, but timeouts are defined in Upgrade Packs * at the task, so each one should be checked individually. * * <p> * WARNING: This method relies on incorrect assumptions about {@link StageWrapper}s and the {@link TaskWrapper}s * that are contained in them. Orchestration is currently forcing a StageWrapper to have only one TaskWrapper, * even though they could have many per the code. * * In addition, a TaskWrapper should have a one-to-one reference with the Task it contains. That will be * fixed in a future release. * </p> * * @param configuration the configuration instance. StageWrappers are not injectable, so pass * this in. * @return the maximum timeout, or the default agent execution timeout if none are found. Never {@code null}. */ public Short getMaxTimeout(Configuration configuration) { Set<String> timeoutKeys = new HashSet<>(); // !!! FIXME a TaskWrapper should have only one task. for (TaskWrapper wrapper : tasks) { timeoutKeys.addAll(wrapper.getTimeoutKeys()); } Short defaultTimeout = Short.valueOf(configuration.getDefaultAgentTaskTimeout(false)); if (CollectionUtils.isEmpty(timeoutKeys)) { return defaultTimeout; } Short timeout = null; for (String key : timeoutKeys) { String configValue = configuration.getProperty(key); if (StringUtils.isNotBlank(configValue)) { try { Short configTimeout = Short.valueOf(configValue); if (null == timeout || configTimeout > timeout) { timeout = configTimeout; } } catch (Exception e) { LOG.warn("Could not parse {}/{} to a timeout value", key, configValue); } } else { LOG.warn("Configuration {} not found to compute timeout", key); } } return null == timeout ? defaultTimeout : timeout; } }