/** * 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 java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.Map; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.RoleCommand; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.Request; import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.controller.ExecuteActionRequest; import org.apache.ambari.server.controller.RequestStatusResponse; import org.apache.ambari.server.controller.ShortTaskStatus; import org.apache.ambari.server.state.State; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Contains stages associated with a request. */ public class RequestStageContainer { /** * Request id */ private Long id; /** * Request stages */ private List<Stage> stages; /** * Request Factory used to create Request instance */ private RequestFactory requestFactory; /** * Action Manager */ private ActionManager actionManager; private String requestContext = null; private ExecuteActionRequest actionRequest = null; private String clusterHostInfo = null; /** * Logger */ private final static Logger LOG = LoggerFactory.getLogger(RequestStageContainer.class); /** * Constructor. * * @param id request id * @param stages stages * @param factory request factory * @param manager action manager */ public RequestStageContainer(Long id, List<Stage> stages, RequestFactory factory, ActionManager manager) { this(id, stages, factory, manager, null); } /** * Constructor. * * @param id request id * @param stages stages * @param factory request factory * @param manager action manager * @param actionRequest action request */ public RequestStageContainer(Long id, List<Stage> stages, RequestFactory factory, ActionManager manager, ExecuteActionRequest actionRequest) { this.id = id; this.stages = stages == null ? new ArrayList<Stage>() : stages; this.requestFactory = factory; this.actionManager = manager; this.actionRequest = actionRequest; this.clusterHostInfo = "{}"; } /** * Get the request id. * * @return request id */ public Long getId() { return id; } public void setClusterHostInfo(String clusterHostInfo){ this.clusterHostInfo = clusterHostInfo; } /** * Add stages to request. * * @param stages stages to add */ public void addStages(List<Stage> stages) { if (stages != null) { this.stages.addAll(stages); } } /** * Get request stages. * * @return list of stages */ public List<Stage> getStages() { return stages; } /** * Get the stage id of the last stage. * * @return stage id of the last stage or -1 if no stages present */ public long getLastStageId() { return stages.isEmpty() ? -1 : stages.get(stages.size() - 1).getStageId(); } /** * Sets the context for the request (optional operation) * * @param context the new context */ public void setRequestContext(String context) { requestContext = context; } /** * Determine the projected state for a host component from the existing stages. * * @param host host name * @param component component name * * @return the projected state of a host component after all stages successfully complete * or null if the host component state is not modified in the current stages */ public State getProjectedState(String host, String component) { RoleCommand lastCommand = null; ListIterator<Stage> iterator = stages.listIterator(stages.size()); while (lastCommand == null && iterator.hasPrevious()) { Stage stage = iterator.previous(); Map<String, Map<String, HostRoleCommand>> stageCommands = stage.getHostRoleCommands(); if (stageCommands != null) { Map<String, HostRoleCommand> hostCommands = stageCommands.get(host); if (hostCommands != null) { HostRoleCommand roleCommand = hostCommands.get(component); if (roleCommand != null && roleCommand.getRoleCommand() != RoleCommand.SERVICE_CHECK) { lastCommand = roleCommand.getRoleCommand(); } } } } State resultingState = null; if (lastCommand != null) { switch(lastCommand) { case INSTALL: case STOP: resultingState = State.INSTALLED; break; case START: resultingState = State.STARTED; break; case UNINSTALL: resultingState = State.INIT; break; default: resultingState = State.UNKNOWN; } } return resultingState; } /** * Persist the stages. */ public void persist() throws AmbariException { if (!stages.isEmpty()) { Request request = (null == actionRequest) ? requestFactory.createNewFromStages(stages, clusterHostInfo) : requestFactory.createNewFromStages(stages, clusterHostInfo, actionRequest); if (null != requestContext) { request.setRequestContext(requestContext); } if (request != null && request.getStages()!= null && !request.getStages().isEmpty()) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Triggering Action Manager, request=%s", request)); } actionManager.sendActions(request, actionRequest); } } } /** * Build a request status response. * * @return a {@link org.apache.ambari.server.controller.RequestStatusResponse} for the request */ public RequestStatusResponse getRequestStatusResponse() { RequestStatusResponse response = null; if (! stages.isEmpty()) { response = new RequestStatusResponse(id); List<HostRoleCommand> hostRoleCommands = actionManager.getRequestTasks(id); response.setRequestContext(actionManager.getRequestContext(id)); List<ShortTaskStatus> tasks = new ArrayList<>(); for (HostRoleCommand hostRoleCommand : hostRoleCommands) { tasks.add(new ShortTaskStatus(hostRoleCommand)); } response.setTasks(tasks); } return response; } }