/******************************************************************************* * =========================================================== * Ankush : Big Data Cluster Management Solution * =========================================================== * * (C) Copyright 2014, by Impetus Technologies * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License (LGPL v3) as * published by the Free Software Foundation; * * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ******************************************************************************/ package com.impetus.ankush2.cassandra.deployer; import java.util.HashMap; import java.util.Map; import net.neoremind.sshxcute.exception.TaskExecFailException; import net.neoremind.sshxcute.task.impl.ExecCommand; import com.impetus.ankush.common.exception.AnkushException; import com.impetus.ankush.common.utils.validator.DirectoryValidator; import com.impetus.ankush.common.utils.validator.JavaValidator; import com.impetus.ankush.common.utils.validator.ValidationResult; import com.impetus.ankush.common.utils.validator.ValidationUtility; import com.impetus.ankush.common.utils.validator.Validator; import com.impetus.ankush2.cassandra.utils.CassandraConstants; import com.impetus.ankush2.constant.Constant; import com.impetus.ankush2.framework.config.ClusterConfig; import com.impetus.ankush2.framework.config.ComponentConfig; import com.impetus.ankush2.framework.config.ComponentConfig.SourceType; import com.impetus.ankush2.framework.config.NodeConfig; import com.impetus.ankush2.logger.AnkushLogger; import com.impetus.ankush2.utils.SSHUtils; public class CassandraValidator { private AnkushLogger logger; private ClusterConfig clusterConfig; private NodeConfig nodeConfig; private ComponentConfig componentConfig; private boolean isError = false; public CassandraValidator(ClusterConfig clusterConfig, NodeConfig nodeConfig) { this.clusterConfig = clusterConfig; this.nodeConfig = nodeConfig; this.logger = new AnkushLogger(this.getClass(), this.clusterConfig); this.componentConfig = clusterConfig.getComponents().get( Constant.Component.Name.CASSANDRA); } public boolean validate() { try { logger.info("Validating " + Constant.Component.Name.CASSANDRA + "...", Constant.Component.Name.CASSANDRA, nodeConfig.getHost()); // validating node connection if (!validateConnection()) { return false; } // Validating whether bundle used for cluster deployment is of same // vendor as specified validateVendor(); // validation paths validatePath(); // Validating local bundle path and download url path validatingBundlePath(); validateJava(); validateJavaVersion(); } catch (AnkushException e) { addError(e.getMessage(), e); } catch (Exception e) { addError("Could not validate " + Constant.Component.Name.CASSANDRA, e); } return !isError; } /** Validation connection with node */ private boolean validateConnection() throws AnkushException { try { logger.debug("Validating connection.", nodeConfig.getHost()); return (nodeConfig.getConnection().exec(new ExecCommand("ls")).rc == 0); } catch (TaskExecFailException e) { throw new AnkushException( "Could not execute task for validating node connection."); } catch (Exception e) { throw new AnkushException( "Could not validating connection on node : " + nodeConfig.getHost()); } } /** * Validate path. * * @param connection * the connection */ private void validateVendor() throws AnkushException { try { String vendor = null; if (componentConfig.getVendor().equalsIgnoreCase("Datastax")) { vendor = CassandraConstants.Cassandra_vendors.CASSANDRA_VENDOR_DSC; } else if (componentConfig.getVendor().equalsIgnoreCase("Apache")) { vendor = CassandraConstants.Cassandra_vendors.CASSANDRA_VENDOR_APACHE; } else { throw new AnkushException(componentConfig.getVendor() + " vendor not supported."); } logger.info("Validating " + Constant.Component.Name.CASSANDRA + " vendor...", Constant.Component.Name.CASSANDRA, nodeConfig.getHost()); String errMsg = "The package provided for installation is of different vendor as specified"; String[] fileParts = componentConfig.getSource().split("/"); String[] packageParts = fileParts[fileParts.length - 1].split("-"); if (!packageParts[0].equals(vendor)) { throw new AnkushException(errMsg); } } catch (AnkushException e) { throw e; } catch (Exception e) { throw new AnkushException("Could not validate " + Constant.Component.Name.CASSANDRA + " vendor."); } } /** * Validate path. */ private void validatePath() throws AnkushException { try { logger.info("Validating " + Constant.Component.Name.CASSANDRA + " directories path.", nodeConfig.getHost()); Validator pathValidator; StringBuilder errMsg = new StringBuilder(""); for (Map.Entry<String, Boolean> directory : getDirectories() .entrySet()) { pathValidator = new DirectoryValidator( nodeConfig.getConnection(), directory.getKey(), directory.getValue()); if (!pathValidator.validate()) { errMsg.append(pathValidator.getErrMsg()); } } if (errMsg.length() > 0) { throw new AnkushException(errMsg.toString()); } } catch (AnkushException e) { throw e; } catch (Exception e) { throw new AnkushException("Could not validate " + Constant.Component.Name.CASSANDRA + " directories path."); } } private Map<String, Boolean> getDirectories() throws AnkushException { try { Map<String, Boolean> directoriesMap = new HashMap<String, Boolean>(); directoriesMap.put(componentConfig.getInstallPath(), true); directoriesMap .put(componentConfig .getAdvanceConfStringProperty(CassandraConstants.ClusterProperties.DATA_DIR), false); directoriesMap .put(componentConfig .getAdvanceConfStringProperty(CassandraConstants.ClusterProperties.LOG_DIR), false); directoriesMap .put(componentConfig .getAdvanceConfStringProperty(CassandraConstants.ClusterProperties.SAVED_CACHES_DIR), false); directoriesMap .put(componentConfig .getAdvanceConfStringProperty(CassandraConstants.ClusterProperties.COMMIT_LOG_DIR), false); return directoriesMap; } catch (Exception e) { throw new AnkushException("Could not get " + Constant.Component.Name.CASSANDRA + " directories path to validate."); } } /** Validating local bundle path and download url path **/ private void validatingBundlePath() throws AnkushException { try { ValidationResult status = null; // Validating the bundle path for the component. logger.info("Validating " + Constant.Component.Name.CASSANDRA + " " + String.valueOf(componentConfig.getSourceType()) .toLowerCase() + " path...", Constant.Component.Name.CASSANDRA, nodeConfig.getHost()); if ((componentConfig.getSourceType().equals(SourceType.LOCAL) && !componentConfig .getSource().isEmpty())) { status = ValidationUtility .isFileExists(nodeConfig.getConnection(), componentConfig.getSource()); } else if ((componentConfig.getSourceType().equals( SourceType.DOWNLOAD) && !componentConfig.getSource() .isEmpty())) { status = ValidationUtility .validateDownloadUrl(nodeConfig.getConnection(), componentConfig.getSource()); } else { throw new AnkushException( "Either " + Constant.Component.Name.CASSANDRA + " bundle source type is invalid or source value is empty."); } if (!status.isStatus()) { throw new AnkushException("Validating " + Constant.Component.Name.CASSANDRA + String.valueOf(componentConfig.getSourceType()) .toLowerCase() + " path failed..."); } } catch (AnkushException e) { throw e; } catch (Exception e) { throw new AnkushException("Could not validate " + Constant.Component.Name.CASSANDRA + " bundle path."); } } /** * Validating Java version for Cassandra 2.x */ private void validateJavaVersion() throws AnkushException { try { // Checking whether the major revision number of the Cassandra // package // version is 2 if (componentConfig.getVersion().split("\\.")[0].equals("2")) { // If Java is already installed, then checking its version if (clusterConfig.getJavaConf().isRegister()) { String username = clusterConfig.getAuthConf().getUsername(); String password = clusterConfig.getAuthConf() .isUsingPassword() ? clusterConfig.getAuthConf() .getPassword() : clusterConfig.getAuthConf() .getPrivateKey(); // Getting Java version String javaVersion = SSHUtils.getJavaVersion( nodeConfig.getHost(), username, password, clusterConfig.getAuthConf().isUsingPassword()); // Checking whether the minor revision number of Java // version is // 7 as Cassandra 2.x.x requires Java 1.7.x if (!javaVersion.split("\\.")[1].equals("7")) { throw new AnkushException( "Java version should be 1.7.x for " + Constant.Component.Name.CASSANDRA + componentConfig.getVersion() + " ..."); } } } } catch (AnkushException e) { throw e; } catch (Exception e) { throw new AnkushException( "Could not validate java version for Cassandra"); } } /** * Validate java. */ private void validateJava() throws AnkushException { try { logger.debug("Validating java.", nodeConfig.getHost()); Validator validator = new JavaValidator(nodeConfig.getConnection()); if (!validator.validate()) { throw new AnkushException(validator.getErrMsg()); } } catch (AnkushException e) { throw e; } catch (Exception e) { throw new AnkushException("Could not validate Java on " + nodeConfig.getHost()); } } /** adding error to clusterConf and logger */ private boolean addError(String error, Throwable t) { isError = true; clusterConfig.addError(nodeConfig.getHost(), Constant.Component.Name.CASSANDRA, error); logger.error(error, Constant.Component.Name.CASSANDRA, nodeConfig.getHost(), t); return false; } }