com.vmware.bdd.specpolicy.ClusterSpecFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.bdd.specpolicy.ClusterSpecFactory.java

Source

/***************************************************************************
 * Copyright (c) 2012-2015 VMware, Inc. All Rights Reserved.
 * Licensed 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 com.vmware.bdd.specpolicy;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.Collections;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.vmware.aurora.global.Configuration;
import com.vmware.bdd.apitypes.ClusterCreate;
import com.vmware.bdd.apitypes.ClusterType;
import com.vmware.bdd.exception.BddException;
import com.vmware.bdd.utils.AuAssert;
import com.vmware.bdd.utils.CommonUtil;
import com.vmware.bdd.utils.Constants;
import com.vmware.bdd.utils.Version;

public class ClusterSpecFactory {
    private enum MAPREDUCE_VERSION {
        V1, V2
    }

    private enum HDP_VERSION {
        V1, V2_0, V2_1, V2_2, V2_3, UNKNOWN
    }

    private static final Logger logger = Logger.getLogger(ClusterSpecFactory.class);

    private static final String DEFAULT_TEMPLATE_SPEC_SUFFIX = "-default-template-spec.json";
    private static final String HDFS_TEMPLATE_SPEC = "hdfs-template-spec.json";
    private static final String HDFS_MAPRED_TEMPLATE_SPEC = "hdfs-mapred-template-spec.json";
    private static final String HDFS_YARN_TEMPLATE_SPEC = "hdfs-yarn-template-spec.json";
    private static final String HDFS_HBASE_TEMPLATE_SPEC = "hdfs-hbase-template-spec.json";
    private static final String HDFS_MAPRED_MAPR_TEMPLATE_SPEC = "hdfs-mapred-mapr-template-spec.json";
    private static final String HDFS_MAPRED_MAPR_V3_TEMPLATE_SPEC = "hdfs-mapred-mapr-v3-template-spec.json";
    private static final String HDFS_HBASE_MAPR_TEMPLATE_SPEC = "hdfs-hbase-mapr-template-spec.json";
    private static final String HDFS_HBASE_MAPR_V3_TEMPLATE_SPEC = "hdfs-hbase-mapr-v3-template-spec.json";
    private static final String HDFS_GPHD_TEMPLATE_SPEC = "hdfs-gphd-template-spec.json";
    private static final String HDFS_MAPRED_GPHD_TEMPLATE_SPEC = "hdfs-mapred-gphd-template-spec.json";
    private static final String HDFS_HBASE_GPHD_TEMPLATE_SPEC = "hdfs-hbase-gphd-template-spec.json";
    private static final String CM_HDFS_MAPRED_TEMPLATE_SPEC = "cm-hdfs-mapred-template-spec.json";
    private static final String CM_HDFS_YARN_TEMPLATE_SPEC = "cm-hdfs-yarn-template-spec.json";
    private static final String CM_HBASE_TEMPLATE_SPEC = "cm-hbase-template-spec.json";
    private static final String AM_HDFS_V1_TEMPLATE_SPEC = "am-hdfs-v1-template-spec.json";
    private static final String AM_HDFS_V2_TEMPLATE_SPEC = "am-hdfs-v2-template-spec.json";
    private static final String AM_HDFS_MAPRED_TEMPLATE_SPEC = "am-hdfs-mapred-template-spec.json";
    private static final String AM_HDP_2_0_HDFS_YARN_TEMPLATE_SPEC = "am-hdp-2-0-hdfs-yarn-template-spec.json";
    private static final String AM_HDP_2_1_HDFS_YARN_TEMPLATE_SPEC = "am-hdp-2-1-hdfs-yarn-template-spec.json";
    private static final String AM_HDP_2_2_HDFS_YARN_TEMPLATE_SPEC = "am-hdp-2-2-hdfs-yarn-template-spec.json";
    private static final String AM_HDP_2_3_HDFS_YARN_TEMPLATE_SPEC = "am-hdp-2-3-hdfs-yarn-template-spec.json";
    private static final String AM_HDP_CUSTOMIZED_HDFS_YARN_TEMPLATE_SPEC = "am-hdp-customized-hdfs-yarn-template-spec.json";
    private static final String AM_HDP_V1_HBASE_TEMPLATE_SPEC = "am-hdp-1-hbase-template-spec.json";
    private static final String AM_HDP_2_0_HBASE_TEMPLATE_SPEC = "am-hdp-2-0-hbase-template-spec.json";
    private static final String AM_HDP_2_1_HBASE_TEMPLATE_SPEC = "am-hdp-2-1-hbase-template-spec.json";
    private static final String AM_HDP_2_2_HBASE_TEMPLATE_SPEC = "am-hdp-2-2-hbase-template-spec.json";
    private static final String AM_HDP_2_3_HBASE_TEMPLATE_SPEC = "am-hdp-2-3-hbase-template-spec.json";
    private static final String AM_HDP_CUSTOMIZED_HBASE_TEMPLATE_SPEC = "am-hdp-customized-hbase-template-spec.json";
    private static final String AM_HDFS_PURE_HBASE_TEMPLATE_SPEC = "am-hdfs-pure-hbase-template-spec.json";

    private static File locateSpecFile(String filename, String appManagerType) {
        // try to locate file directly
        File specFile = new File(filename);
        if (specFile.exists()) {
            return specFile;
        }

        // search ${serengeti.home.dir}/conf directory
        String homeDir = System.getProperties().getProperty("serengeti.home.dir");
        if (homeDir != null && !homeDir.trim().isEmpty()) {
            StringBuilder builder = new StringBuilder();
            builder.append(homeDir).append(File.separator).append("conf").append(File.separator)
                    .append(appManagerType).append(File.separator).append("spec-templates").append(File.separator)
                    .append(filename);
            specFile = new File(builder.toString());
        }

        if (!specFile.exists()) {
            logger.warn("template cluster file does not exist: " + specFile.getAbsolutePath());
            // search in class paths
            URL filePath = ConfigurationUtils.locate(filename);
            if (filePath != null) {
                specFile = ConfigurationUtils.fileFromURL(filePath);
            }
        }

        if (!specFile.exists()) {
            throw BddException.INTERNAL(null, "Can not find template cluster spec file " + filename);
        }

        return specFile;
    }

    /**
     * Load and create cluster from spec file
     * 
     * @return cluster spec
     */
    public static ClusterCreate loadFromFile(File file) throws FileNotFoundException {
        Reader fileReader = null;
        try {
            fileReader = new FileReader(file);
            Gson gson = new Gson();
            return gson.fromJson(fileReader, ClusterCreate.class);
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    logger.error("Failed to release buffer: " + e.getMessage());
                }
            }
        }
    }

    /**
     * Create default cluster spec.
     * 
     * @param type
     *           cluster type
     * @return default cluster spec
     * @throws FileNotFoundException
     */
    public static ClusterCreate createDefaultSpec(ClusterType type, String vendor, String distroVersion,
            String appManagerType) throws FileNotFoundException {
        // loading from file each time is slow but fine
        if (vendor.trim().equalsIgnoreCase(Constants.MAPR_VENDOR)) {
            boolean isMapr3 = Version.compare(distroVersion, "4") < 0;
            switch (type) {
            case HDFS_MAPRED:
                return loadFromFile(
                        locateSpecFile(isMapr3 ? HDFS_MAPRED_MAPR_V3_TEMPLATE_SPEC : HDFS_MAPRED_MAPR_TEMPLATE_SPEC,
                                appManagerType));
            case HDFS_HBASE:
                return loadFromFile(
                        locateSpecFile(isMapr3 ? HDFS_HBASE_MAPR_V3_TEMPLATE_SPEC : HDFS_HBASE_MAPR_TEMPLATE_SPEC,
                                appManagerType));
            default:
                throw BddException.INVALID_PARAMETER("cluster type", type);
            }
        } else if (vendor.trim().equalsIgnoreCase(Constants.GPHD_VENDOR)) {
            switch (type) {
            case HDFS:
                return loadFromFile(locateSpecFile(HDFS_GPHD_TEMPLATE_SPEC, appManagerType));
            case HDFS_MAPRED:
                return loadFromFile(locateSpecFile(HDFS_MAPRED_GPHD_TEMPLATE_SPEC, appManagerType));
            case HDFS_HBASE:
                return loadFromFile(locateSpecFile(HDFS_HBASE_GPHD_TEMPLATE_SPEC, appManagerType));
            default:
                throw BddException.INVALID_PARAMETER("cluster type", type);
            }
        } else if (Constants.AMBARI_PLUGIN_TYPE.equals(appManagerType)
                && vendor.trim().equalsIgnoreCase(Constants.HDP_VENDOR)) {
            MAPREDUCE_VERSION mr = getDefaultMapReduceVersion(vendor, distroVersion);
            HDP_VERSION hdpVersion = getDefaultHdfsVersion(vendor, distroVersion);
            if (type == null) {
                if (mr == MAPREDUCE_VERSION.V1) {
                    return loadFromFile(locateSpecFile(AM_HDFS_MAPRED_TEMPLATE_SPEC, appManagerType));
                } else {
                    if (hdpVersion == HDP_VERSION.V2_0) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_0_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_1) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_1_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_2) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_2_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_3) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_3_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else {
                        return loadFromFile(
                                locateSpecFile(AM_HDP_CUSTOMIZED_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    }
                }
            }
            switch (type) {
            case HDFS:
                if (hdpVersion == HDP_VERSION.V1) {
                    return loadFromFile(locateSpecFile(AM_HDFS_V1_TEMPLATE_SPEC, appManagerType));
                } else {
                    return loadFromFile(locateSpecFile(AM_HDFS_V2_TEMPLATE_SPEC, appManagerType));
                }
            case HDFS_MAPRED:
                if (mr == MAPREDUCE_VERSION.V1) {
                    return loadFromFile(locateSpecFile(AM_HDFS_MAPRED_TEMPLATE_SPEC, appManagerType));
                } else {
                    if (hdpVersion == HDP_VERSION.V2_0) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_0_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_1) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_1_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_2) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_2_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else if (hdpVersion == HDP_VERSION.V2_3) {
                        return loadFromFile(locateSpecFile(AM_HDP_2_3_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    } else {
                        return loadFromFile(
                                locateSpecFile(AM_HDP_CUSTOMIZED_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                    }
                }
            case HDFS_HBASE:
                if (Configuration.getBoolean(Constants.AMBARI_HBASE_DEPEND_ON_MAPREDUCE)) {
                    if (hdpVersion == HDP_VERSION.V1) {
                        return loadFromFile(locateSpecFile(AM_HDP_V1_HBASE_TEMPLATE_SPEC, appManagerType));
                    } else {
                        if (hdpVersion == HDP_VERSION.V2_0) {
                            return loadFromFile(locateSpecFile(AM_HDP_2_0_HBASE_TEMPLATE_SPEC, appManagerType));
                        } else if (hdpVersion == HDP_VERSION.V2_1) {
                            return loadFromFile(locateSpecFile(AM_HDP_2_1_HBASE_TEMPLATE_SPEC, appManagerType));
                        } else if (hdpVersion == HDP_VERSION.V2_2) {
                            return loadFromFile(locateSpecFile(AM_HDP_2_2_HBASE_TEMPLATE_SPEC, appManagerType));
                        } else if (hdpVersion == HDP_VERSION.V2_3) {
                            return loadFromFile(locateSpecFile(AM_HDP_2_3_HBASE_TEMPLATE_SPEC, appManagerType));
                        } else {
                            return loadFromFile(
                                    locateSpecFile(AM_HDP_CUSTOMIZED_HBASE_TEMPLATE_SPEC, appManagerType));
                        }
                    }
                } else {
                    return loadFromFile(locateSpecFile(AM_HDFS_PURE_HBASE_TEMPLATE_SPEC, appManagerType));
                }
            default:
                throw BddException.INVALID_PARAMETER("cluster type", type);
            }
        } else {
            MAPREDUCE_VERSION mr = getDefaultMapReduceVersion(vendor, distroVersion);
            if (Constants.CLOUDERA_MANAGER_PLUGIN_TYPE.equals(appManagerType)) {
                if (type.equals(ClusterType.HDFS_HBASE)) {
                    return loadFromFile(locateSpecFile(CM_HBASE_TEMPLATE_SPEC, appManagerType));
                }
                if (mr == MAPREDUCE_VERSION.V1) {
                    return loadFromFile(locateSpecFile(CM_HDFS_MAPRED_TEMPLATE_SPEC, appManagerType));
                } else {
                    return loadFromFile(locateSpecFile(CM_HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                }
            }

            switch (type) {
            case HDFS:
                return loadFromFile(locateSpecFile(HDFS_TEMPLATE_SPEC, appManagerType));
            case HDFS_MAPRED:
                if (mr == MAPREDUCE_VERSION.V1) {
                    return loadFromFile(locateSpecFile(HDFS_MAPRED_TEMPLATE_SPEC, appManagerType));
                } else {
                    return loadFromFile(locateSpecFile(HDFS_YARN_TEMPLATE_SPEC, appManagerType));
                }
            case HDFS_HBASE:
                return loadFromFile(locateSpecFile(HDFS_HBASE_TEMPLATE_SPEC, appManagerType));
            default:
                return loadFromFile(
                        locateSpecFile(vendor.toLowerCase() + DEFAULT_TEMPLATE_SPEC_SUFFIX, appManagerType));
            }
        }
    }

    private static MAPREDUCE_VERSION getDefaultMapReduceVersion(String vendor, String distroVersion) {
        if (vendor.trim().equalsIgnoreCase(Constants.DEFAULT_VENDOR)) {
            return MAPREDUCE_VERSION.V2;
        }

        if (vendor.trim().equalsIgnoreCase(Constants.APACHE_VENDOR)) {
            return MAPREDUCE_VERSION.V1;
        }

        if (vendor.trim().equalsIgnoreCase(Constants.BIGTOP_VENDOR)) {
            return MAPREDUCE_VERSION.V2;
        }

        if (vendor.trim().equalsIgnoreCase(Constants.CDH_VENDOR)) {
            if (distroVersion.startsWith("5")) {
                return MAPREDUCE_VERSION.V2;
            } else {
                return MAPREDUCE_VERSION.V1;
            }
        }

        if (vendor.trim().equalsIgnoreCase(Constants.HDP_VENDOR)) {
            if (distroVersion.startsWith("2")) {
                return MAPREDUCE_VERSION.V2;
            } else {
                return MAPREDUCE_VERSION.V1;
            }
        }

        if (vendor.trim().equalsIgnoreCase(Constants.INTEL_VENDOR)) {
            if (distroVersion.startsWith("3")) {
                return MAPREDUCE_VERSION.V2;
            } else {
                return MAPREDUCE_VERSION.V1;
            }
        }

        if (vendor.trim().equalsIgnoreCase(Constants.PHD_VENDOR)) {
            return MAPREDUCE_VERSION.V2;
        }

        if (vendor.trim().equalsIgnoreCase(Constants.MAPR_VENDOR)) {
            return MAPREDUCE_VERSION.V1;
        }

        if (vendor.trim().equalsIgnoreCase(Constants.GPHD_VENDOR)) {
            return MAPREDUCE_VERSION.V1;
        }

        logger.error("Unknown distro vendor, return default mapreduce version 2");
        return MAPREDUCE_VERSION.V2;
    }

    private static HDP_VERSION getDefaultHdfsVersion(String vendor, String distroVersion) {

        if (vendor.trim().equalsIgnoreCase(Constants.HDP_VENDOR)) {
            if (Version.compare(distroVersion, "1.0") >= 0 && Version.compare(distroVersion, "2.0") < 0) {
                return HDP_VERSION.V1;
            } else if (Version.compare(distroVersion, "2.0") >= 0 && Version.compare(distroVersion, "2.1") < 0) {
                return HDP_VERSION.V2_0;
            } else if (Version.compare(distroVersion, "2.1") >= 0 && Version.compare(distroVersion, "2.2") < 0) {
                return HDP_VERSION.V2_1;
            } else if (Version.compare(distroVersion, "2.2") >= 0 && Version.compare(distroVersion, "2.3") < 0) {
                return HDP_VERSION.V2_2;
            } else if (Version.compare(distroVersion, "2.3") >= 0 && Version.compare(distroVersion, "2.4") < 0) {
                return HDP_VERSION.V2_3;
            } else {
                return HDP_VERSION.UNKNOWN;
            }
        }

        logger.error("Unknown distro HDP version");
        return HDP_VERSION.UNKNOWN;
    }

    /**
     * There are two approach to create a cluster: 1) specify a cluster type and
     * optionally overwriting the parameters 2) specify a customized spec with
     * cluster type not specified
     * 
     * @param spec
     *           spec with customized field
     * @return customized cluster spec
     * @throws FileNotFoundException
     */
    public static ClusterCreate getCustomizedSpec(ClusterCreate spec, String appManagerType)
            throws FileNotFoundException {

        if (!ArrayUtils.isEmpty(spec.getNodeGroups())) {
            spec.setSpecFile(true);
        }
        if (spec.isSpecFile()) {
            return spec;
        }

        ClusterCreate newSpec = createDefaultSpec(spec.getType(), spec.getDistroVendor(), spec.getDistroVersion(),
                appManagerType);

        // --name
        if (spec.getName() != null) {
            newSpec.setName(spec.getName());
        }

        //--password
        newSpec.setPassword(spec.getPassword());

        // --appManager
        if (!CommonUtil.isBlank(spec.getAppManager())) {
            newSpec.setAppManager(spec.getAppManager());
        }

        // --locaRepoURL
        if (!CommonUtil.isBlank(spec.getLocalRepoURL())) {
            newSpec.setLocalRepoURL(spec.getLocalRepoURL());
        }

        // --distro
        if (spec.getDistro() != null) {
            newSpec.setDistro(spec.getDistro());
        }

        //vendor
        if (spec.getDistroVendor() != null) {
            newSpec.setDistroVendor(spec.getDistroVendor());
        }

        //version
        if (spec.getDistroVersion() != null) {
            newSpec.setDistroVersion(spec.getDistroVersion());
        }

        // template name
        if (spec.getTemplateName() != null) {
            newSpec.setTemplateName(spec.getTemplateName());
        }

        // --dsNames
        if (spec.getDsNames() != null) {
            newSpec.setDsNames(spec.getDsNames());
        }

        // --rpNames
        if (spec.getRpNames() != null) {
            newSpec.setRpNames(spec.getRpNames());
        }

        // --networkConfig
        if (spec.getNetworkConfig() != null) {
            newSpec.setNetworkConfig(spec.getNetworkConfig());
        }

        // --topology
        if (spec.getTopologyPolicy() != null) {
            newSpec.setTopologyPolicy(spec.getTopologyPolicy());
        }

        if (MapUtils.isNotEmpty(spec.getInfrastructure_config())) {
            newSpec.setInfrastructure_config(spec.getInfrastructure_config());
        }

        return newSpec;
    }
}