Package org.apache.whirr.actions

Source Code of org.apache.whirr.actions.ConfigureClusterAction

/**
* 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.whirr.actions;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;

import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.whirr.Cluster;
import org.apache.whirr.Cluster.Instance;
import org.apache.whirr.ClusterSpec;
import org.apache.whirr.InstanceTemplate;
import org.apache.whirr.RolePredicates;
import org.apache.whirr.service.ClusterActionEvent;
import org.apache.whirr.service.ClusterActionHandler;
import org.apache.whirr.service.jclouds.StatementBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunScriptOnNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Credentials;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A {@link org.apache.whirr.ClusterAction} for running a configuration script on instances
* in the cluster after it has been bootstrapped.
*/
public class ConfigureClusterAction extends ScriptBasedClusterAction {
 
  private static final Logger LOG =
    LoggerFactory.getLogger(ConfigureClusterAction.class);

  public ConfigureClusterAction(Function<ClusterSpec, ComputeServiceContext> getCompute,
      Map<String, ClusterActionHandler> handlerMap) {
    super(getCompute, handlerMap);
  }
 
  @Override
  protected String getAction() {
    return ClusterActionHandler.CONFIGURE_ACTION;
  }
 
  @Override
  protected void doAction(Map<InstanceTemplate, ClusterActionEvent> eventMap)
      throws IOException {
   
    for (Entry<InstanceTemplate, ClusterActionEvent> entry : eventMap.entrySet()) {
      ClusterSpec clusterSpec = entry.getValue().getClusterSpec();
      Cluster cluster = entry.getValue().getCluster();

      StatementBuilder statementBuilder = entry.getValue().getStatementBuilder();

      ComputeServiceContext computeServiceContext = getCompute().apply(clusterSpec);
      ComputeService computeService = computeServiceContext.getComputeService();

      Credentials credentials = new Credentials(
          clusterSpec.getClusterUser(),
          clusterSpec.getPrivateKey());

      try {
        Map<String, ? extends NodeMetadata> nodesInCluster = getNodesForInstanceIdsInCluster(cluster, computeService);
       
        if (LOG.isDebugEnabled()) {
          LOG.debug("Nodes in cluster: {}", nodesInCluster.values());
        }
       
        Map<String, ? extends NodeMetadata> nodesToApply = Maps.uniqueIndex(
            Iterables.filter(nodesInCluster.values(),
                toNodeMetadataPredicate(clusterSpec, cluster, entry.getKey().getRoles())),
            getNodeId
        );

        LOG.info("Running configuration script on nodes: {}", nodesToApply.keySet());
        if (LOG.isDebugEnabled())
          LOG.debug("script:\n{}", statementBuilder.render(OsFamily.UNIX));
       
        computeService.runScriptOnNodesMatching(
            withIds(nodesToApply.keySet()),
            statementBuilder,
            RunScriptOptions.Builder.overrideCredentialsWith(credentials)
        );
       
        LOG.info("Configuration script run completed");
      } catch (RunScriptOnNodesException e) {
        // TODO: retry
        throw new IOException(e);
      }
    }
  }

  private Map<String, ? extends NodeMetadata> getNodesForInstanceIdsInCluster(Cluster cluster,
        ComputeService computeService) {
    Iterable<String> ids = Iterables.transform(cluster.getInstances(), new Function<Instance, String>() {

      @Override
      public String apply(Instance arg0) {
        return arg0.getId();
      }

    });
   
    Set<? extends NodeMetadata> nodes = computeService.listNodesDetailsMatching(
        NodePredicates.withIds(Iterables.toArray(ids, String.class)));
   
    return Maps.uniqueIndex(nodes, getNodeId);
  }

  public static Predicate<NodeMetadata> withIds(Iterable<String> ids) {
    checkNotNull(ids, "ids must be defined");
    final Set<String> search = ImmutableSet.copyOf(ids);
    return new Predicate<NodeMetadata>() {
      @Override
      public boolean apply(NodeMetadata nodeMetadata) {
        return search.contains(nodeMetadata.getId());
      }
    };
  }
 
  private static Function<NodeMetadata, String> getNodeId = new Function<NodeMetadata, String>() {

    @Override
    public String apply(NodeMetadata arg0) {
      return arg0.getId();
    }
    
  };
 
  private Predicate<NodeMetadata> toNodeMetadataPredicate(final ClusterSpec clusterSpec, final Cluster cluster, final Set<String> roles) {
    final Map<String, Instance> nodeIdToInstanceMap = Maps.newHashMap();
    for (Instance instance : cluster.getInstances()) {
      nodeIdToInstanceMap.put(instance.getId(), instance);
    }
    return new Predicate<NodeMetadata>() {
      @Override
      public boolean apply(NodeMetadata nodeMetadata) {
        Instance instance = nodeIdToInstanceMap.get(nodeMetadata.getId());
        if (instance == null) {
          LOG.debug("No instance for {} found in map", nodeMetadata);
          return false;
        }
        return RolePredicates.onlyRolesIn(roles).apply(instance);
      }
      @Override
      public String toString() {
         return "roles(" + roles + ")";
      }
   };
  }
}
TOP

Related Classes of org.apache.whirr.actions.ConfigureClusterAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.