| /** |
| * 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; |
| |
| import com.google.gson.Gson; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.Singleton; |
| import com.google.inject.persist.Transactional; |
| import org.apache.ambari.server.AmbariException; |
| import org.apache.ambari.server.ClusterNotFoundException; |
| import org.apache.ambari.server.DuplicateResourceException; |
| import org.apache.ambari.server.HostNotFoundException; |
| import org.apache.ambari.server.ObjectNotFoundException; |
| import org.apache.ambari.server.ParentObjectNotFoundException; |
| import org.apache.ambari.server.Role; |
| import org.apache.ambari.server.RoleCommand; |
| import org.apache.ambari.server.ServiceComponentHostNotFoundException; |
| import org.apache.ambari.server.ServiceComponentNotFoundException; |
| import org.apache.ambari.server.ServiceNotFoundException; |
| import org.apache.ambari.server.StackAccessException; |
| import org.apache.ambari.server.actionmanager.ActionManager; |
| import org.apache.ambari.server.actionmanager.HostRoleCommand; |
| import org.apache.ambari.server.actionmanager.Stage; |
| import org.apache.ambari.server.actionmanager.StageFactory; |
| import org.apache.ambari.server.agent.ExecutionCommand; |
| import org.apache.ambari.server.api.services.AmbariMetaInfo; |
| import org.apache.ambari.server.configuration.Configuration; |
| import org.apache.ambari.server.controller.internal.URLStreamProvider; |
| import org.apache.ambari.server.metadata.ActionMetadata; |
| import org.apache.ambari.server.metadata.RoleCommandOrder; |
| import org.apache.ambari.server.security.authorization.AuthorizationHelper; |
| import org.apache.ambari.server.security.authorization.User; |
| import org.apache.ambari.server.security.authorization.Users; |
| import org.apache.ambari.server.stageplanner.RoleGraph; |
| import org.apache.ambari.server.state.Cluster; |
| import org.apache.ambari.server.state.Clusters; |
| import org.apache.ambari.server.state.ComponentInfo; |
| import org.apache.ambari.server.state.Config; |
| import org.apache.ambari.server.state.ConfigFactory; |
| import org.apache.ambari.server.state.ConfigHelper; |
| import org.apache.ambari.server.state.Host; |
| import org.apache.ambari.server.state.HostState; |
| import org.apache.ambari.server.state.OperatingSystemInfo; |
| import org.apache.ambari.server.state.PropertyInfo; |
| import org.apache.ambari.server.state.RepositoryInfo; |
| import org.apache.ambari.server.state.Service; |
| import org.apache.ambari.server.state.ServiceComponent; |
| import org.apache.ambari.server.state.ServiceComponentFactory; |
| import org.apache.ambari.server.state.ServiceComponentHost; |
| import org.apache.ambari.server.state.ServiceComponentHostEvent; |
| import org.apache.ambari.server.state.ServiceComponentHostFactory; |
| import org.apache.ambari.server.state.ServiceFactory; |
| 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.State; |
| import org.apache.ambari.server.state.configgroup.ConfigGroupFactory; |
| import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostMaintenanceEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostRestoreEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent; |
| import org.apache.ambari.server.state.svccomphost.ServiceComponentHostUpgradeEvent; |
| import org.apache.ambari.server.utils.StageUtils; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.http.client.utils.URIBuilder; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.TreeMap; |
| |
| @Singleton |
| public class AmbariManagementControllerImpl implements |
| AmbariManagementController { |
| |
| private final static Logger LOG = |
| LoggerFactory.getLogger(AmbariManagementControllerImpl.class); |
| |
| /** |
| * Property name of request context. |
| */ |
| private static final String REQUEST_CONTEXT_PROPERTY = "context"; |
| |
| private static final String BASE_LOG_DIR = "/tmp/ambari"; |
| |
| private final Clusters clusters; |
| |
| private final ActionManager actionManager; |
| |
| @SuppressWarnings("unused") |
| private final Injector injector; |
| |
| private final Gson gson; |
| |
| @Inject |
| private ServiceFactory serviceFactory; |
| @Inject |
| private ServiceComponentFactory serviceComponentFactory; |
| @Inject |
| private ServiceComponentHostFactory serviceComponentHostFactory; |
| @Inject |
| private ConfigFactory configFactory; |
| @Inject |
| private StageFactory stageFactory; |
| @Inject |
| private ActionMetadata actionMetadata; |
| @Inject |
| private AmbariMetaInfo ambariMetaInfo; |
| @Inject |
| private Users users; |
| @Inject |
| private HostsMap hostsMap; |
| @Inject |
| private Configuration configs; |
| @Inject |
| private AbstractRootServiceResponseFactory rootServiceResponseFactory; |
| @Inject |
| private ConfigGroupFactory configGroupFactory; |
| @Inject |
| private ConfigHelper configHelper; |
| |
| final private String masterHostname; |
| final private Integer masterPort; |
| final private String masterProtocol; |
| |
| final private static String JDK_RESOURCE_LOCATION = |
| "/resources/"; |
| |
| final private static int REPO_URL_CONNECT_TIMEOUT = 3000; |
| final private static int REPO_URL_READ_TIMEOUT = 500; |
| |
| final private String jdkResourceUrl; |
| final private String ojdbcUrl; |
| final private String serverDB; |
| final private String mysqljdbcUrl; |
| |
| final private AmbariCustomCommandExecutionHelper customCommandExecutionHelper; |
| final private AmbariActionExecutionHelper actionExecutionHelper; |
| |
| @Inject |
| public AmbariManagementControllerImpl(ActionManager actionManager, |
| Clusters clusters, Injector injector) throws Exception { |
| this.clusters = clusters; |
| this.actionManager = actionManager; |
| this.injector = injector; |
| injector.injectMembers(this); |
| this.gson = injector.getInstance(Gson.class); |
| LOG.info("Initializing the AmbariManagementControllerImpl"); |
| this.masterHostname = InetAddress.getLocalHost().getCanonicalHostName(); |
| |
| if(configs != null) |
| { |
| if (configs.getApiSSLAuthentication()) { |
| this.masterProtocol = "https"; |
| this.masterPort = configs.getClientSSLApiPort(); |
| } else { |
| this.masterProtocol = "http"; |
| this.masterPort = configs.getClientApiPort(); |
| } |
| this.jdkResourceUrl = getAmbariServerURI(JDK_RESOURCE_LOCATION); |
| this.ojdbcUrl = getAmbariServerURI(JDK_RESOURCE_LOCATION + "/" + configs.getOjdbcJarName()); |
| this.mysqljdbcUrl = getAmbariServerURI(JDK_RESOURCE_LOCATION + "/" + configs.getMySQLJarName()); |
| |
| this.serverDB = configs.getServerDBName(); |
| } else { |
| this.masterProtocol = null; |
| this.masterPort = null; |
| |
| this.jdkResourceUrl = null; |
| this.ojdbcUrl = null; |
| this.mysqljdbcUrl = null; |
| this.serverDB = null; |
| } |
| |
| this.customCommandExecutionHelper = new AmbariCustomCommandExecutionHelper( |
| this.actionMetadata, this.clusters, this); |
| this.actionExecutionHelper = new AmbariActionExecutionHelper( |
| this.actionMetadata, this.clusters, this); |
| } |
| |
| public String getAmbariServerURI(String path) { |
| if(masterProtocol==null || masterHostname==null || masterPort==null) |
| return null; |
| |
| URIBuilder uriBuilder = new URIBuilder(); |
| uriBuilder.setScheme(masterProtocol); |
| uriBuilder.setHost(masterHostname); |
| uriBuilder.setPort(masterPort); |
| uriBuilder.setPath(path); |
| |
| return uriBuilder.toString(); |
| } |
| |
| private RoleCommandOrder getRoleCommandOrder(Cluster cluster) { |
| RoleCommandOrder rco; |
| rco = injector.getInstance(RoleCommandOrder.class); |
| rco.initialize(cluster); |
| return rco; |
| } |
| |
| @Override |
| public void createCluster(ClusterRequest request) |
| throws AmbariException { |
| if (request.getClusterName() == null |
| || request.getClusterName().isEmpty() |
| || request.getClusterId() != null) { |
| throw new IllegalArgumentException("Cluster name should be provided" + |
| " and clusterId should be null"); |
| } |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a createCluster request" |
| + ", clusterName=" + request.getClusterName() |
| + ", request=" + request); |
| } |
| |
| if (request.getStackVersion() == null |
| || request.getStackVersion().isEmpty()) { |
| throw new IllegalArgumentException("Stack information should be" |
| + " provided when creating a cluster"); |
| } |
| StackId stackId = new StackId(request.getStackVersion()); |
| StackInfo stackInfo = ambariMetaInfo.getStackInfo(stackId.getStackName(), |
| stackId.getStackVersion()); |
| if (stackInfo == null) { |
| throw new StackAccessException("stackName=" + stackId.getStackName() + ", stackVersion=" + stackId.getStackVersion()); |
| } |
| |
| // FIXME add support for desired configs at cluster level |
| |
| boolean foundInvalidHosts = false; |
| StringBuilder invalidHostsStr = new StringBuilder(); |
| if (request.getHostNames() != null) { |
| for (String hostname : request.getHostNames()) { |
| try { |
| clusters.getHost(hostname); |
| } catch (HostNotFoundException e) { |
| if (foundInvalidHosts) { |
| invalidHostsStr.append(","); |
| } |
| foundInvalidHosts = true; |
| invalidHostsStr.append(hostname); |
| } |
| } |
| } |
| if (foundInvalidHosts) { |
| throw new HostNotFoundException(invalidHostsStr.toString()); |
| } |
| |
| clusters.addCluster(request.getClusterName()); |
| Cluster c = clusters.getCluster(request.getClusterName()); |
| if (request.getStackVersion() != null) { |
| StackId newStackId = new StackId(request.getStackVersion()); |
| c.setDesiredStackVersion(newStackId); |
| clusters.setCurrentStackVersion(request.getClusterName(), newStackId); |
| } |
| |
| if (request.getHostNames() != null) { |
| clusters.mapHostsToCluster(request.getHostNames(), |
| request.getClusterName()); |
| } |
| |
| } |
| |
| @Override |
| public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests) |
| throws AmbariException { |
| |
| if (requests.isEmpty()) { |
| LOG.warn("Received an empty requests set"); |
| return; |
| } |
| |
| // do all validation checks |
| Map<String, Map<String, Map<String, Set<String>>>> hostComponentNames = |
| new HashMap<String, Map<String, Map<String, Set<String>>>>(); |
| Set<String> duplicates = new HashSet<String>(); |
| for (ServiceComponentHostRequest request : requests) { |
| validateServiceComponentHostRequest(request); |
| |
| Cluster cluster; |
| try { |
| cluster = clusters.getCluster(request.getClusterName()); |
| } catch (ClusterNotFoundException e) { |
| throw new ParentObjectNotFoundException( |
| "Attempted to add a host_component to a cluster which doesn't exist: ", e); |
| } |
| |
| if (StringUtils.isEmpty(request.getServiceName())) { |
| request.setServiceName(findServiceName(cluster, request.getComponentName())); |
| } |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a createHostComponent request" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + request.getServiceName() |
| + ", componentName=" + request.getComponentName() |
| + ", hostname=" + request.getHostname() |
| + ", request=" + request); |
| } |
| |
| if (!hostComponentNames.containsKey(request.getClusterName())) { |
| hostComponentNames.put(request.getClusterName(), |
| new HashMap<String, Map<String,Set<String>>>()); |
| } |
| if (!hostComponentNames.get(request.getClusterName()) |
| .containsKey(request.getServiceName())) { |
| hostComponentNames.get(request.getClusterName()).put( |
| request.getServiceName(), new HashMap<String, Set<String>>()); |
| } |
| if (!hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()) |
| .containsKey(request.getComponentName())) { |
| hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).put(request.getComponentName(), |
| new HashSet<String>()); |
| } |
| if (hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).get(request.getComponentName()) |
| .contains(request.getHostname())) { |
| duplicates.add("[clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname() + |
| ", componentName=" +request.getComponentName() +']'); |
| continue; |
| } |
| hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).get(request.getComponentName()) |
| .add(request.getHostname()); |
| |
| if (request.getDesiredState() != null |
| && !request.getDesiredState().isEmpty()) { |
| State state = State.valueOf(request.getDesiredState()); |
| if (!state.isValidDesiredState() |
| || state != State.INIT) { |
| throw new IllegalArgumentException("Invalid desired state" |
| + " only INIT state allowed during creation" |
| + ", providedDesiredState=" + request.getDesiredState()); |
| } |
| } |
| |
| Service s; |
| try { |
| s = cluster.getService(request.getServiceName()); |
| } catch (ServiceNotFoundException e) { |
| throw new IllegalArgumentException( |
| "The service[" + request.getServiceName() + "] associated with the component[" + |
| request.getComponentName() + "] doesn't exist for the cluster[" + request.getClusterName() + "]"); |
| } |
| ServiceComponent sc = s.getServiceComponent( |
| request.getComponentName()); |
| |
| Host host; |
| try { |
| host = clusters.getHost(request.getHostname()); |
| } catch (HostNotFoundException e) { |
| throw new ParentObjectNotFoundException( |
| "Attempted to add a host_component to a host that doesn't exist: ", e); |
| } |
| Set<Cluster> mappedClusters = |
| clusters.getClustersForHost(request.getHostname()); |
| boolean validCluster = false; |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Looking to match host to cluster" |
| + ", hostnameViaReg=" + host.getHostName() |
| + ", hostname=" + request.getHostname() |
| + ", clusterName=" + request.getClusterName() |
| + ", hostClusterMapCount=" + mappedClusters.size()); |
| } |
| for (Cluster mappedCluster : mappedClusters) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Host belongs to cluster" |
| + ", hostname=" + request.getHostname() |
| + ", clusterName=" + mappedCluster.getClusterName()); |
| } |
| if (mappedCluster.getClusterName().equals( |
| request.getClusterName())) { |
| validCluster = true; |
| break; |
| } |
| } |
| if (!validCluster) { |
| throw new ParentObjectNotFoundException("Attempted to add a host_component to a host that doesn't exist: " + |
| "clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname()); |
| } |
| try { |
| ServiceComponentHost sch = sc.getServiceComponentHost( |
| request.getHostname()); |
| if (sch != null) { |
| duplicates.add("[clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname() + |
| ", componentName=" +request.getComponentName() +']'); |
| } |
| } catch (AmbariException e) { |
| // Expected |
| } |
| } |
| |
| // ensure only a single cluster update |
| if (hostComponentNames.size() != 1) { |
| throw new IllegalArgumentException("Invalid arguments - updates allowed" |
| + " on only one cluster at a time"); |
| } |
| |
| if (!duplicates.isEmpty()) { |
| StringBuilder names = new StringBuilder(); |
| boolean first = true; |
| for (String hName : duplicates) { |
| if (!first) { |
| names.append(","); |
| } |
| first = false; |
| names.append(hName); |
| } |
| String msg; |
| if (duplicates.size() == 1) { |
| msg = "Attempted to create a host_component which already exists: "; |
| } else { |
| msg = "Attempted to create host_component's which already exist: "; |
| } |
| throw new DuplicateResourceException(msg + names.toString()); |
| } |
| |
| // now doing actual work |
| for (ServiceComponentHostRequest request : requests) { |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| Service s = cluster.getService(request.getServiceName()); |
| ServiceComponent sc = s.getServiceComponent( |
| request.getComponentName()); |
| |
| StackId stackId = sc.getDesiredStackVersion(); |
| ComponentInfo compInfo = ambariMetaInfo.getComponentCategory( |
| stackId.getStackName(), stackId.getStackVersion(), |
| s.getName(), sc.getName()); |
| boolean isClient = compInfo.isClient(); |
| |
| ServiceComponentHost sch = |
| serviceComponentHostFactory.createNew(sc, request.getHostname(), |
| isClient); |
| |
| if (request.getDesiredState() != null |
| && !request.getDesiredState().isEmpty()) { |
| State state = State.valueOf(request.getDesiredState()); |
| sch.setDesiredState(state); |
| } |
| |
| sch.setDesiredStackVersion(sc.getDesiredStackVersion()); |
| |
| sc.addServiceComponentHost(sch); |
| sch.persist(); |
| } |
| } |
| |
| @Override |
| public synchronized void createConfiguration( |
| ConfigurationRequest request) throws AmbariException { |
| if (null == request.getClusterName() || request.getClusterName().isEmpty() |
| || null == request.getType() || request.getType().isEmpty() |
| || null == request.getVersionTag() || request.getVersionTag().isEmpty() |
| || null == request.getProperties() || request.getProperties().isEmpty()) { |
| throw new IllegalArgumentException("Invalid Arguments," |
| + " clustername, config type, config version and configs should not" |
| + " be null or empty"); |
| } |
| |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| Map<String, Config> configs = cluster.getConfigsByType( |
| request.getType()); |
| if (null == configs) { |
| configs = new HashMap<String, Config>(); |
| } |
| |
| if (configs.containsKey(request.getVersionTag())) { |
| throw new AmbariException(MessageFormat.format("Configuration with tag ''{0}'' exists for ''{1}''", |
| request.getVersionTag(), |
| request.getType())); |
| } |
| |
| Config config = configFactory.createNew (cluster, request.getType(), |
| request.getProperties()); |
| config.setVersionTag(request.getVersionTag()); |
| |
| config.persist(); |
| |
| cluster.addConfig(config); |
| } |
| |
| @Override |
| public void createUsers(Set<UserRequest> requests) throws AmbariException { |
| |
| for (UserRequest request : requests) { |
| |
| if (null == request.getUsername() || request.getUsername().isEmpty() || |
| null == request.getPassword() || request.getPassword().isEmpty()) { |
| throw new AmbariException("Username and password must be supplied."); |
| } |
| |
| User user = users.getAnyUser(request.getUsername()); |
| if (null != user) |
| throw new AmbariException("User already exists."); |
| |
| users.createUser(request.getUsername(), request.getPassword()); |
| |
| if (0 != request.getRoles().size()) { |
| user = users.getAnyUser(request.getUsername()); |
| if (null != user) { |
| for (String role : request.getRoles()) { |
| if (!user.getRoles().contains(role)) |
| users.addRoleToUser(user, role); |
| } |
| } |
| } |
| } |
| } |
| |
| private Stage createNewStage(Cluster cluster, long requestId, String requestContext, String clusterHostInfo) { |
| String logDir = BASE_LOG_DIR + File.pathSeparator + requestId; |
| return stageFactory.createNew(requestId, logDir, cluster.getClusterName(), requestContext, clusterHostInfo); |
| } |
| |
| private void createHostAction(Cluster cluster, |
| Stage stage, ServiceComponentHost scHost, |
| Map<String, Map<String, String>> configurations, |
| Map<String, Map<String, String>> configTags, |
| RoleCommand command, |
| Map<String, String> commandParams, |
| ServiceComponentHostEvent event) throws AmbariException { |
| |
| stage.addHostRoleExecutionCommand(scHost.getHostName(), Role.valueOf(scHost |
| .getServiceComponentName()), command, |
| event, scHost.getClusterName(), |
| scHost.getServiceName()); |
| ExecutionCommand execCmd = stage.getExecutionCommandWrapper(scHost.getHostName(), |
| scHost.getServiceComponentName()).getExecutionCommand(); |
| |
| Host host = clusters.getHost(scHost.getHostName()); |
| |
| // Hack - Remove passwords from configs |
| if (event.getServiceComponentName().equals(Role.HIVE_CLIENT.toString())) { |
| configHelper.applyCustomConfig(configurations, Configuration.HIVE_CONFIG_TAG, |
| Configuration.HIVE_METASTORE_PASSWORD_PROPERTY, "", true); |
| } |
| |
| execCmd.setConfigurations(configurations); |
| execCmd.setConfigurationTags(configTags); |
| execCmd.setCommandParams(commandParams); |
| |
| // send stack info to agent |
| StackId stackId = scHost.getDesiredStackVersion(); |
| Map<String, List<RepositoryInfo>> repos = ambariMetaInfo.getRepository( |
| stackId.getStackName(), stackId.getStackVersion()); |
| String repoInfo = ""; |
| if (!repos.containsKey(host.getOsType())) { |
| // FIXME should this be an error? |
| LOG.warn("Could not retrieve repo information for host" |
| + ", hostname=" + scHost.getHostName() |
| + ", clusterName=" + cluster.getClusterName() |
| + ", stackInfo=" + stackId.getStackId()); |
| } else { |
| repoInfo = gson.toJson(repos.get(host.getOsType())); |
| } |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Sending repo information to agent" |
| + ", hostname=" + scHost.getHostName() |
| + ", clusterName=" + cluster.getClusterName() |
| + ", stackInfo=" + stackId.getStackId() |
| + ", repoInfo=" + repoInfo); |
| } |
| |
| Map<String, String> params = new TreeMap<String, String>(); |
| params.put("repo_info", repoInfo); |
| params.put("jdk_location", jdkResourceUrl); |
| params.put("stack_version", stackId.getStackVersion()); |
| params.put("db_name", serverDB); |
| params.put("mysql_jdbc_url" , mysqljdbcUrl); |
| params.put("oracle_jdbc_url", ojdbcUrl); |
| |
| if (configs.getServerDBName().equalsIgnoreCase(Configuration |
| .ORACLE_DB_NAME)) { |
| params.put("db_driver_filename", configs.getOjdbcJarName()); |
| } else if (configs.getServerDBName().equalsIgnoreCase(Configuration |
| .MYSQL_DB_NAME)) { |
| params.put("db_driver_filename", configs.getMySQLJarName()); |
| } |
| execCmd.setHostLevelParams(params); |
| |
| Map<String, String> roleParams = new TreeMap<String, String>(); |
| execCmd.setRoleParams(roleParams); |
| } |
| |
| private synchronized Set<ClusterResponse> getClusters(ClusterRequest request) |
| throws AmbariException { |
| |
| Set<ClusterResponse> response = new HashSet<ClusterResponse>(); |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a getClusters request" |
| + ", clusterName=" + request.getClusterName() |
| + ", clusterId=" + request.getClusterId() |
| + ", stackInfo=" + request.getStackVersion()); |
| } |
| |
| if (request.getClusterName() != null) { |
| Cluster c = clusters.getCluster(request.getClusterName()); |
| ClusterResponse cr = c.convertToResponse(); |
| cr.setDesiredConfigs(c.getDesiredConfigs()); |
| response.add(cr); |
| return response; |
| } else if (request.getClusterId() != null) { |
| Cluster c = clusters.getClusterById(request.getClusterId()); |
| ClusterResponse cr = c.convertToResponse(); |
| cr.setDesiredConfigs(c.getDesiredConfigs()); |
| response.add(cr); |
| return response; |
| } |
| |
| Map<String, Cluster> allClusters = clusters.getClusters(); |
| for (Cluster c : allClusters.values()) { |
| if (request.getStackVersion() != null) { |
| if (!request.getStackVersion().equals( |
| c.getDesiredStackVersion().getStackId())) { |
| // skip non matching stack versions |
| continue; |
| } |
| } |
| response.add(c.convertToResponse()); |
| } |
| StringBuilder builder = new StringBuilder(); |
| if (LOG.isDebugEnabled()) { |
| clusters.debugDump(builder); |
| LOG.debug("Cluster State for cluster " + builder.toString()); |
| } |
| return response; |
| } |
| |
| private synchronized Set<ServiceComponentHostResponse> getHostComponents( |
| ServiceComponentHostRequest request) throws AmbariException { |
| if (request.getClusterName() == null |
| || request.getClusterName().isEmpty()) { |
| throw new IllegalArgumentException("Invalid arguments, cluster name should not be null"); |
| } |
| |
| final Cluster cluster; |
| try { |
| cluster = clusters.getCluster(request.getClusterName()); |
| } catch (ClusterNotFoundException e) { |
| throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e); |
| } |
| |
| if (request.getHostname() != null) { |
| try { |
| if (! clusters.getClustersForHost(request.getHostname()).contains(cluster)) { |
| // case where host exists but not associated with given cluster |
| throw new ParentObjectNotFoundException("Parent Host resource doesn't exist", |
| new HostNotFoundException(request.getClusterName(), request.getHostname())); |
| } |
| } catch (HostNotFoundException e) { |
| // creating new HostNotFoundException to add cluster name |
| throw new ParentObjectNotFoundException("Parent Host resource doesn't exist", |
| new HostNotFoundException(request.getClusterName(), request.getHostname())); |
| } |
| } |
| |
| if (request.getComponentName() != null) { |
| if (request.getServiceName() == null |
| || request.getServiceName().isEmpty()) { |
| StackId stackId = cluster.getDesiredStackVersion(); |
| String serviceName = |
| ambariMetaInfo.getComponentToService(stackId.getStackName(), |
| stackId.getStackVersion(), request.getComponentName()); |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Looking up service name for component" |
| + ", componentName=" + request.getComponentName() |
| + ", serviceName=" + serviceName |
| + ", stackInfo=" + stackId.getStackId()); |
| } |
| if (serviceName == null |
| || serviceName.isEmpty()) { |
| throw new ServiceComponentHostNotFoundException( |
| cluster.getClusterName(), null, request.getComponentName(),request.getHostname()); |
| } |
| request.setServiceName(serviceName); |
| } |
| } |
| |
| Set<Service> services = new HashSet<Service>(); |
| if (request.getServiceName() != null && !request.getServiceName().isEmpty()) { |
| services.add(cluster.getService(request.getServiceName())); |
| } else { |
| services.addAll(cluster.getServices().values()); |
| } |
| |
| Set<ServiceComponentHostResponse> response = |
| new HashSet<ServiceComponentHostResponse>(); |
| |
| boolean checkDesiredState = false; |
| State desiredStateToCheck = null; |
| if (request.getDesiredState() != null |
| && !request.getDesiredState().isEmpty()) { |
| desiredStateToCheck = State.valueOf(request.getDesiredState()); |
| if (!desiredStateToCheck.isValidDesiredState()) { |
| throw new IllegalArgumentException("Invalid arguments, invalid desired" |
| + " state, desiredState=" + desiredStateToCheck); |
| } |
| checkDesiredState = true; |
| } |
| |
| for (Service s : services) { |
| // filter on component name if provided |
| Set<ServiceComponent> components = new HashSet<ServiceComponent>(); |
| if (request.getComponentName() != null) { |
| components.add(s.getServiceComponent(request.getComponentName())); |
| } else { |
| components.addAll(s.getServiceComponents().values()); |
| } |
| for(ServiceComponent sc : components) { |
| if (request.getComponentName() != null) { |
| if (!sc.getName().equals(request.getComponentName())) { |
| continue; |
| } |
| } |
| |
| // filter on hostname if provided |
| // filter on desired state if provided |
| |
| if (request.getHostname() != null) { |
| try { |
| ServiceComponentHost sch = sc.getServiceComponentHost( |
| request.getHostname()); |
| if (checkDesiredState |
| && (desiredStateToCheck != sch.getDesiredState())) { |
| continue; |
| } |
| ServiceComponentHostResponse r = sch.convertToResponse(); |
| response.add(r); |
| } catch (ServiceComponentHostNotFoundException e) { |
| if (request.getServiceName() != null && request.getComponentName() != null) { |
| throw new ServiceComponentHostNotFoundException(cluster.getClusterName(), |
| request.getServiceName(), request.getComponentName(),request.getHostname()); |
| } else { |
| // ignore this since host_component was not specified |
| // this is an artifact of how we get host_components and can happen |
| // in case where we get all host_components for a host |
| } |
| |
| } |
| } else { |
| for (ServiceComponentHost sch : |
| sc.getServiceComponentHosts().values()) { |
| if (checkDesiredState |
| && (desiredStateToCheck != sch.getDesiredState())) { |
| continue; |
| } |
| ServiceComponentHostResponse r = sch.convertToResponse(); |
| response.add(r); |
| } |
| } |
| } |
| } |
| return response; |
| } |
| |
| |
| private synchronized Set<ConfigurationResponse> getConfigurations( |
| ConfigurationRequest request) throws AmbariException { |
| if (request.getClusterName() == null) { |
| throw new IllegalArgumentException("Invalid arguments, cluster name" |
| + " should not be null"); |
| } |
| |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| Set<ConfigurationResponse> responses = new HashSet<ConfigurationResponse>(); |
| |
| // !!! if only one, then we need full properties |
| if (null != request.getType() && null != request.getVersionTag()) { |
| Config config = cluster.getConfig(request.getType(), |
| request.getVersionTag()); |
| if (null != config) { |
| ConfigurationResponse response = new ConfigurationResponse( |
| cluster.getClusterName(), config.getType(), config.getVersionTag(), |
| config.getProperties()); |
| responses.add(response); |
| } |
| } |
| else { |
| if (null != request.getType()) { |
| Map<String, Config> configs = cluster.getConfigsByType( |
| request.getType()); |
| |
| if (null != configs) { |
| for (Entry<String, Config> entry : configs.entrySet()) { |
| ConfigurationResponse response = new ConfigurationResponse( |
| cluster.getClusterName(), request.getType(), |
| entry.getValue().getVersionTag(), new HashMap<String, String>()); |
| responses.add(response); |
| } |
| } |
| } else { |
| // !!! all configuration |
| Collection<Config> all = cluster.getAllConfigs(); |
| |
| for (Config config : all) { |
| ConfigurationResponse response = new ConfigurationResponse( |
| cluster.getClusterName(), config.getType(), config.getVersionTag(), |
| new HashMap<String, String>()); |
| |
| responses.add(response); |
| } |
| } |
| } |
| |
| return responses; |
| |
| } |
| |
| @Override |
| public synchronized RequestStatusResponse updateClusters(Set<ClusterRequest> requests, |
| Map<String, String> requestProperties) |
| throws AmbariException { |
| |
| RequestStatusResponse response = null; |
| |
| // We have to allow for multiple requests to account for multiple |
| // configuration updates (create multiple configuration resources)... |
| for (ClusterRequest request : requests) { |
| // TODO : Is there ever a real world case where we could have multiple non-null responses? |
| response = updateCluster(request); |
| } |
| return response; |
| } |
| |
| private synchronized RequestStatusResponse updateCluster(ClusterRequest request) |
| throws AmbariException { |
| |
| if (request.getClusterName() == null |
| || request.getClusterName().isEmpty()) { |
| throw new IllegalArgumentException("Invalid arguments, cluster name" |
| + " should not be null"); |
| } |
| |
| LOG.info("Received a updateCluster request" |
| + ", clusterName=" + request.getClusterName() |
| + ", request=" + request); |
| |
| final Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| // set or create configuration mapping (and optionally create the map of properties) |
| if (null != request.getDesiredConfig()) { |
| ConfigurationRequest cr = request.getDesiredConfig(); |
| |
| if (null != cr.getProperties() && cr.getProperties().size() > 0) { |
| LOG.info(MessageFormat.format("Applying configuration with tag ''{0}'' to cluster ''{1}''", |
| cr.getVersionTag(), |
| request.getClusterName())); |
| |
| cr.setClusterName(cluster.getClusterName()); |
| createConfiguration(cr); |
| } |
| |
| Config baseConfig = cluster.getConfig(cr.getType(), cr.getVersionTag()); |
| if (null != baseConfig) { |
| Config oldConfig = cluster.getDesiredConfigByType(cr.getType()); |
| String authName = getAuthName(); |
| if (cluster.addDesiredConfig(authName, baseConfig)) { |
| Logger logger = LoggerFactory.getLogger("configchange"); |
| logger.info("cluster '" + request.getClusterName() + "' " |
| + "changed by: '" + authName + "'; " |
| + "type='" + baseConfig.getType() + "' " |
| + "tag='" + baseConfig.getVersionTag() + "'" |
| + (null == oldConfig ? "" : " from='"+ oldConfig.getVersionTag() + "'")); |
| } |
| } |
| } |
| |
| StackId currentVersion = cluster.getCurrentStackVersion(); |
| StackId desiredVersion = cluster.getDesiredStackVersion(); |
| |
| // Set the current version value if its not already set |
| if (currentVersion == null) { |
| cluster.setCurrentStackVersion(desiredVersion); |
| } |
| |
| boolean requiresHostListUpdate = |
| request.getHostNames() != null && !request.getHostNames().isEmpty(); |
| |
| if (requiresHostListUpdate) { |
| clusters.mapHostsToCluster( |
| request.getHostNames(), request.getClusterName()); |
| } |
| |
| return null; |
| } |
| |
| private String getJobTrackerHost(Cluster cluster) { |
| try { |
| Service svc = cluster.getService("MAPREDUCE"); |
| ServiceComponent sc = svc.getServiceComponent(Role.JOBTRACKER.toString()); |
| if (sc.getServiceComponentHosts() != null |
| && !sc.getServiceComponentHosts().isEmpty()) { |
| return sc.getServiceComponentHosts().keySet().iterator().next(); |
| } |
| } catch (AmbariException ex) { |
| return null; |
| } |
| return null; |
| } |
| |
| private Set<String> getServicesForSmokeTests(Cluster cluster, |
| Map<State, List<Service>> changedServices, |
| Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts, |
| boolean runSmokeTest) throws AmbariException { |
| |
| Set<String> smokeTestServices = new HashSet<String>(); |
| |
| if (changedServices != null) { |
| for (Entry<State, List<Service>> entry : changedServices.entrySet()) { |
| if (State.STARTED != entry.getKey()) { |
| continue; |
| } |
| for (Service s : entry.getValue()) { |
| if (runSmokeTest && (State.INSTALLED == s.getDesiredState())) { |
| smokeTestServices.add(s.getName()); |
| } |
| } |
| } |
| } |
| |
| Map<String, Map<String, Integer>> changedComponentCount = |
| new HashMap<String, Map<String, Integer>>(); |
| for (Map<State, List<ServiceComponentHost>> stateScHostMap : |
| changedScHosts.values()) { |
| for (Entry<State, List<ServiceComponentHost>> entry : |
| stateScHostMap.entrySet()) { |
| if (State.STARTED != entry.getKey()) { |
| continue; |
| } |
| for (ServiceComponentHost sch : entry.getValue()) { |
| if (State.INSTALLED != sch.getState()) { |
| continue; |
| } |
| if (!changedComponentCount.containsKey(sch.getServiceName())) { |
| changedComponentCount.put(sch.getServiceName(), |
| new HashMap<String, Integer>()); |
| } |
| if (!changedComponentCount.get(sch.getServiceName()) |
| .containsKey(sch.getServiceComponentName())) { |
| changedComponentCount.get(sch.getServiceName()) |
| .put(sch.getServiceComponentName(), 1); |
| } else { |
| Integer i = changedComponentCount.get(sch.getServiceName()) |
| .get(sch.getServiceComponentName()); |
| changedComponentCount.get(sch.getServiceName()) |
| .put(sch.getServiceComponentName(), ++i); |
| } |
| } |
| } |
| } |
| |
| for (Entry<String, Map<String, Integer>> entry : |
| changedComponentCount.entrySet()) { |
| String serviceName = entry.getKey(); |
| // smoke test service if more than one component is started |
| if (runSmokeTest && (entry.getValue().size() > 1)) { |
| smokeTestServices.add(serviceName); |
| continue; |
| } |
| for (String componentName : |
| changedComponentCount.get(serviceName).keySet()) { |
| ServiceComponent sc = cluster.getService(serviceName) |
| .getServiceComponent(componentName); |
| StackId stackId = sc.getDesiredStackVersion(); |
| ComponentInfo compInfo = ambariMetaInfo.getComponentCategory( |
| stackId.getStackName(), stackId.getStackVersion(), serviceName, |
| componentName); |
| if (runSmokeTest && compInfo.isMaster()) { |
| smokeTestServices.add(serviceName); |
| } |
| |
| // FIXME if master check if we need to run a smoke test for the master |
| } |
| } |
| return smokeTestServices; |
| } |
| |
| private void addClientSchForReinstall(Cluster cluster, |
| Map<State, List<Service>> changedServices, |
| Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts) |
| throws AmbariException { |
| |
| Set<String> services = new HashSet<String>(); |
| |
| if (changedServices != null) { |
| for (Entry<State, List<Service>> entry : changedServices.entrySet()) { |
| if (State.STARTED != entry.getKey()) { |
| continue; |
| } |
| for (Service s : entry.getValue()) { |
| if (State.INSTALLED == s.getDesiredState()) { |
| services.add(s.getName()); |
| } |
| } |
| } |
| } |
| |
| // Flatten changed Schs that are going to be Started |
| List<ServiceComponentHost> serviceComponentHosts = new |
| ArrayList<ServiceComponentHost>(); |
| if (changedScHosts != null && !changedScHosts.isEmpty()) { |
| for (String sc : changedScHosts.keySet()) { |
| for (State s : changedScHosts.get(sc).keySet()) |
| if (s == State.STARTED) { |
| serviceComponentHosts.addAll(changedScHosts.get(sc).get(s)); |
| } |
| } |
| } |
| |
| if (!serviceComponentHosts.isEmpty()) { |
| for (ServiceComponentHost sch : serviceComponentHosts) { |
| services.add(sch.getServiceName()); |
| } |
| } |
| |
| if (services.isEmpty()) |
| return; |
| |
| Map<String, List<ServiceComponentHost>> clientSchs = new |
| HashMap<String, List<ServiceComponentHost>>(); |
| |
| for (String serviceName : services) { |
| Service s = cluster.getService(serviceName); |
| for (String component : s.getServiceComponents().keySet()) { |
| List<ServiceComponentHost> potentialHosts = new |
| ArrayList<ServiceComponentHost>(); |
| ServiceComponent sc = s.getServiceComponents().get(component); |
| if (sc.isClientComponent()) { |
| for (ServiceComponentHost potentialSch : sc |
| .getServiceComponentHosts().values()) { |
| if (!potentialSch.getHostState().equals(HostState |
| .HEARTBEAT_LOST)) { |
| potentialHosts.add(potentialSch); |
| } |
| } |
| } |
| if (!potentialHosts.isEmpty()) { |
| clientSchs.put(sc.getName(), potentialHosts); |
| } |
| } |
| } |
| LOG.info("Client hosts for reinstall : " + clientSchs.size()); |
| |
| if (changedScHosts != null) { |
| for (String sc : clientSchs.keySet()) { |
| Map<State, List<ServiceComponentHost>> schMap = new |
| HashMap<State, List<ServiceComponentHost>>(); |
| schMap.put(State.INSTALLED, clientSchs.get(sc)); |
| changedScHosts.put(sc, schMap); |
| } |
| } |
| } |
| |
| /** |
| * Find configuration tags with applied overrides |
| * |
| * @param cluster the cluster |
| * @param hostName the host name |
| * |
| * @return the configuration tags |
| * |
| * @throws AmbariException if configuration tags can not be obtained |
| */ |
| protected Map<String, Map<String,String>> findConfigurationTagsWithOverrides( |
| Cluster cluster, String hostName) throws AmbariException { |
| |
| return configHelper.getEffectiveDesiredTags(cluster, hostName); |
| } |
| |
| private List<Stage> doStageCreation(Cluster cluster, |
| Map<State, List<Service>> changedServices, |
| Map<State, List<ServiceComponent>> changedComps, |
| Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts, |
| Map<String, String> requestParameters, String requestContext, |
| boolean runSmokeTest, boolean reconfigureClients) |
| throws AmbariException { |
| |
| |
| // TODO handle different transitions? |
| // Say HDFS to stopped and MR to started, what order should actions be done |
| // in? |
| |
| // TODO additional validation? |
| // verify all configs |
| // verify all required components |
| |
| if ((changedServices == null || changedServices.isEmpty()) |
| && (changedComps == null || changedComps.isEmpty()) |
| && (changedScHosts == null || changedScHosts.isEmpty())) { |
| return null; |
| } |
| |
| // smoke test any service that goes from installed to started |
| Set<String> smokeTestServices = getServicesForSmokeTests(cluster, |
| changedServices, changedScHosts, runSmokeTest); |
| |
| if (reconfigureClients) { |
| // Re-install client only hosts to reattach changed configs on service |
| // restart |
| addClientSchForReinstall(cluster, changedServices, changedScHosts); |
| } |
| |
| if (!changedScHosts.isEmpty() |
| || !smokeTestServices.isEmpty()) { |
| long nowTimestamp = System.currentTimeMillis(); |
| Long requestId = actionManager.getNextRequestId(); |
| |
| // FIXME cannot work with a single stage |
| // multiple stages may be needed for reconfigure |
| long stageId = 0; |
| Map<String, List<String>> clusterHostInfo = StageUtils.getClusterHostInfo( |
| clusters.getHostsForCluster(cluster.getClusterName()), cluster, hostsMap, injector.getInstance(Configuration.class)); |
| |
| |
| String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo); |
| |
| Stage stage = createNewStage(cluster, requestId, requestContext, clusterHostInfoJson); |
| stage.setStageId(stageId); |
| |
| //HACK |
| String jobtrackerHost = getJobTrackerHost(cluster); |
| for (String compName : changedScHosts.keySet()) { |
| for (State newState : changedScHosts.get(compName).keySet()) { |
| for (ServiceComponentHost scHost : |
| changedScHosts.get(compName).get(newState)) { |
| |
| // Do not create role command for hosts that are not responding |
| if (scHost.getHostState().equals(HostState.HEARTBEAT_LOST)) { |
| LOG.info("Command is not created for servicecomponenthost " |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + scHost.getServiceName() |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", hostState=" + scHost.getHostState() |
| + ", targetNewState=" + newState); |
| continue; |
| } |
| |
| RoleCommand roleCommand; |
| State oldSchState = scHost.getState(); |
| ServiceComponentHostEvent event; |
| switch (newState) { |
| case INSTALLED: |
| if (oldSchState == State.INIT |
| || oldSchState == State.UNINSTALLED |
| || oldSchState == State.INSTALLED |
| || oldSchState == State.INSTALLING |
| || oldSchState == State.UNKNOWN |
| || oldSchState == State.INSTALL_FAILED) { |
| roleCommand = RoleCommand.INSTALL; |
| event = new ServiceComponentHostInstallEvent( |
| scHost.getServiceComponentName(), scHost.getHostName(), |
| nowTimestamp, |
| scHost.getDesiredStackVersion().getStackId()); |
| } else if (oldSchState == State.STARTED |
| || oldSchState == State.INSTALLED |
| || oldSchState == State.STOPPING) { |
| roleCommand = RoleCommand.STOP; |
| event = new ServiceComponentHostStopEvent( |
| scHost.getServiceComponentName(), scHost.getHostName(), |
| nowTimestamp); |
| } else if (oldSchState == State.UPGRADING) { |
| roleCommand = RoleCommand.UPGRADE; |
| event = new ServiceComponentHostUpgradeEvent( |
| scHost.getServiceComponentName(), scHost.getHostName(), |
| nowTimestamp, scHost.getDesiredStackVersion().getStackId()); |
| } else { |
| throw new AmbariException("Invalid transition for" |
| + " servicecomponenthost" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + scHost.getServiceName() |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| break; |
| case STARTED: |
| StackId stackId = scHost.getDesiredStackVersion(); |
| ComponentInfo compInfo = ambariMetaInfo.getComponentCategory( |
| stackId.getStackName(), stackId.getStackVersion(), scHost.getServiceName(), |
| scHost.getServiceComponentName()); |
| if (oldSchState == State.INSTALLED |
| || oldSchState == State.STARTING) { |
| roleCommand = RoleCommand.START; |
| event = new ServiceComponentHostStartEvent( |
| scHost.getServiceComponentName(), scHost.getHostName(), |
| nowTimestamp); |
| } else { |
| String error = "Invalid transition for" |
| + " servicecomponenthost" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + scHost.getServiceName() |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState; |
| if (compInfo.isMaster()) { |
| throw new AmbariException(error); |
| } else { |
| LOG.info("Ignoring: " + error); |
| continue; |
| } |
| } |
| break; |
| case UNINSTALLED: |
| if (oldSchState == State.INSTALLED |
| || oldSchState == State.UNINSTALLING) { |
| roleCommand = RoleCommand.UNINSTALL; |
| event = new ServiceComponentHostStartEvent( |
| scHost.getServiceComponentName(), scHost.getHostName(), |
| nowTimestamp); |
| } else { |
| throw new AmbariException("Invalid transition for" |
| + " servicecomponenthost" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + scHost.getServiceName() |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| break; |
| case INIT: |
| throw new AmbariException("Unsupported transition to INIT for" |
| + " servicecomponenthost" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + scHost.getServiceName() |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| default: |
| throw new AmbariException("Unsupported state change operation" |
| + ", newState=" + newState.toString()); |
| } |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Create a new host action" |
| + ", requestId=" + requestId |
| + ", componentName=" + scHost.getServiceComponentName() |
| + ", hostname=" + scHost.getHostName() |
| + ", roleCommand=" + roleCommand.name()); |
| } |
| |
| // [ type -> [ key, value ] ] |
| Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>(); |
| Host host = clusters.getHost(scHost.getHostName()); |
| |
| Map<String, Map<String, String>> configTags = |
| findConfigurationTagsWithOverrides(cluster, host.getHostName()); |
| |
| // HACK - Set configs on the ExecCmd |
| if (!scHost.getHostName().equals(jobtrackerHost)) { |
| if (configTags.get(Configuration.GLOBAL_CONFIG_TAG) != null) { |
| configHelper.applyCustomConfig( |
| configurations, Configuration.GLOBAL_CONFIG_TAG, |
| Configuration.RCA_ENABLED_PROPERTY, "false", false); |
| } |
| } |
| |
| createHostAction(cluster, stage, scHost, configurations, configTags, |
| roleCommand, requestParameters, event); |
| } |
| } |
| } |
| |
| for (String serviceName : smokeTestServices) { |
| Service s = cluster.getService(serviceName); |
| |
| // find service component host |
| String clientHost = getClientHostForRunningAction(cluster, s); |
| String smokeTestRole = |
| actionMetadata.getServiceCheckAction(serviceName); |
| |
| if (clientHost == null || smokeTestRole == null) { |
| LOG.info("Nothing to do for service check as could not find role or" |
| + " or host to run check on" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", serviceName=" + serviceName |
| + ", clientHost=" + clientHost |
| + ", serviceCheckRole=" + smokeTestRole); |
| continue; |
| } |
| |
| stage.addHostRoleExecutionCommand(clientHost, |
| Role.valueOf(smokeTestRole), |
| RoleCommand.EXECUTE, |
| new ServiceComponentHostOpInProgressEvent(null, clientHost, |
| nowTimestamp), cluster.getClusterName(), serviceName); |
| |
| // [ type -> [ key, value ] ] |
| Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String,String>>(); |
| Map<String, Map<String, String>> configTags = |
| findConfigurationTagsWithOverrides(cluster, clientHost); |
| |
| stage.getExecutionCommandWrapper(clientHost, |
| smokeTestRole).getExecutionCommand() |
| .setConfigurations(configurations); |
| |
| stage.getExecutionCommandWrapper(clientHost, |
| smokeTestRole).getExecutionCommand() |
| .setConfigurationTags(configTags); |
| |
| // Generate cluster host info |
| stage.getExecutionCommandWrapper(clientHost, smokeTestRole) |
| .getExecutionCommand() |
| .setClusterHostInfo(StageUtils.getClusterHostInfo( |
| clusters.getHostsForCluster(cluster.getClusterName()), cluster, hostsMap, |
| injector.getInstance(Configuration.class))); |
| |
| Map<String,String> hostParams = new HashMap<String, String>(); |
| hostParams.put("stack_version", cluster.getDesiredStackVersion().getStackVersion()); |
| // smoke tests need stack version |
| stage.getExecutionCommandWrapper(clientHost, |
| smokeTestRole).getExecutionCommand() |
| .setHostLevelParams(hostParams); |
| |
| } |
| |
| RoleCommandOrder rco = getRoleCommandOrder(cluster); |
| RoleGraph rg = new RoleGraph(rco); |
| rg.build(stage); |
| return rg.getStages(); |
| } |
| |
| return null; |
| } |
| |
| private void persistStages(List<Stage> stages) { |
| if(stages != null && stages.size() > 0) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Triggering Action Manager" |
| + ", clusterName=" + stages.get(0).getClusterName() |
| + ", requestId=" + stages.get(0).getRequestId() |
| + ", stagesCount=" + stages.size()); |
| } |
| actionManager.sendActions(stages, null); |
| } |
| } |
| |
| @Transactional |
| void updateServiceStates( |
| Map<State, List<Service>> changedServices, |
| Map<State, List<ServiceComponent>> changedComps, |
| Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts, |
| Collection<ServiceComponentHost> ignoredScHosts |
| ) { |
| if (changedServices != null) { |
| for (Entry<State, List<Service>> entry : changedServices.entrySet()) { |
| State newState = entry.getKey(); |
| for (Service s : entry.getValue()) { |
| if (s.isClientOnlyService() |
| && newState == State.STARTED) { |
| continue; |
| } |
| s.setDesiredState(newState); |
| } |
| } |
| } |
| |
| if (changedComps != null) { |
| for (Entry<State, List<ServiceComponent>> entry : |
| changedComps.entrySet()){ |
| State newState = entry.getKey(); |
| for (ServiceComponent sc : entry.getValue()) { |
| sc.setDesiredState(newState); |
| } |
| } |
| } |
| |
| for (Map<State, List<ServiceComponentHost>> stateScHostMap : |
| changedScHosts.values()) { |
| for (Entry<State, List<ServiceComponentHost>> entry : |
| stateScHostMap.entrySet()) { |
| State newState = entry.getKey(); |
| for (ServiceComponentHost sch : entry.getValue()) { |
| sch.setDesiredState(newState); |
| } |
| } |
| } |
| |
| if (ignoredScHosts != null) { |
| for (ServiceComponentHost scHost : ignoredScHosts) { |
| scHost.setDesiredState(scHost.getState()); |
| } |
| } |
| } |
| |
| @Override |
| public RequestStatusResponse createStages(Cluster cluster, Map<String, String> requestProperties, |
| Map<String, String> requestParameters, |
| Map<State, List<Service>> changedServices, |
| Map<State, List<ServiceComponent>> changedComponents, |
| Map<String, Map<State, List<ServiceComponentHost>>> changedHosts, |
| Collection<ServiceComponentHost> ignoredHosts, |
| boolean runSmokeTest, boolean reconfigureClients) throws AmbariException { |
| |
| List<Stage> stages = doStageCreation(cluster, changedServices, changedComponents, |
| changedHosts, requestParameters, requestProperties.get(REQUEST_CONTEXT_PROPERTY), |
| runSmokeTest, reconfigureClients); |
| |
| persistStages(stages); |
| |
| updateServiceStates(changedServices, changedComponents, changedHosts, ignoredHosts); |
| |
| return stages == null || stages.isEmpty() ? null : getRequestStatusResponse(stages.get(0).getRequestId()); |
| } |
| |
| @Override |
| public synchronized RequestStatusResponse updateHostComponents(Set<ServiceComponentHostRequest> requests, |
| Map<String, String> requestProperties, boolean runSmokeTest) |
| throws AmbariException { |
| |
| if (requests.isEmpty()) { |
| LOG.warn("Received an empty requests set"); |
| return null; |
| } |
| |
| Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts = |
| new HashMap<String, Map<State, List<ServiceComponentHost>>>(); |
| Collection<ServiceComponentHost> ignoredScHosts = |
| new ArrayList<ServiceComponentHost>(); |
| |
| Set<String> clusterNames = new HashSet<String>(); |
| Map<String, Map<String, Map<String, Set<String>>>> hostComponentNames = |
| new HashMap<String, Map<String, Map<String, Set<String>>>>(); |
| Set<State> seenNewStates = new HashSet<State>(); |
| Map<ServiceComponentHost, State> directTransitionScHosts = new HashMap<ServiceComponentHost, State>(); |
| for (ServiceComponentHostRequest request : requests) { |
| validateServiceComponentHostRequest(request); |
| |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| if (StringUtils.isEmpty(request.getServiceName())) { |
| request.setServiceName(findServiceName(cluster, request.getComponentName())); |
| } |
| |
| LOG.info("Received a updateHostComponent request" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + request.getServiceName() |
| + ", componentName=" + request.getComponentName() |
| + ", hostname=" + request.getHostname() |
| + ", request=" + request); |
| |
| clusterNames.add(request.getClusterName()); |
| |
| if (clusterNames.size() > 1) { |
| throw new IllegalArgumentException("Updates to multiple clusters is not" |
| + " supported"); |
| } |
| |
| if (!hostComponentNames.containsKey(request.getClusterName())) { |
| hostComponentNames.put(request.getClusterName(), |
| new HashMap<String, Map<String, Set<String>>>()); |
| } |
| if (!hostComponentNames.get(request.getClusterName()) |
| .containsKey(request.getServiceName())) { |
| hostComponentNames.get(request.getClusterName()).put( |
| request.getServiceName(), new HashMap<String, Set<String>>()); |
| } |
| if (!hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()) |
| .containsKey(request.getComponentName())) { |
| hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).put(request.getComponentName(), |
| new HashSet<String>()); |
| } |
| if (hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).get(request.getComponentName()) |
| .contains(request.getHostname())) { |
| throw new IllegalArgumentException("Invalid request contains duplicate" |
| + " hostcomponents"); |
| } |
| hostComponentNames.get(request.getClusterName()) |
| .get(request.getServiceName()).get(request.getComponentName()) |
| .add(request.getHostname()); |
| |
| Service s = cluster.getService(request.getServiceName()); |
| ServiceComponent sc = s.getServiceComponent( |
| request.getComponentName()); |
| ServiceComponentHost sch = sc.getServiceComponentHost( |
| request.getHostname()); |
| State oldState = sch.getState(); |
| State newState = null; |
| if (request.getDesiredState() != null) { |
| newState = State.valueOf(request.getDesiredState()); |
| if (!newState.isValidDesiredState()) { |
| throw new IllegalArgumentException("Invalid arguments, invalid" |
| + " desired state, desiredState=" + newState.toString()); |
| } |
| } |
| |
| if (newState == null) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Nothing to do for new updateServiceComponentHost request" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + request.getServiceName() |
| + ", componentName=" + request.getComponentName() |
| + ", hostname=" + request.getHostname() |
| + ", oldState=" + oldState |
| + ", newDesiredState=null"); |
| } |
| continue; |
| } |
| |
| if (sc.isClientComponent() && |
| !newState.isValidClientComponentState()) { |
| throw new IllegalArgumentException("Invalid desired state for a client" |
| + " component"); |
| } |
| |
| seenNewStates.add(newState); |
| |
| State oldSchState = sch.getState(); |
| // Client component reinstall allowed |
| if (newState == oldSchState && !sc.isClientComponent()) { |
| ignoredScHosts.add(sch); |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Ignoring ServiceComponentHost" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + s.getName() |
| + ", componentName=" + sc.getName() |
| + ", hostname=" + sch.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| continue; |
| } |
| |
| if (!State.isValidStateTransition(oldSchState, newState)) { |
| throw new AmbariException("Invalid transition for" |
| + " servicecomponenthost" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", clusterId=" + cluster.getClusterId() |
| + ", serviceName=" + sch.getServiceName() |
| + ", componentName=" + sch.getServiceComponentName() |
| + ", hostname=" + sch.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| |
| if (isDirectTransition(oldSchState, newState)) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Handling direct transition update to ServiceComponentHost" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + s.getName() |
| + ", componentName=" + sc.getName() |
| + ", hostname=" + sch.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| directTransitionScHosts.put(sch, newState); |
| } else { |
| if (!changedScHosts.containsKey(sc.getName())) { |
| changedScHosts.put(sc.getName(), |
| new HashMap<State, List<ServiceComponentHost>>()); |
| } |
| if (!changedScHosts.get(sc.getName()).containsKey(newState)) { |
| changedScHosts.get(sc.getName()).put(newState, |
| new ArrayList<ServiceComponentHost>()); |
| } |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Handling update to ServiceComponentHost" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + s.getName() |
| + ", componentName=" + sc.getName() |
| + ", hostname=" + sch.getHostName() |
| + ", currentState=" + oldSchState |
| + ", newDesiredState=" + newState); |
| } |
| changedScHosts.get(sc.getName()).get(newState).add(sch); |
| } |
| } |
| |
| if (seenNewStates.size() > 1) { |
| // FIXME should we handle this scenario |
| throw new IllegalArgumentException("Cannot handle different desired" |
| + " state changes for a set of service components at the same time"); |
| } |
| |
| // Perform direct transitions (without task generation) |
| for (Entry<ServiceComponentHost, State> entry : directTransitionScHosts.entrySet()) { |
| ServiceComponentHost componentHost = entry.getKey(); |
| State newState = entry.getValue(); |
| long timestamp = System.currentTimeMillis(); |
| ServiceComponentHostEvent event; |
| componentHost.setDesiredState(newState); |
| switch (newState) { |
| case MAINTENANCE: |
| event = new ServiceComponentHostMaintenanceEvent( |
| componentHost.getServiceComponentName(), |
| componentHost.getHostName(), |
| timestamp); |
| break; |
| case INSTALLED: |
| event = new ServiceComponentHostRestoreEvent( |
| componentHost.getServiceComponentName(), |
| componentHost.getHostName(), |
| timestamp); |
| break; |
| default: |
| throw new AmbariException("Direct transition from " + componentHost.getState() + " to " + newState + " not supported"); |
| } |
| try { |
| componentHost.handleEvent(event); |
| } catch (InvalidStateTransitionException e) { |
| //Should not occur, must be covered by previous checks |
| throw new AmbariException("Internal error - not supported transition", e); |
| } |
| } |
| |
| Cluster cluster = clusters.getCluster(clusterNames.iterator().next()); |
| |
| return createStages(cluster, requestProperties, null, null, null, changedScHosts, ignoredScHosts, runSmokeTest, |
| false); |
| } |
| |
| private void validateServiceComponentHostRequest(ServiceComponentHostRequest request) { |
| if (request.getClusterName() == null |
| || request.getClusterName().isEmpty() |
| || request.getComponentName() == null |
| || request.getComponentName().isEmpty() |
| || request.getHostname() == null |
| || request.getHostname().isEmpty()) { |
| throw new IllegalArgumentException("Invalid arguments" |
| + ", cluster name, component name and host name should be" |
| + " provided"); |
| } |
| } |
| |
| private String findServiceName(Cluster cluster, String componentName) throws AmbariException { |
| StackId stackId = cluster.getDesiredStackVersion(); |
| String serviceName = |
| ambariMetaInfo.getComponentToService(stackId.getStackName(), |
| stackId.getStackVersion(), componentName); |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Looking up service name for component" |
| + ", componentName=" + componentName |
| + ", serviceName=" + serviceName); |
| } |
| |
| if (serviceName == null |
| || serviceName.isEmpty()) { |
| throw new AmbariException("Could not find service for component" |
| + ", componentName=" + componentName |
| + ", clusterName=" + cluster.getClusterName() |
| + ", stackInfo=" + stackId.getStackId()); |
| } |
| return serviceName; |
| } |
| |
| private boolean isDirectTransition(State oldState, State newState) { |
| switch (newState) { |
| case INSTALLED: |
| if (oldState == State.MAINTENANCE) { |
| return true; |
| } |
| break; |
| case MAINTENANCE: |
| if (oldState == State.INSTALLED || |
| oldState == State.UNKNOWN) { |
| return true; |
| } |
| break; |
| default: |
| break; |
| } |
| return false; |
| } |
| |
| @Override |
| public synchronized void updateUsers(Set<UserRequest> requests) throws AmbariException { |
| for (UserRequest request : requests) { |
| User u = users.getAnyUser(request.getUsername()); |
| if (null == u) |
| continue; |
| |
| if (null != request.getOldPassword() && null != request.getPassword()) { |
| users.modifyPassword(u.getUserName(), request.getOldPassword(), |
| request.getPassword()); |
| } |
| |
| if (request.getRoles().size() > 0) { |
| for (String role : u.getRoles()) { |
| users.removeRoleFromUser(u, role); |
| } |
| |
| for (String role : request.getRoles()) { |
| users.addRoleToUser(u, role); |
| } |
| } |
| |
| } |
| } |
| |
| @Override |
| public synchronized void deleteCluster(ClusterRequest request) |
| throws AmbariException { |
| |
| if (request.getClusterName() == null |
| || request.getClusterName().isEmpty()) { |
| // FIXME throw correct error |
| throw new AmbariException("Invalid arguments"); |
| } |
| LOG.info("Received a delete cluster request" |
| + ", clusterName=" + request.getClusterName()); |
| if (request.getHostNames() != null) { |
| // FIXME treat this as removing a host from a cluster? |
| } else { |
| // deleting whole cluster |
| clusters.deleteCluster(request.getClusterName()); |
| } |
| } |
| |
| @Override |
| public RequestStatusResponse deleteHostComponents( |
| Set<ServiceComponentHostRequest> requests) throws AmbariException { |
| |
| Set<ServiceComponentHostRequest> expanded = new HashSet<ServiceComponentHostRequest>(); |
| |
| // if any request are for the whole host, they need to be expanded |
| for (ServiceComponentHostRequest request : requests) { |
| if (null == request.getComponentName()) { |
| if (null == request.getClusterName() || request.getClusterName().isEmpty() || |
| null == request.getHostname() || request.getHostname().isEmpty()) { |
| throw new IllegalArgumentException("Cluster name and hostname must be specified."); |
| } |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| for (ServiceComponentHost sch : cluster.getServiceComponentHosts(request.getHostname())) { |
| ServiceComponentHostRequest schr = new ServiceComponentHostRequest(request.getClusterName(), |
| sch.getServiceName(), sch.getServiceComponentName(), sch.getHostName(), null); |
| expanded.add(schr); |
| } |
| } |
| else { |
| expanded.add(request); |
| } |
| } |
| |
| Map<ServiceComponent, Set<ServiceComponentHost>> safeToRemoveSCHs = new HashMap<ServiceComponent, Set<ServiceComponentHost>>(); |
| |
| for (ServiceComponentHostRequest request : expanded) { |
| |
| validateServiceComponentHostRequest(request); |
| |
| Cluster cluster = clusters.getCluster(request.getClusterName()); |
| |
| if (StringUtils.isEmpty(request.getServiceName())) { |
| request.setServiceName(findServiceName(cluster, request.getComponentName())); |
| } |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a hostComponent DELETE request" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + request.getServiceName() |
| + ", componentName=" + request.getComponentName() |
| + ", hostname=" + request.getHostname() |
| + ", request=" + request); |
| } |
| |
| Service service = cluster.getService(request.getServiceName()); |
| ServiceComponent component = service.getServiceComponent(request.getComponentName()); |
| ServiceComponentHost componentHost = component.getServiceComponentHost(request.getHostname()); |
| |
| if (!componentHost.canBeRemoved()) { |
| throw new AmbariException("Host Component cannot be removed" |
| + ", clusterName=" + request.getClusterName() |
| + ", serviceName=" + request.getServiceName() |
| + ", componentName=" + request.getComponentName() |
| + ", hostname=" + request.getHostname() |
| + ", request=" + request); |
| } |
| |
| // Only allow removing master/slave components in MAINTENANCE/UNKNOWN/INSTALL_FAILED/INIT state without stages |
| // generation. |
| // Clients may be removed without a state check. |
| if (!component.isClientComponent() && |
| !componentHost.getState().isRemovableState()) { |
| throw new AmbariException("To remove master or slave components they must be in " + |
| "MAINTENANCE/INIT/INSTALLED/INSTALL_FAILED/UNKNOWN state. Current=" + componentHost.getState() + "."); |
| } |
| |
| if (!safeToRemoveSCHs.containsKey(component)) { |
| safeToRemoveSCHs.put(component, new HashSet<ServiceComponentHost>()); |
| } |
| safeToRemoveSCHs.get(component).add(componentHost); |
| } |
| |
| for (Entry<ServiceComponent, Set<ServiceComponentHost>> entry : safeToRemoveSCHs.entrySet()) { |
| for (ServiceComponentHost componentHost : entry.getValue()) { |
| entry.getKey().deleteServiceComponentHosts(componentHost.getHostName()); |
| } |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public void deleteUsers(Set<UserRequest> requests) |
| throws AmbariException { |
| |
| for (UserRequest r : requests) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a delete user request" |
| + ", username=" + r.getUsername()); |
| } |
| User u = users.getAnyUser(r.getUsername()); |
| if (null != u) |
| users.removeUser(u); |
| } |
| } |
| |
| /** |
| * Get a request response for the given request ids. Note that this method |
| * fully populates a request resource including the set of task sub-resources |
| * in the request response. |
| */ |
| private RequestStatusResponse getRequestStatusResponse(long requestId) { |
| RequestStatusResponse response = new RequestStatusResponse(requestId); |
| List<HostRoleCommand> hostRoleCommands = |
| actionManager.getRequestTasks(requestId); |
| |
| response.setRequestContext(actionManager.getRequestContext(requestId)); |
| List<ShortTaskStatus> tasks = new ArrayList<ShortTaskStatus>(); |
| |
| for (HostRoleCommand hostRoleCommand : hostRoleCommands) { |
| tasks.add(new ShortTaskStatus(hostRoleCommand)); |
| } |
| response.setTasks(tasks); |
| |
| return response; |
| } |
| |
| @Override |
| public Set<TaskStatusResponse> getTaskStatus(Set<TaskStatusRequest> requests) |
| throws AmbariException { |
| |
| Collection<Long> requestIds = new ArrayList<Long>(); |
| Collection<Long> taskIds = new ArrayList<Long>(); |
| |
| for (TaskStatusRequest request : requests) { |
| if (request.getTaskId() != null) { |
| taskIds.add(request.getTaskId()); |
| } |
| if (request.getRequestId() != null) { |
| requestIds.add(request.getRequestId()); |
| } |
| } |
| |
| Set<TaskStatusResponse> responses = new HashSet<TaskStatusResponse>(); |
| for (HostRoleCommand command : actionManager.getTasksByRequestAndTaskIds(requestIds, taskIds)) { |
| TaskStatusResponse taskStatusResponse = new TaskStatusResponse(command); |
| responses.add(taskStatusResponse); |
| } |
| |
| if (responses.size() == 0) { |
| throw new ObjectNotFoundException("Task resource doesn't exist."); |
| } |
| |
| return responses; |
| } |
| |
| @Override |
| public Set<ClusterResponse> getClusters(Set<ClusterRequest> requests) throws AmbariException { |
| Set<ClusterResponse> response = new HashSet<ClusterResponse>(); |
| for (ClusterRequest request : requests) { |
| try { |
| response.addAll(getClusters(request)); |
| } catch (ClusterNotFoundException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| } |
| |
| @Override |
| public Set<ServiceComponentHostResponse> getHostComponents( |
| Set<ServiceComponentHostRequest> requests) throws AmbariException { |
| Set<ServiceComponentHostResponse> response = |
| new HashSet<ServiceComponentHostResponse>(); |
| for (ServiceComponentHostRequest request : requests) { |
| try { |
| response.addAll(getHostComponents(request)); |
| } catch (ServiceComponentHostNotFoundException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } catch (ServiceNotFoundException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| // In 'OR' case, a host_component may be included in predicate |
| // that has no corresponding service |
| throw e; |
| } |
| } catch (ServiceComponentNotFoundException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| // In 'OR' case, a host_component may be included in predicate |
| // that has no corresponding component |
| throw e; |
| } |
| } catch (ParentObjectNotFoundException e) { |
| // If there is only one request, always throw exception. |
| // There will be > 1 request in case of OR predicate. |
| |
| // For HostNotFoundException, only throw exception if host_name is |
| // provided in URL. If host_name is part of query, don't throw exception. |
| boolean throwException = true; |
| if (requests.size() > 1 && HostNotFoundException.class.isInstance(e.getCause())) { |
| for (ServiceComponentHostRequest r : requests) { |
| if (r.getHostname() == null) { |
| // host_name provided in query since all requests don't have host_name set |
| throwException = false; |
| break; |
| } |
| } |
| } |
| if (throwException) throw e; |
| } |
| } |
| return response; |
| } |
| |
| @Override |
| public Set<ConfigurationResponse> getConfigurations( |
| Set<ConfigurationRequest> requests) throws AmbariException { |
| Set<ConfigurationResponse> response = |
| new HashSet<ConfigurationResponse>(); |
| for (ConfigurationRequest request : requests) { |
| response.addAll(getConfigurations(request)); |
| } |
| return response; |
| } |
| |
| @Override |
| public Set<UserResponse> getUsers(Set<UserRequest> requests) |
| throws AmbariException { |
| |
| Set<UserResponse> responses = new HashSet<UserResponse>(); |
| |
| for (UserRequest r : requests) { |
| |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Received a getUsers request" |
| + ", userRequest=" + r.toString()); |
| } |
| // get them all |
| if (null == r.getUsername()) { |
| for (User u : users.getAllUsers()) { |
| UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser()); |
| resp.setRoles(new HashSet<String>(u.getRoles())); |
| responses.add(resp); |
| } |
| } else { |
| |
| User u = users.getAnyUser(r.getUsername()); |
| if (null == u) { |
| if (requests.size() == 1) { |
| // only throw exceptin if there is a single request |
| // if there are multiple requests, this indicates an OR predicate |
| throw new ObjectNotFoundException("Cannot find user '" |
| + r.getUsername() + "'"); |
| } |
| } else { |
| UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser()); |
| resp.setRoles(new HashSet<String>(u.getRoles())); |
| responses.add(resp); |
| } |
| } |
| } |
| |
| return responses; |
| } |
| |
| private String getClientHostForRunningAction(Cluster cluster, |
| Service service) throws AmbariException { |
| StackId stackId = service.getDesiredStackVersion(); |
| ComponentInfo compInfo = |
| ambariMetaInfo.getServiceInfo(stackId.getStackName(), |
| stackId.getStackVersion(), service.getName()).getClientComponent(); |
| if (compInfo != null) { |
| try { |
| ServiceComponent serviceComponent = |
| service.getServiceComponent(compInfo.getName()); |
| if (!serviceComponent.getServiceComponentHosts().isEmpty()) { |
| return getHealthyHost(serviceComponent.getServiceComponentHosts().keySet()); |
| } |
| } catch (ServiceComponentNotFoundException e) { |
| LOG.warn("Could not find required component to run action" |
| + ", clusterName=" + cluster.getClusterName() |
| + ", serviceName=" + service.getName() |
| + ", componentName=" + compInfo.getName()); |
| |
| |
| } |
| } |
| |
| // any component will do |
| Map<String, ServiceComponent> components = service.getServiceComponents(); |
| if (components.isEmpty()) { |
| return null; |
| } |
| |
| for (ServiceComponent serviceComponent : components.values()) { |
| if (serviceComponent.getServiceComponentHosts().isEmpty()) { |
| continue; |
| } |
| return getHealthyHost(serviceComponent.getServiceComponentHosts().keySet()); |
| } |
| return null; |
| } |
| |
| protected String getHealthyHost(Set<String> hostList) throws AmbariException { |
| // Return a healthy host if found otherwise any random host |
| String hostName = null; |
| for (String candidateHostName : hostList) { |
| hostName = candidateHostName; |
| Host candidateHost = clusters.getHost(hostName); |
| if (candidateHost.getState() == HostState.HEALTHY) { |
| break; |
| } |
| } |
| return hostName; |
| } |
| |
| @Override |
| public RequestStatusResponse createAction(ExecuteActionRequest actionRequest, Map<String, String> requestProperties) |
| throws AmbariException { |
| String clusterName; |
| Configuration configuration = injector.getInstance(Configuration.class); |
| String requestContext = ""; |
| |
| if (requestProperties != null) { |
| requestContext = requestProperties.get(REQUEST_CONTEXT_PROPERTY); |
| if (requestContext == null) { |
| // guice needs a non-null value as there is no way to mark this parameter @Nullable |
| requestContext = ""; |
| } |
| } |
| |
| if (actionRequest.getClusterName() == null |
| || actionRequest.getClusterName().isEmpty()) { |
| throw new AmbariException("Invalid request, cluster name must be specified"); |
| } |
| clusterName = actionRequest.getClusterName(); |
| |
| Cluster cluster = clusters.getCluster(clusterName); |
| |
| ActionExecutionContext actionExecContext = null; |
| if (actionRequest.isCommand()) { |
| customCommandExecutionHelper.validateCustomCommand(actionRequest); |
| } else { |
| actionExecContext = actionExecutionHelper.validateCustomAction(actionRequest, cluster); |
| } |
| |
| Map<String, List<String>> clusterHostInfo = StageUtils.getClusterHostInfo( |
| clusters.getHostsForCluster(cluster.getClusterName()), cluster, hostsMap, |
| injector.getInstance(Configuration.class)); |
| |
| String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo); |
| Stage stage = createNewStage(cluster, actionManager.getNextRequestId(), requestContext, clusterHostInfoJson); |
| |
| stage.setStageId(0); |
| |
| Map<String, String> params = new TreeMap<String, String>(); |
| params.put("jdk_location", this.jdkResourceUrl); |
| params.put("stack_version", cluster.getDesiredStackVersion().getStackVersion()); |
| |
| if (actionRequest.isCommand()) { |
| customCommandExecutionHelper.addAction(actionRequest, stage, configuration, hostsMap, params); |
| } else { |
| actionExecutionHelper.addAction(actionExecContext, stage, configuration, hostsMap, params); |
| } |
| |
| RoleCommandOrder rco = this.getRoleCommandOrder(cluster); |
| RoleGraph rg = new RoleGraph(rco); |
| rg.build(stage); |
| List<Stage> stages = rg.getStages(); |
| if (stages != null && !stages.isEmpty()) { |
| actionManager.sendActions(stages, actionRequest); |
| return getRequestStatusResponse(stage.getRequestId()); |
| } else { |
| throw new AmbariException("Stage was not created"); |
| } |
| } |
| |
| @Override |
| public Set<StackResponse> getStacks(Set<StackRequest> requests) |
| throws AmbariException { |
| Set<StackResponse> response = new HashSet<StackResponse>(); |
| for (StackRequest request : requests) { |
| try { |
| response.addAll(getStacks(request)); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| |
| } |
| |
| |
| private Set<StackResponse> getStacks(StackRequest request) |
| throws AmbariException { |
| Set<StackResponse> response; |
| |
| String stackName = request.getStackName(); |
| |
| if (stackName != null) { |
| org.apache.ambari.server.state.Stack stack = this.ambariMetaInfo.getStack(stackName); |
| response = Collections.singleton(stack.convertToResponse()); |
| } else { |
| Set<org.apache.ambari.server.state.Stack> supportedStackNames = this.ambariMetaInfo.getStackNames(); |
| response = new HashSet<StackResponse>(); |
| for (org.apache.ambari.server.state.Stack stack: supportedStackNames) { |
| response.add(stack.convertToResponse()); |
| } |
| } |
| return response; |
| } |
| |
| @Override |
| public synchronized RequestStatusResponse updateStacks() throws AmbariException { |
| |
| try { |
| ambariMetaInfo.init(); |
| } catch (Exception e) { |
| throw new AmbariException( |
| "Ambari metainormation can't be read from the stack root directory"); |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public Set<RepositoryResponse> getRepositories(Set<RepositoryRequest> requests) |
| throws AmbariException { |
| Set<RepositoryResponse> response = new HashSet<RepositoryResponse>(); |
| for (RepositoryRequest request : requests) { |
| try { |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| |
| Set<RepositoryResponse> repositories = getRepositories(request); |
| |
| for (RepositoryResponse repositoryResponse : repositories) { |
| repositoryResponse.setStackName(stackName); |
| repositoryResponse.setStackVersion(stackVersion); |
| } |
| response.addAll(repositories); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| } |
| |
| private Set<RepositoryResponse> getRepositories(RepositoryRequest request) throws AmbariException { |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String osType = request.getOsType(); |
| String repoId = request.getRepoId(); |
| |
| Set<RepositoryResponse> response; |
| |
| if (repoId == null) { |
| List<RepositoryInfo> repositories = this.ambariMetaInfo.getRepositories(stackName, stackVersion, osType); |
| response = new HashSet<RepositoryResponse>(); |
| |
| for (RepositoryInfo repository: repositories) { |
| response.add(repository.convertToResponse()); |
| } |
| |
| } else { |
| RepositoryInfo repository = this.ambariMetaInfo.getRepository(stackName, stackVersion, osType, repoId); |
| response = Collections.singleton(repository.convertToResponse()); |
| } |
| |
| return response; |
| } |
| |
| @Override |
| public void updateRespositories(Set<RepositoryRequest> requests) throws AmbariException { |
| for (RepositoryRequest rr : requests) { |
| if (null == rr.getStackName() || rr.getStackName().isEmpty()) |
| throw new AmbariException("Stack name must be specified."); |
| |
| if (null == rr.getStackVersion() || rr.getStackVersion().isEmpty()) |
| throw new AmbariException("Stack version must be specified."); |
| |
| if (null == rr.getOsType() || rr.getOsType().isEmpty()) |
| throw new AmbariException("OS type must be specified."); |
| |
| if (null == rr.getRepoId() || rr.getRepoId().isEmpty()) |
| throw new AmbariException("Repo ID must be specified."); |
| |
| if (null != rr.getBaseUrl()) { |
| if (!rr.isVerifyBaseUrl()) { |
| ambariMetaInfo.updateRepoBaseURL(rr.getStackName(), |
| rr.getStackVersion(), rr.getOsType(), rr.getRepoId(), |
| rr.getBaseUrl()); |
| } else { |
| URLStreamProvider usp = new URLStreamProvider(REPO_URL_CONNECT_TIMEOUT, |
| REPO_URL_READ_TIMEOUT, null, null, null); |
| |
| boolean bFound = false; |
| |
| String[] suffixes = configs.getRepoValidationSuffixes(); |
| for (int i = 0; i < suffixes.length && !bFound; i++) { |
| String suffix = suffixes[i]; |
| String spec = rr.getBaseUrl(); |
| |
| if (spec.charAt(spec.length()-1) != '/' && suffix.charAt(0) != '/') |
| spec = rr.getBaseUrl() + "/" + suffix; |
| else if (spec.charAt(spec.length()-1) == '/' && suffix.charAt(0) == '/') |
| spec = rr.getBaseUrl() + suffix.substring(1); |
| else |
| spec = rr.getBaseUrl() + suffix; |
| |
| try { |
| IOUtils.readLines(usp.readFrom(spec)); |
| bFound = true; |
| } catch (IOException ioe) { |
| // failed, but try other suffixes |
| } |
| } |
| |
| if (bFound) { |
| ambariMetaInfo.updateRepoBaseURL(rr.getStackName(), |
| rr.getStackVersion(), rr.getOsType(), rr.getRepoId(), |
| rr.getBaseUrl()); |
| } else { |
| throw new IllegalArgumentException("Could not access base url '" + |
| rr.getBaseUrl() + "'"); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| @Override |
| public Set<StackVersionResponse> getStackVersions( |
| Set<StackVersionRequest> requests) throws AmbariException { |
| Set<StackVersionResponse> response = new HashSet<StackVersionResponse>(); |
| for (StackVersionRequest request : requests) { |
| String stackName = request.getStackName(); |
| try { |
| Set<StackVersionResponse> stackVersions = getStackVersions(request); |
| for (StackVersionResponse stackVersionResponse : stackVersions) { |
| stackVersionResponse.setStackName(stackName); |
| } |
| response.addAll(stackVersions); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| |
| return response; |
| |
| } |
| |
| private Set<StackVersionResponse> getStackVersions(StackVersionRequest request) throws AmbariException { |
| Set<StackVersionResponse> response; |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| |
| if (stackVersion != null) { |
| StackInfo stackInfo = this.ambariMetaInfo.getStackInfo(stackName, stackVersion); |
| response = Collections.singleton(stackInfo.convertToResponse()); |
| } else { |
| Set<StackInfo> stackInfos = this.ambariMetaInfo.getStackInfos(stackName); |
| response = new HashSet<StackVersionResponse>(); |
| for (StackInfo stackInfo: stackInfos) { |
| response.add(stackInfo.convertToResponse()); |
| } |
| } |
| |
| return response; |
| } |
| |
| @Override |
| public Set<StackServiceResponse> getStackServices( |
| Set<StackServiceRequest> requests) throws AmbariException { |
| |
| Set<StackServiceResponse> response = new HashSet<StackServiceResponse>(); |
| |
| for (StackServiceRequest request : requests) { |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| |
| try { |
| Set<StackServiceResponse> stackServices = getStackServices(request); |
| |
| for (StackServiceResponse stackServiceResponse : stackServices) { |
| stackServiceResponse.setStackName(stackName); |
| stackServiceResponse.setStackVersion(stackVersion); |
| } |
| |
| response.addAll(stackServices); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| |
| return response; |
| } |
| |
| private Set<StackServiceResponse> getStackServices(StackServiceRequest request) throws AmbariException { |
| Set<StackServiceResponse> response; |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String serviceName = request.getServiceName(); |
| |
| if (serviceName != null) { |
| ServiceInfo service = this.ambariMetaInfo.getService(stackName, stackVersion, serviceName); |
| response = Collections.singleton(service.convertToResponse()); |
| } else { |
| Map<String, ServiceInfo> services = this.ambariMetaInfo.getServices(stackName, stackVersion); |
| response = new HashSet<StackServiceResponse>(); |
| for (ServiceInfo service : services.values()) { |
| response.add(service.convertToResponse()); |
| } |
| } |
| return response; |
| } |
| |
| @Override |
| public Set<StackConfigurationResponse> getStackConfigurations( |
| Set<StackConfigurationRequest> requests) throws AmbariException { |
| Set<StackConfigurationResponse> response = new HashSet<StackConfigurationResponse>(); |
| for (StackConfigurationRequest request : requests) { |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String serviceName = request.getServiceName(); |
| |
| Set<StackConfigurationResponse> stackConfigurations = getStackConfigurations(request); |
| |
| for (StackConfigurationResponse stackConfigurationResponse : stackConfigurations) { |
| stackConfigurationResponse.setStackName(stackName); |
| stackConfigurationResponse.setStackVersion(stackVersion); |
| stackConfigurationResponse.setServiceName(serviceName); |
| } |
| |
| response.addAll(stackConfigurations); |
| } |
| |
| return response; |
| } |
| |
| private Set<StackConfigurationResponse> getStackConfigurations( |
| StackConfigurationRequest request) throws AmbariException { |
| |
| Set<StackConfigurationResponse> response; |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String serviceName = request.getServiceName(); |
| String propertyName = request.getPropertyName(); |
| |
| if (propertyName != null) { |
| PropertyInfo property = this.ambariMetaInfo.getProperty(stackName, stackVersion, serviceName, propertyName); |
| response = Collections.singleton(property.convertToResponse()); |
| } else { |
| |
| Set<PropertyInfo> properties = this.ambariMetaInfo.getProperties(stackName, stackVersion, serviceName); |
| response = new HashSet<StackConfigurationResponse>(); |
| |
| for (PropertyInfo property: properties) { |
| response.add(property.convertToResponse()); |
| } |
| } |
| |
| return response; |
| } |
| |
| @Override |
| public Set<StackServiceComponentResponse> getStackComponents( |
| Set<StackServiceComponentRequest> requests) throws AmbariException { |
| Set<StackServiceComponentResponse> response = new HashSet<StackServiceComponentResponse>(); |
| for (StackServiceComponentRequest request : requests) { |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String serviceName = request.getServiceName(); |
| |
| try { |
| Set<StackServiceComponentResponse> stackComponents = getStackComponents(request); |
| |
| for (StackServiceComponentResponse stackServiceComponentResponse : stackComponents) { |
| stackServiceComponentResponse.setStackName(stackName); |
| stackServiceComponentResponse.setStackVersion(stackVersion); |
| stackServiceComponentResponse.setServiceName(serviceName); |
| } |
| |
| response.addAll(stackComponents); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| |
| return response; |
| } |
| |
| private Set<StackServiceComponentResponse> getStackComponents( |
| StackServiceComponentRequest request) throws AmbariException { |
| Set<StackServiceComponentResponse> response; |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String serviceName = request.getServiceName(); |
| String componentName = request.getComponentName(); |
| |
| if (componentName != null) { |
| ComponentInfo component = this.ambariMetaInfo.getComponent(stackName, stackVersion, serviceName, componentName); |
| response = Collections.singleton(component.convertToResponse()); |
| |
| } else { |
| List<ComponentInfo> components = this.ambariMetaInfo.getComponentsByService(stackName, stackVersion, serviceName); |
| response = new HashSet<StackServiceComponentResponse>(); |
| |
| for (ComponentInfo component: components) { |
| response.add(component.convertToResponse()); |
| } |
| } |
| return response; |
| } |
| |
| @Override |
| public Set<OperatingSystemResponse> getStackOperatingSystems( |
| Set<OperatingSystemRequest> requests) throws AmbariException { |
| Set<OperatingSystemResponse> response = new HashSet<OperatingSystemResponse>(); |
| for (OperatingSystemRequest request : requests) { |
| try { |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| |
| Set<OperatingSystemResponse> stackOperatingSystems = getStackOperatingSystems(request); |
| |
| for (OperatingSystemResponse operatingSystemResponse : stackOperatingSystems) { |
| operatingSystemResponse.setStackName(stackName); |
| operatingSystemResponse.setStackVersion(stackVersion); |
| } |
| response.addAll(stackOperatingSystems); |
| } catch (StackAccessException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| } |
| |
| private Set<OperatingSystemResponse> getStackOperatingSystems( |
| OperatingSystemRequest request) throws AmbariException { |
| |
| Set<OperatingSystemResponse> response; |
| |
| String stackName = request.getStackName(); |
| String stackVersion = request.getStackVersion(); |
| String osType = request.getOsType(); |
| |
| if (osType != null) { |
| OperatingSystemInfo operatingSystem = this.ambariMetaInfo.getOperatingSystem(stackName, stackVersion, osType); |
| response = Collections.singleton(operatingSystem.convertToResponse()); |
| } else { |
| Set<OperatingSystemInfo> operatingSystems = this.ambariMetaInfo.getOperatingSystems(stackName, stackVersion); |
| response = new HashSet<OperatingSystemResponse>(); |
| for (OperatingSystemInfo operatingSystem : operatingSystems) |
| response.add(operatingSystem.convertToResponse()); |
| } |
| |
| return response; |
| } |
| |
| @Override |
| public String getAuthName() { |
| return AuthorizationHelper.getAuthenticatedName(configs.getAnonymousAuditName()); |
| } |
| |
| @Override |
| public Set<RootServiceResponse> getRootServices( |
| Set<RootServiceRequest> requests) throws AmbariException { |
| Set<RootServiceResponse> response = new HashSet<RootServiceResponse>(); |
| for (RootServiceRequest request : requests) { |
| try { |
| response.addAll(getRootServices(request)); |
| } catch (AmbariException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| } |
| |
| private Set<RootServiceResponse> getRootServices (RootServiceRequest request) |
| throws AmbariException{ |
| return this.rootServiceResponseFactory.getRootServices(request); |
| } |
| |
| @Override |
| public Set<RootServiceComponentResponse> getRootServiceComponents( |
| Set<RootServiceComponentRequest> requests) throws AmbariException { |
| Set<RootServiceComponentResponse> response = new HashSet<RootServiceComponentResponse>(); |
| for (RootServiceComponentRequest request : requests) { |
| String serviceName = request.getServiceName(); |
| try { |
| Set<RootServiceComponentResponse> rootServiceComponents = getRootServiceComponents(request); |
| |
| for (RootServiceComponentResponse serviceComponentResponse : rootServiceComponents) { |
| serviceComponentResponse.setServiceName(serviceName); |
| } |
| |
| response.addAll(rootServiceComponents); |
| } catch (AmbariException e) { |
| if (requests.size() == 1) { |
| // only throw exception if 1 request. |
| // there will be > 1 request in case of OR predicate |
| throw e; |
| } |
| } |
| } |
| return response; |
| } |
| |
| private Set<RootServiceComponentResponse> getRootServiceComponents( |
| RootServiceComponentRequest request) throws AmbariException{ |
| return this.rootServiceResponseFactory.getRootServiceComponents(request); |
| } |
| |
| @Override |
| public Clusters getClusters() { |
| return clusters; |
| } |
| |
| @Override |
| public AmbariMetaInfo getAmbariMetaInfo() { |
| return ambariMetaInfo; |
| } |
| |
| @Override |
| public ServiceFactory getServiceFactory() { |
| return serviceFactory; |
| } |
| |
| @Override |
| public ServiceComponentFactory getServiceComponentFactory() { |
| return serviceComponentFactory; |
| } |
| |
| @Override |
| public ConfigGroupFactory getConfigGroupFactory() { |
| return configGroupFactory; |
| } |
| |
| @Override |
| public AbstractRootServiceResponseFactory getRootServiceResponseFactory() { |
| return rootServiceResponseFactory; |
| |
| } |
| |
| @Override |
| public ActionManager getActionManager() { |
| return actionManager; |
| } |
| } |