org.apache.hive.ptest.execution.context.CloudComputeService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hive.ptest.execution.context.CloudComputeService.java

Source

/*
 * 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.hive.ptest.execution.context;

import java.io.File;
import java.io.IOException;
import java.util.*;

import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import org.jclouds.Constants;
import org.jclouds.ContextBuilder;
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.config.ComputeServiceProperties;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadata.Status;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.googlecloud.GoogleCredentialsFromJson;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import static com.google.common.base.Charsets.UTF_8;

public class CloudComputeService {
    private static final Logger LOG = LoggerFactory.getLogger(CloudComputeService.class);
    private final CloudComputeConfig mConfig;
    private final ComputeServiceContext mComputeServiceContext;
    private final ComputeService mComputeService;
    private final Template mTemplate;
    private final String mGroupTag;

    public CloudComputeService(final CloudComputeConfig config) {
        mConfig = config;

        mComputeServiceContext = initComputeServiceContext(config.getmProvider(), config.getIdentity(),
                config.getCredential());
        mComputeService = mComputeServiceContext.getComputeService();
        mTemplate = mComputeService.templateBuilder().hardwareId(config.getInstanceType())
                .imageId(config.getImageId()).build();

        TemplateOptions options = mTemplate.getOptions();

        // Set generic options
        options.blockOnPort(22, 60);
        options.userMetadata(config.getUserMetaData());

        // Set provider options
        switch (config.getmProvider()) {
        case AWS:
            mGroupTag = String.format("group=%s", config.getGroupName());

            options.as(AWSEC2TemplateOptions.class).keyPair(config.getKeyPairName())
                    .securityGroupIds(config.getSecurityGroup()).spotPrice(config.getMaxBid())
                    .tags(Collections.singletonList(mGroupTag));
            break;
        case GCE:
            mGroupTag = config.getGroupName();

            options.as(GoogleComputeEngineTemplateOptions.class)
                    .tags(Arrays.asList(config.getGroupName(), config.getSecurityGroup())); // GCE firewall is set through instance tags
            break;
        default:
            mGroupTag = "";
        }
    }

    private ComputeServiceContext initComputeServiceContext(CloudComputeConfig.CloudComputeProvider provider,
            String identity, String credential) {
        Properties overrides = new Properties();

        overrides.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, String.valueOf(60L * 1000L));
        overrides.put(ComputeServiceProperties.POLL_MAX_PERIOD, String.valueOf(600L * 1000L));
        overrides.put(Constants.PROPERTY_MAX_RETRIES, String.valueOf(60));

        return ContextBuilder.newBuilder(provider.getmJcloudsId()).credentials(identity, credential)
                .modules(ImmutableSet.of(new SshjSshClientModule(), new Log4JLoggingModule())).overrides(overrides)
                .buildView(ComputeServiceContext.class);
    }

    public Set<NodeMetadata> createNodes(int count) throws RunNodesException {
        Set<NodeMetadata> result = Sets.newHashSet();
        result.addAll(mComputeService.createNodesInGroup(mConfig.getGroupName(), count, mTemplate));
        return result;
    }

    static Predicate<ComputeMetadata> createFilterPTestPredicate(final String groupName, final String groupTag) {
        return new Predicate<ComputeMetadata>() {
            @Override
            public boolean apply(ComputeMetadata computeMetadata) {
                NodeMetadata nodeMetadata = (NodeMetadata) computeMetadata;
                return nodeMetadata.getStatus() == Status.RUNNING && isPTestHost(nodeMetadata);
            }

            private boolean isPTestHost(NodeMetadata node) {
                String result = "false non-ptest host";
                if (groupName.equalsIgnoreCase(node.getGroup())) {
                    result = "true due to group " + groupName;
                    return true;
                }
                if (Strings.nullToEmpty(node.getName()).startsWith(groupName)) {
                    result = "true due to name " + groupName;
                    return true;
                }
                if (node.getTags().contains(groupTag)) {
                    result = "true due to tag " + groupName;
                    return true;
                }
                LOG.debug("Found node: " + node + ", Result: " + result);
                return false;
            }
        };
    }

    public Set<NodeMetadata> listRunningNodes() {
        Set<NodeMetadata> result = Sets.newHashSet();
        result.addAll(mComputeService
                .listNodesDetailsMatching(createFilterPTestPredicate(mConfig.getGroupName(), mGroupTag)));
        return result;
    }

    public void destroyNode(String nodeId) {
        mComputeService.destroyNode(nodeId);
    }

    public void close() {
        mComputeServiceContext.close();
    }

    public static class CloudComputeConfig {
        public enum CloudComputeProvider {
            AWS("aws-ec2"), GCE("google-compute-engine");

            private final String mJcloudsId;

            CloudComputeProvider(String jcloudsId) {
                mJcloudsId = jcloudsId;
            }

            public String getmJcloudsId() {
                return mJcloudsId;
            }
        };

        private final CloudComputeProvider mProvider;

        private String mIdentity;
        private String mCredential;
        private String mInstanceType;
        private String mImageId;
        private String mGroupName;
        private String mSecurityGroup;
        private String mKeyPairName;
        private Map<String, String> mUserMetaData;

        /**
         * JClouds requests on-demand instances when null
         */
        private Float mMaxBid;

        public CloudComputeConfig(CloudComputeProvider provider) {
            mProvider = provider;
        }

        public void setCredentials(String identity, String credential) {
            mIdentity = identity;
            mCredential = credential;
        }

        public void setInstanceType(String instanceType) {
            mInstanceType = instanceType;
        }

        public void setImageId(String imageId) {
            mImageId = imageId;
        }

        public void setGroupName(String groupName) {
            mGroupName = groupName;
        }

        public void setSecurityGroup(String securityGroup) {
            mSecurityGroup = securityGroup;
        }

        public void setMaxBid(Float maxBid) {
            mMaxBid = maxBid;
        }

        public void setmKeyPairName(String keyPairName) {
            mKeyPairName = keyPairName;
        }

        public void setUserMetaData(Map<String, String> userMetaData) {
            mUserMetaData = userMetaData;
        }

        public CloudComputeProvider getmProvider() {
            return mProvider;
        }

        public String getIdentity() {
            return mIdentity;
        }

        public String getCredential() {
            return mCredential;
        }

        public String getInstanceType() {
            return mInstanceType;
        }

        public String getImageId() {
            return mImageId;
        }

        public String getGroupName() {
            return mGroupName;
        }

        public String getSecurityGroup() {
            return mSecurityGroup;
        }

        public Float getMaxBid() {
            return mMaxBid;
        }

        public String getKeyPairName() {
            return mKeyPairName;
        }

        public Map<String, String> getUserMetaData() {
            if (mUserMetaData == null) {
                return ImmutableMap.of();
            }

            return mUserMetaData;
        }
    }

    public static Credentials getCredentialsFromJsonKeyFile(String filename) throws IOException {
        String fileContents = Files.toString(new File(filename), UTF_8);
        Supplier<Credentials> credentialSupplier = new GoogleCredentialsFromJson(fileContents);
        return credentialSupplier.get();
    }
}