com.vmware.bdd.utils.CommonUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.bdd.utils.CommonUtil.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.utils;

import java.io.*;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Pattern;

import com.vmware.aurora.global.Configuration;
import com.vmware.aurora.util.StringUtil;
import com.vmware.bdd.apitypes.StorageRead;
import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.vmware.bdd.apitypes.NetworkDnsType;
import com.vmware.bdd.exception.BddException;
import org.springframework.batch.core.scope.context.ChunkContext;

public class CommonUtil {

    static final Logger logger = Logger.getLogger(CommonUtil.class);

    /*
    * Set file permission to 600
    */
    public static void setOwnerOnlyReadWrite(String filename) throws IOException {
        try {
            Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
            perms.add(PosixFilePermission.OWNER_READ);
            perms.add(PosixFilePermission.OWNER_WRITE);
            Files.setPosixFilePermissions(Paths.get(filename), perms);
        } catch (UnsupportedOperationException uoe) {
            logger.error("we are probably on windows! failed to set PosixFilePermission to: " + filename, uoe);
        }
    }

    public static String getConfDir() {
        String homeDir = System.getProperties().getProperty("serengeti.home.dir");
        if (StringUtil.isNullOrWhitespace(homeDir)) {
            homeDir = Constants.DEFAULT_SERENGETI_ROOT_DIR;
        }
        StringBuilder builder = new StringBuilder();
        builder.append(homeDir).append(File.separator).append("conf");
        return builder.toString();
    }

    public static File getConfigurationFile(final String filename, final String typeName) {
        // 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(getConfDir()).append(File.separator).append(filename);
            specFile = new File(builder.toString());

            if (!specFile.exists()) {
                logger.warn(typeName + " file does not exist: " + builder);
            } else {
                return specFile;
            }
        }

        // search in class paths
        URL filePath = ConfigurationUtils.locate(filename);
        if (filePath != null) {
            specFile = ConfigurationUtils.fileFromURL(filePath);
        }

        if (!specFile.exists()) {
            String errorMsg = "Can not find file " + filename;
            logger.fatal(errorMsg);
            throw new RuntimeException(errorMsg);
        }

        return specFile;
    }

    public static String readJsonFile(URL fileURL) {
        StringBuilder jsonBuff = new StringBuilder();
        if (fileURL != null) {
            String fileName = fileURL.getFile();
            InputStream in = null;
            try {
                in = new BufferedInputStream(fileURL.openStream());
                Reader rd = new InputStreamReader(in, "UTF-8");
                int c = 0;
                while ((c = rd.read()) != -1) {
                    jsonBuff.append((char) c);
                }
            } catch (IOException e) {
                logger.error(e.getMessage() + "\n Can not find " + fileName + " or IO read error.");
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    logger.error(e.getMessage() + "\n Can not close " + fileName + ".");
                }
            }
        }
        return jsonBuff.toString();
    }

    public static String readJsonFile(final String fileName) {
        URL fileURL = CommonUtil.class.getClassLoader().getResource(fileName);
        return readJsonFile(fileURL);
    }

    //TODO this is copied from CLI CommandsUtils
    public static String dataFromFile(String filePath) throws IOException, FileNotFoundException {
        StringBuffer dataStringBuffer = new StringBuffer();
        FileInputStream fis = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            fis = new FileInputStream(filePath);
            inputStreamReader = new InputStreamReader(fis, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                dataStringBuffer.append(line);
                dataStringBuffer.append("\n");
            }
        } finally {
            if (fis != null) {
                fis.close();
            }
            if (inputStreamReader != null) {
                inputStreamReader.close();
            }
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
        return dataStringBuffer.toString();
    }

    public static void gracefulRackTopologyOutput(Map<String, String> racksTopology, String filename,
            String delimeter) throws Exception {
        List<Object> list = new ArrayList<Object>();

        if (racksTopology != null && racksTopology.size() > 0) {
            Iterator<Entry<String, String>> it = racksTopology.entrySet().iterator();
            Map.Entry<String, String> entry = null;
            String vmIP = "";
            String rackPath = "";
            while (it.hasNext()) {
                entry = (Map.Entry<String, String>) it.next();
                vmIP = entry.getKey();
                rackPath = entry.getValue();
                StringBuffer buff = new StringBuffer();
                list.add(buff.append(vmIP).append(" ").append(rackPath).toString());
            }
        }

        prettyOutputStrings(list, filename, delimeter);
    }

    /*
     * throws IO Exception
     */
    public static void prettyOutputStrings(List<Object> objs, String fileName, String delimeter) throws Exception {
        StringBuffer buff = new StringBuffer();
        if (isBlank(delimeter)) {
            delimeter = System.lineSeparator();
        }

        for (Object obj : objs) {
            if (obj != null) {
                String str = obj.toString();
                if (!isBlank(str)) {
                    buff.append(str).append(delimeter);
                }
            }
        }
        if (buff.length() > 0) {
            buff.delete(buff.length() - delimeter.length(), buff.length());
        }

        OutputStream out = null;
        BufferedWriter bw = null;
        try {
            if (!isBlank(fileName)) {
                out = new FileOutputStream(fileName);
            } else {
                out = System.out;
            }
            bw = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            bw.write(buff.toString());
            if (!isBlank(fileName)) {
                // [Bug 1406542] always append a newline at the end of the file
                bw.newLine();
            }
            bw.flush();
        } finally {
            if (bw != null && out != null && !(out instanceof PrintStream)) {
                bw.close();
                out.close();
            }
        }
    }

    public static List<String> inputsConvert(String inputs) {
        List<String> names = new ArrayList<String>();
        for (String s : inputs.split(",")) {
            if (!s.trim().isEmpty()) {
                names.add(s.trim());
            }
        }
        return names;
    }

    public static Set<String> inputsConvertSet(String inputs) {
        Set<String> names = new HashSet<String>();
        for (String s : inputs.split(",")) {
            if (!s.trim().isEmpty()) {
                names.add(s.trim());
            }
        }
        return names;
    }

    public static String inputsConvert(Set<String> words) {
        String newWordStr = "";
        if (words != null && !words.isEmpty()) {
            StringBuffer wordsBuff = new StringBuffer();
            for (String word : words) {
                wordsBuff.append(word).append(",");
            }
            wordsBuff.delete(wordsBuff.length() - 1, wordsBuff.length());
            newWordStr = wordsBuff.toString();
        }
        return newWordStr;
    }

    public static <K, V> String inputsConvert(Map<K, V> wordsMap) {
        StringBuffer wordsBuff = new StringBuffer();
        if (wordsMap != null && !wordsMap.isEmpty()) {
            for (Entry<K, V> entry : wordsMap.entrySet()) {
                wordsBuff.append(entry.getKey()).append(":").append(entry.getValue()).append(",");
            }
            wordsBuff.delete(wordsBuff.length() - 1, wordsBuff.length());
        }
        return wordsBuff.toString();
    }

    public static boolean isBlank(final String str) {
        return str == null || str.trim().isEmpty();
    }

    public static String notNull(final String str, final String desStr) {
        return str == null ? desStr : str;
    }

    public static boolean validateVcResourceName(final String input) {
        return match(input, Constants.VC_RESOURCE_NAME_PATTERN);
    }

    public static boolean validateResourceName(final String input) {
        return match(input, Constants.RESOURCE_NAME_PATTERN);
    }

    public static boolean validateDistroName(final String input) {
        return match(input, Constants.DISTRO_NAME_PATTERN);
    }

    public static boolean validateClusterName(final String input) {
        return match(input, Constants.CLUSTER_NAME_PATTERN);
    }

    public static boolean validateNodeGroupName(final String input) {
        return match(input, Constants.NODE_GROUP_NAME_PATTERN);
    }

    public static boolean validataPathInfo(final String input) {
        return match(input, Constants.REST_REQUEST_PATH_INFO_PATTERN);
    }

    public static boolean validateVcDataStoreNames(List<String> names) {
        if (names == null || names.isEmpty()) {
            return false;
        }
        for (String name : names) {
            if (!validateVcDataStoreName(name)) {
                return false;
            }
        }
        return true;
    }

    private static boolean validateVcDataStoreName(final String input) {
        return match(input, Constants.VC_DATASTORE_NAME_PATTERN);
    }

    private static boolean match(final String input, final String regex) {
        Pattern pattern = Pattern.compile(regex);
        return pattern.matcher(input).matches();
    }

    public static boolean matchDatastorePattern(Set<String> patterns, Set<String> datastores) {
        for (String pattern : patterns) {
            // the datastore pattern should be converted to Java Regular Expression already
            for (String datastore : datastores) {
                try {
                    if (datastore.matches(pattern)) {
                        return true;
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    continue;
                }
            }
        }
        return false;
    }

    public static String escapePattern(String pattern) {
        return pattern.replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)");
    }

    public static String getDatastoreJavaPattern(String pattern) {
        return escapePattern(pattern).replace("?", ".").replace("*", ".*");
    }

    public static String getUUID() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    public static long makeVmMemoryDivisibleBy4(long memory) {
        if ((memory % 4) == 0) {
            return memory;
        } else {
            long temp = memory / 4;
            return temp * 4;
        }
    }

    public static boolean validateClusterPassword(String password) {
        Pattern pattern = Pattern.compile("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[_@#$%^&*]).{8,20})");
        if (pattern.matcher(password).matches()) {
            return true;
        }
        return false;
    }

    public static boolean passwordContainInvalidCharacter(String password) {
        Pattern pattern = Pattern.compile("[a-zA-Z0-9_@#$%^&*]+");
        if (!pattern.matcher(password).matches()) {
            return true;
        }
        return false;
    }

    public static char[] allChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_=+-/"
            .toCharArray();

    public static String randomString(int count) {
        return RandomStringUtils.random(count, allChars);
    }

    public static String getClusterName(String vmName) throws BddException {
        String[] split = splitVmName(vmName);
        return split[0];
    }

    public static long getVmIndex(String vmName) throws BddException {
        String[] split = splitVmName(vmName);
        try {
            return Long.valueOf(split[2]);
        } catch (Exception e) {
            logger.error("vm name " + vmName + " violate serengeti vm name definition.");
            throw BddException.VM_NAME_VIOLATE_NAME_PATTERN(vmName);
        }
    }

    private static String[] splitVmName(String vmName) {
        String[] split = vmName.split("-");
        if (split.length < 3) {
            throw BddException.VM_NAME_VIOLATE_NAME_PATTERN(vmName);
        }
        return split;
    }

    public static Process execCommand(String cmd) {
        if (cmd == null || cmd.isEmpty()) {
            return null;
        }

        Process p = null;
        try {
            p = new ProcessBuilder(Arrays.asList(cmd.split(" "))).start();
            p.waitFor();
        } catch (Exception e) {
            p = null;
            logger.error("Failed to execute command " + cmd + " : " + e.getMessage());
        }

        return p;
    }

    public static String decode(final String paramName) {
        try {
            return URLDecoder.decode(paramName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(), e);
            return paramName;
        }
    }

    public static String encode(final String paramName) {
        try {
            return URLEncoder.encode(paramName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(), e);
            return paramName;
        }
    }

    public static String getCurrentTimestamp() {
        return "[" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(Calendar.getInstance().getTime())
                + "]";
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    /*
     * transfer a byte array to a hexadecimal string
     */
    public static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(':');
        }
        if (sb.length() > 0) {
            sb.delete(sb.length() - 1, sb.length());
        }
        return sb.toString().toUpperCase();
    }

    public static KeyStore loadAppMgrKeyStore(String keystorePath) {
        File file = new File(keystorePath + Constants.APPMANAGER_KEYSTORE_FILE);
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security");
            file = new File(dir, Constants.APPMANAGER_KEYSTORE_FILE);
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }

        KeyStore keyStore = null;
        try {
            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        } catch (KeyStoreException e) {
            logger.error("Can't get KeyStore instance. ", e);
            return null;
        }
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            keyStore.load(in, Constants.APPMANAGER_KEYSTORE_PASSWORD);
        } catch (FileNotFoundException e) {
            logger.error("Can't find file " + file.getAbsolutePath(), e);
            return null;
        } catch (NoSuchAlgorithmException e) {
            logger.error("No such algorithm error during loading keystore.", e);
            return null;
        } catch (CertificateException e) {
            logger.error("Certificate exception during loading keystore.", e);
            return null;
        } catch (IOException e) {
            logger.error("Caught IO Exception.", e);
            return null;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.warn("Input stream of appmanagers.jks close failed.");
                }
            }
        }
        return keyStore;
    }

    public static boolean validateUrl(String url, List<String> errorMsgs) {
        if (errorMsgs == null) {
            errorMsgs = new ArrayList<String>();
        }
        boolean result = true;
        try {
            URI uri = new URI(url);
            String schema = uri.getScheme();
            if (!"https".equalsIgnoreCase(schema) && !"http".equalsIgnoreCase(schema)) {
                errorMsgs.add("URL should starts with http or https");
                result = false;
            }
            if ("https".equalsIgnoreCase(schema) && uri.getHost().matches(Constants.IP_PATTERN)) {
                errorMsgs.add("You should use FQDN instead of ip address when using https protocol");
                result = false;
            }
        } catch (URISyntaxException e) {
            logger.error("invalid URL syntax ", e);
            errorMsgs.add("invalid URL syntax");
            return false;
        }

        return result;
    }

    public static String mergeErrorMsgList(List<String> errorMsgs) {
        StringBuilder errorMsg = new StringBuilder();
        for (String msg : errorMsgs) {
            errorMsg.append(msg);
            errorMsg.append(", ");
        }
        return errorMsg.substring(0, errorMsg.length() - 2);
    }

    public static String formatWarningMsg(String warningMsg) {
        String msg;
        if (warningMsg != null && !warningMsg.startsWith("Warning:")) {
            msg = "Warning: " + warningMsg;
        } else {
            msg = warningMsg;
        }
        return msg;
    }

    /**
    *
    * @param host
    * @param port
    * @param waitTime
    */
    public static boolean checkServerConnection(final String host, final int port, int waitTime) {
        boolean connectResult = false;

        // validate the server is reachable
        ExecutorService exec = Executors.newFixedThreadPool(1);
        try {
            // if the target ip does not exist or the host is shutdown, it will take about 2 minutes
            // for the socket connection to time out.
            // here we fork a child thread to do the actual connecting action, if it does not succeed
            // within given waitTime, we will consider it to be failure.
            Future<Boolean> futureResult = exec.submit(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    try {
                        new Socket(host, port);
                        return true;
                    } catch (Exception e) {
                    }
                    return false;
                }
            });

            // wait for the thread to finish within given waitTime
            Boolean result = (Boolean) waitForThreadResult(futureResult, waitTime);

            // result==null means the time out occurs
            if (null != result) {
                connectResult = result;
            }
        } catch (Exception e) {
            logger.error("Unexpected error occurred with threading.");
        } finally {
            if (null != exec) {
                exec.shutdown();
            }
        }

        return connectResult;
    }

    public static Object waitForThreadResult(Future<?> result, int waitTime) {
        for (int i = 0; i < waitTime; i++) {
            try {
                if (result.isDone()) {
                    return result.get();
                }

                // sleep 1 second here
                Thread.sleep(1000);
            } catch (Exception e) {
                logger.error("Unexpected error occurred with threading.");
            }
        }

        // time out now
        return null;
    }

    public static boolean validateDnsType(NetworkDnsType dnsType) {
        if (NetworkDnsType.isDynamic(dnsType) || NetworkDnsType.isNormal(dnsType)
                || NetworkDnsType.isOthers(dnsType)) {
            return true;
        } else {
            return false;
        }
    }

    public static void writeFile(File file, String content) {
        writeFile(file, content, false);
    }

    public static void writeFile(File file, String content, boolean append) {
        OutputStream out = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, append);
            bw = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
            bw.write(content);
            bw.flush();
        } catch (IOException e) {
            logger.warn("Write file failed : " + e.getMessage());
        } finally {
            if (bw != null && out != null) {
                try {
                    bw.close();
                    out.close();
                } catch (IOException e) {
                    logger.warn("Close file failed : " + e.getMessage());
                }
            }
        }
    }

    public static boolean getBooleanFromString(String booleanString, boolean defaultValue) {
        boolean ret = defaultValue;
        if (!StringUtils.isBlank(booleanString)) {
            ret = Boolean.valueOf(booleanString);
        }
        return ret;
    }

    public static String getCustomizedSudoCmd() {
        return Configuration.getString(Constants.SUDO_COMMAND, Constants.DEFAULT_SUDO_COMMAND);
    }

    public static StorageRead.DiskScsiControllerType getSystemAndSwapControllerType() {
        String controllerType;
        try {
            controllerType = Configuration.getString(Constants.SYSTEM_AND_SWAP_DISK_CONTROLLER_TYPE);
        } catch (NoSuchElementException e) {
            controllerType = null;
        }
        if (controllerType == null || controllerType
                .equalsIgnoreCase(StorageRead.DiskScsiControllerType.LSI_CONTROLLER.getDisplayName())) {
            return StorageRead.DiskScsiControllerType.LSI_CONTROLLER;
        } else if (controllerType
                .equalsIgnoreCase(StorageRead.DiskScsiControllerType.PARA_VIRTUAL_CONTROLLER.getDisplayName())) {
            return StorageRead.DiskScsiControllerType.PARA_VIRTUAL_CONTROLLER;
        } else {
            throw BddException.INVALID_PARAMETER(Constants.SYSTEM_AND_SWAP_DISK_CONTROLLER_TYPE, controllerType);
        }
    }

    public static StorageRead.DiskScsiControllerType getDataDiskControllerType() {
        String controllerType;
        try {
            controllerType = Configuration.getString(Constants.DATA_DISK_CONTROLLER_TYPE);
        } catch (NoSuchElementException e) {
            controllerType = null;
        }
        if (controllerType == null || controllerType
                .equalsIgnoreCase(StorageRead.DiskScsiControllerType.PARA_VIRTUAL_CONTROLLER.getDisplayName())) {
            return StorageRead.DiskScsiControllerType.PARA_VIRTUAL_CONTROLLER;
        } else if (controllerType
                .equalsIgnoreCase(StorageRead.DiskScsiControllerType.LSI_CONTROLLER.getDisplayName())) {
            return StorageRead.DiskScsiControllerType.LSI_CONTROLLER;
        } else {
            throw BddException.INVALID_PARAMETER(Constants.DATA_DISK_CONTROLLER_TYPE, controllerType);
        }
    }
}