/* * 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.actionmanager; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.controller.ExecuteActionRequest; import org.apache.ambari.server.controller.internal.RequestOperationLevel; import org.apache.ambari.server.controller.internal.RequestResourceFilter; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.entities.HostEntity; import org.apache.ambari.server.orm.entities.RequestEntity; import org.apache.ambari.server.orm.entities.RequestOperationLevelEntity; import org.apache.ambari.server.orm.entities.RequestResourceFilterEntity; import org.apache.ambari.server.orm.entities.StageEntity; import org.apache.ambari.server.state.Clusters; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; @StaticallyInject public class Request { private static final Logger LOG = LoggerFactory.getLogger(Request.class); private final long requestId; private long clusterId; private String clusterName; private Long requestScheduleId; private String commandName; private String requestContext; private long createTime; private long startTime; private long endTime; private String clusterHostInfo; /** * If true, this request can not be executed in parallel with any another * requests. That is useful when updating MM state, performing * decommission etc. * Defaults to false. */ private boolean exclusive; /** * As of now, this field is not used. Request status is * calculated at RequestResourceProvider on the fly. */ private HostRoleStatus status = HostRoleStatus.PENDING; private HostRoleStatus displayStatus = HostRoleStatus.PENDING; private String inputs; private List<RequestResourceFilter> resourceFilters; private RequestOperationLevel operationLevel; private RequestType requestType; private Collection<Stage> stages = new ArrayList<>(); @Inject private static HostDAO hostDAO; @AssistedInject /** * Construct new entity */ public Request(@Assisted long requestId, @Assisted("clusterId") Long clusterId, Clusters clusters) { this.requestId = requestId; this.clusterId = clusterId.longValue(); this.createTime = System.currentTimeMillis(); this.startTime = -1; this.endTime = -1; this.exclusive = false; this.clusterHostInfo = "{}"; if (-1L != this.clusterId) { try { this.clusterName = clusters.getClusterById(this.clusterId).getClusterName(); } catch (AmbariException e) { LOG.debug("Could not load cluster with id {}, the cluster may have been removed for request {}", clusterId, Long.valueOf(requestId)); } } } @AssistedInject /** * Construct new entity from stages provided */ //TODO remove when not needed public Request(@Assisted Collection<Stage> stages, @Assisted String clusterHostInfo, Clusters clusters){ if (stages != null && !stages.isEmpty()) { this.stages.addAll(stages); Stage stage = stages.iterator().next(); this.requestId = stage.getRequestId(); this.clusterName = stage.getClusterName(); try { this.clusterId = clusters.getCluster(clusterName).getClusterId(); } catch (Exception e) { if (null != clusterName) { String message = String.format("Cluster %s not found", clusterName); LOG.error(message); throw new RuntimeException(message); } } this.requestContext = stages.iterator().next().getRequestContext(); this.createTime = System.currentTimeMillis(); this.startTime = -1; this.endTime = -1; this.clusterHostInfo = clusterHostInfo; this.requestType = RequestType.INTERNAL_REQUEST; this.exclusive = false; } else { String message = "Attempted to construct request from empty stage collection"; LOG.error(message); throw new RuntimeException(message); } } @AssistedInject /** * Construct new entity from stages provided */ //TODO remove when not needed public Request(@Assisted Collection<Stage> stages, @Assisted String clusterHostInfo, @Assisted ExecuteActionRequest actionRequest, Clusters clusters, Gson gson) throws AmbariException { this(stages, clusterHostInfo, clusters); if (actionRequest != null) { this.resourceFilters = actionRequest.getResourceFilters(); this.operationLevel = actionRequest.getOperationLevel(); this.inputs = gson.toJson(actionRequest.getParameters()); this.requestType = actionRequest.isCommand() ? RequestType.COMMAND : RequestType.ACTION; this.commandName = actionRequest.isCommand() ? actionRequest.getCommandName() : actionRequest.getActionName(); this.exclusive = actionRequest.isExclusive(); } } @AssistedInject /** * Load existing request from database */ public Request(@Assisted RequestEntity entity, final StageFactory stageFactory, Clusters clusters){ if (entity == null) { throw new RuntimeException("Request entity cannot be null."); } this.requestId = entity.getRequestId(); this.clusterId = entity.getClusterId(); if (-1L != this.clusterId) { try { this.clusterName = clusters.getClusterById(this.clusterId).getClusterName(); } catch (AmbariException e) { LOG.debug("Could not load cluster with id {}, the cluster may have been removed for request {}", Long.valueOf(clusterId), Long.valueOf(requestId)); } } this.createTime = entity.getCreateTime(); this.startTime = entity.getStartTime(); this.endTime = entity.getEndTime(); this.exclusive = entity.isExclusive(); this.requestContext = entity.getRequestContext(); this.inputs = entity.getInputs(); this.clusterHostInfo = entity.getClusterHostInfo(); this.requestType = entity.getRequestType(); this.commandName = entity.getCommandName(); this.status = entity.getStatus(); this.displayStatus = entity.getDisplayStatus(); if (entity.getRequestScheduleEntity() != null) { this.requestScheduleId = entity.getRequestScheduleEntity().getScheduleId(); } Collection<StageEntity> stageEntities = entity.getStages(); if(stageEntities == null || stageEntities.isEmpty()) { stages = Collections.emptyList(); } else { stages = new ArrayList<>(stageEntities.size()); for (StageEntity stageEntity : stageEntities) { stages.add(stageFactory.createExisting(stageEntity)); } } resourceFilters = filtersFromEntity(entity); operationLevel = operationLevelFromEntity(entity); } private static List<String> getHostsList(String hosts) { List<String> hostList = new ArrayList<>(); if (hosts != null && !hosts.isEmpty()) { for (String host : hosts.split(",")) { if (!host.trim().isEmpty()) { hostList.add(host.trim()); } } } return hostList; } public Collection<Stage> getStages() { return stages; } public void setStages(Collection<Stage> stages) { this.stages = stages; } public long getRequestId() { return requestId; } public synchronized RequestEntity constructNewPersistenceEntity() { RequestEntity requestEntity = new RequestEntity(); requestEntity.setRequestId(requestId); requestEntity.setClusterId(clusterId); requestEntity.setCreateTime(createTime); requestEntity.setStartTime(startTime); requestEntity.setEndTime(endTime); requestEntity.setExclusive(exclusive); requestEntity.setRequestContext(requestContext); requestEntity.setInputs(inputs); requestEntity.setRequestType(requestType); requestEntity.setRequestScheduleId(requestScheduleId); requestEntity.setStatus(status); requestEntity.setDisplayStatus(displayStatus); requestEntity.setClusterHostInfo(clusterHostInfo); //TODO set all fields if (resourceFilters != null) { List<RequestResourceFilterEntity> filterEntities = new ArrayList<>(); for (RequestResourceFilter resourceFilter : resourceFilters) { RequestResourceFilterEntity filterEntity = new RequestResourceFilterEntity(); filterEntity.setServiceName(resourceFilter.getServiceName()); filterEntity.setComponentName(resourceFilter.getComponentName()); filterEntity.setHosts(resourceFilter.getHostNames() != null ? StringUtils.join(resourceFilter.getHostNames(), ",") : null); filterEntity.setRequestEntity(requestEntity); filterEntity.setRequestId(requestId); filterEntities.add(filterEntity); } requestEntity.setResourceFilterEntities(filterEntities); } if (operationLevel != null) { HostEntity hostEntity = hostDAO.findByName(operationLevel.getHostName()); Long hostId = hostEntity != null ? hostEntity.getHostId() : null; RequestOperationLevelEntity operationLevelEntity = new RequestOperationLevelEntity(); operationLevelEntity.setLevel(operationLevel.getLevel().toString()); operationLevelEntity.setClusterName(operationLevel.getClusterName()); operationLevelEntity.setServiceName(operationLevel.getServiceName()); operationLevelEntity.setHostComponentName(operationLevel.getHostComponentName()); operationLevelEntity.setHostId(hostId); operationLevelEntity.setRequestEntity(requestEntity); operationLevelEntity.setRequestId(requestId); requestEntity.setRequestOperationLevel(operationLevelEntity); } return requestEntity; } public String getClusterHostInfo() { return clusterHostInfo; } public void setClusterHostInfo(String clusterHostInfo) { this.clusterHostInfo = clusterHostInfo; } public Long getClusterId() { return Long.valueOf(clusterId); } public String getClusterName() { return clusterName; } public String getRequestContext() { return requestContext; } public void setRequestContext(String requestContext) { this.requestContext = requestContext; } public long getCreateTime() { return createTime; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } public long getEndTime() { return endTime; } public void setEndTime(long endTime) { this.endTime = endTime; } public String getInputs() { return inputs; } public void setInputs(String inputs) { this.inputs = inputs; } public List<RequestResourceFilter> getResourceFilters() { return resourceFilters; } public void setResourceFilters(List<RequestResourceFilter> resourceFilters) { this.resourceFilters = resourceFilters; } public RequestOperationLevel getOperationLevel() { return operationLevel; } public void setOperationLevel(RequestOperationLevel operationLevel) { this.operationLevel = operationLevel; } public RequestType getRequestType() { return requestType; } public void setRequestType(RequestType requestType) { this.requestType = requestType; } public String getCommandName() { return commandName; } public void setCommandName(String commandName) { this.commandName = commandName; } public Long getRequestScheduleId() { return requestScheduleId; } public void setRequestScheduleId(Long requestScheduleId) { this.requestScheduleId = requestScheduleId; } public List<HostRoleCommand> getCommands() { List<HostRoleCommand> commands = new ArrayList<>(); for (Stage stage : stages) { commands.addAll(stage.getOrderedHostRoleCommands()); } return commands; } @Override public String toString() { return "Request{" + "requestId=" + requestId + ", clusterId=" + clusterId + ", clusterName='" + clusterName + '\'' + ", requestContext='" + requestContext + '\'' + ", createTime=" + createTime + ", startTime=" + startTime + ", endTime=" + endTime + ", inputs='" + inputs + '\'' + ", status='" + status + '\'' + ", displayStatus='" + displayStatus + '\'' + ", resourceFilters='" + resourceFilters + '\'' + ", operationLevel='" + operationLevel + '\'' + ", requestType=" + requestType + ", stages=" + stages + '}'; } public HostRoleStatus getStatus() { return status; } public void setStatus(HostRoleStatus status) { this.status = status; } public boolean isExclusive() { return exclusive; } public void setExclusive(boolean isExclusive) { exclusive = isExclusive; } /** * @param entity the request entity * @return a list of {@link RequestResourceFilter} from the entity, or {@code null} * if none are defined */ public static List<RequestResourceFilter> filtersFromEntity (RequestEntity entity) { List<RequestResourceFilter> resourceFilters = null; Collection<RequestResourceFilterEntity> resourceFilterEntities = entity.getResourceFilterEntities(); if (resourceFilterEntities != null) { resourceFilters = new ArrayList<>(); for (RequestResourceFilterEntity resourceFilterEntity : resourceFilterEntities) { RequestResourceFilter resourceFilter = new RequestResourceFilter( resourceFilterEntity.getServiceName(), resourceFilterEntity.getComponentName(), getHostsList(resourceFilterEntity.getHosts())); resourceFilters.add(resourceFilter); } } return resourceFilters; } /** * @param entity the request entity * @return the {@link RequestOperationLevel} from the entity, or {@code null} * if none is defined */ public static RequestOperationLevel operationLevelFromEntity(RequestEntity entity) { RequestOperationLevel level = null; RequestOperationLevelEntity operationLevelEntity = entity.getRequestOperationLevel(); if (operationLevelEntity != null) { String hostName = null; if (operationLevelEntity.getHostId() != null) { HostEntity hostEntity = hostDAO.findById(operationLevelEntity.getHostId()); hostName = hostEntity.getHostName(); } level = new RequestOperationLevel( Resource.Type.valueOf(operationLevelEntity.getLevel()), operationLevelEntity.getClusterName(), operationLevelEntity.getServiceName(), operationLevelEntity.getHostComponentName(), hostName); } return level; } }