All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.nacos.sys.env.EnvUtil Maven / Gradle / Ivy

/*
 *  Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 *  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.alibaba.nacos.sys.env;

import com.alibaba.nacos.common.JustForTest;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.ThreadUtils;
import com.alibaba.nacos.sys.utils.DiskUtils;
import com.alibaba.nacos.sys.utils.InetUtils;
import com.sun.management.OperatingSystemMXBean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.management.ManagementFactory;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Its own configuration information manipulation tool class.
 *
 * @author liaochuntao
 */
public class EnvUtil {
    
    public static final String STANDALONE_MODE_ALONE = "standalone";
    
    public static final String STANDALONE_MODE_CLUSTER = "cluster";
    
    public static final String FUNCTION_MODE_CONFIG = "config";
    
    public static final String FUNCTION_MODE_NAMING = "naming";
    
    /**
     * The key of nacos home.
     */
    public static final String NACOS_HOME_KEY = "nacos.home";
    
    private static String localAddress = "";
    
    private static int port = -1;
    
    private static Boolean isStandalone = null;
    
    private static String functionModeType = null;
    
    private static String contextPath = null;
    
    private static final String FILE_PREFIX = "file:";
    
    private static final String SERVER_PORT_PROPERTY = "server.port";
    
    private static final int DEFAULT_SERVER_PORT = 8848;
    
    private static final String DEFAULT_WEB_CONTEXT_PATH = "/nacos";
    
    private static final String MEMBER_LIST_PROPERTY = "nacos.member.list";
    
    private static final String NACOS_HOME_PROPERTY = "user.home";
    
    private static final String CUSTOM_CONFIG_LOCATION_PROPERTY = "spring.config.additional-location";
    
    private static final String DEFAULT_CONFIG_LOCATION  = "application.properties";
    
    private static final String DEFAULT_RESOURCE_PATH = "/application.properties";
    
    private static final String DEFAULT_ADDITIONAL_PATH = "conf";
    
    private static final String DEFAULT_ADDITIONAL_FILE = "cluster.conf";
    
    private static final String NACOS_HOME_ADDITIONAL_FILEPATH = "nacos";
    
    private static final String NACOS_TEMP_DIR_1 = "data";
    
    private static final String NACOS_TEMP_DIR_2 = "tmp";
    
    @JustForTest
    private static String confPath = "";
    
    @JustForTest
    private static String nacosHomePath = null;
    
    private static final OperatingSystemMXBean OPERATING_SYSTEM_MX_BEAN = (com.sun.management.OperatingSystemMXBean) ManagementFactory
            .getOperatingSystemMXBean();
    
    private static ConfigurableEnvironment environment;
    
    public static ConfigurableEnvironment getEnvironment() {
        return environment;
    }
    
    public static void setEnvironment(ConfigurableEnvironment environment) {
        EnvUtil.environment = environment;
    }
    
    public static boolean containsProperty(String key) {
        return environment.containsProperty(key);
    }
    
    public static String getProperty(String key) {
        return environment.getProperty(key);
    }
    
    public static String getProperty(String key, String defaultValue) {
        return environment.getProperty(key, defaultValue);
    }
    
    public static  T getProperty(String key, Class targetType) {
        return environment.getProperty(key, targetType);
    }
    
    public static  T getProperty(String key, Class targetType, T defaultValue) {
        return environment.getProperty(key, targetType, defaultValue);
    }
    
    public static String getRequiredProperty(String key) throws IllegalStateException {
        return environment.getRequiredProperty(key);
    }
    
    public static  T getRequiredProperty(String key, Class targetType) throws IllegalStateException {
        return environment.getRequiredProperty(key, targetType);
    }
    
    public static String resolvePlaceholders(String text) {
        return environment.resolvePlaceholders(text);
    }
    
    public static String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
        return environment.resolveRequiredPlaceholders(text);
    }
    
    public static List getPropertyList(String key) {
        List valueList = new ArrayList<>();
        
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String value = environment.getProperty(key + "[" + i + "]");
            if (StringUtils.isBlank(value)) {
                break;
            }
            
            valueList.add(value);
        }
        
        return valueList;
    }
    
    public static String getLocalAddress() {
        if (StringUtils.isBlank(localAddress)) {
            localAddress = InetUtils.getSelfIP() + ":" + getPort();
        }
        return localAddress;
    }
    
    public static void setLocalAddress(String localAddress) {
        EnvUtil.localAddress = localAddress;
    }
    
    public static int getPort() {
        if (port == -1) {
            port = getProperty(SERVER_PORT_PROPERTY, Integer.class, DEFAULT_SERVER_PORT);
        }
        return port;
    }
    
    public static void setPort(int port) {
        EnvUtil.port = port;
    }
    
    public static String getContextPath() {
        if (Objects.isNull(contextPath)) {
            contextPath = getProperty(Constants.WEB_CONTEXT_PATH, DEFAULT_WEB_CONTEXT_PATH);
            if (Constants.ROOT_WEB_CONTEXT_PATH.equals(contextPath)) {
                contextPath = StringUtils.EMPTY;
            }
        }
        return contextPath;
    }
    
    public static void setContextPath(String contextPath) {
        EnvUtil.contextPath = contextPath;
    }
    
    @JustForTest
    public static void setIsStandalone(Boolean isStandalone) {
        EnvUtil.isStandalone = isStandalone;
    }
    
    /**
     * Standalone mode or not.
     */
    public static boolean getStandaloneMode() {
        if (Objects.isNull(isStandalone)) {
            isStandalone = Boolean.getBoolean(Constants.STANDALONE_MODE_PROPERTY_NAME);
        }
        return isStandalone;
    }
    
    /**
     * server function mode.
     */
    public static String getFunctionMode() {
        if (StringUtils.isEmpty(functionModeType)) {
            functionModeType = System.getProperty(Constants.FUNCTION_MODE_PROPERTY_NAME);
        }
        return functionModeType;
    }
    
    private static String nacosTmpDir;
    
    public static String getNacosTmpDir() {
        if (StringUtils.isBlank(nacosTmpDir)) {
            nacosTmpDir = Paths.get(getNacosHome(), NACOS_TEMP_DIR_1, NACOS_TEMP_DIR_2).toString();
        }
        return nacosTmpDir;
    }
    
    public static String getNacosHome() {
        if (StringUtils.isBlank(nacosHomePath)) {
            String nacosHome = System.getProperty(NACOS_HOME_KEY);
            if (StringUtils.isBlank(nacosHome)) {
                nacosHome = Paths.get(System.getProperty(NACOS_HOME_PROPERTY), NACOS_HOME_ADDITIONAL_FILEPATH).toString();
            }
            return nacosHome;
        }
        // test-first
        return nacosHomePath;
    }
    
    @JustForTest
    public static void setNacosHomePath(String nacosHomePath) {
        EnvUtil.nacosHomePath = nacosHomePath;
    }
    
    public static List getIPsBySystemEnv(String key) {
        String env = getSystemEnv(key);
        List ips = new ArrayList<>();
        if (StringUtils.isNotEmpty(env)) {
            ips = Arrays.asList(env.split(","));
        }
        return ips;
    }
    
    public static String getSystemEnv(String key) {
        return System.getenv(key);
    }
    
    public static float getLoad() {
        return (float) OPERATING_SYSTEM_MX_BEAN.getSystemLoadAverage();
    }
    
    @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
    public static float getCPU() {
        return (float) OPERATING_SYSTEM_MX_BEAN.getSystemCpuLoad();
    }
    
    public static float getMem() {
        return (float) (1
                - (double) OPERATING_SYSTEM_MX_BEAN.getFreePhysicalMemorySize() / (double) OPERATING_SYSTEM_MX_BEAN
                .getTotalPhysicalMemorySize());
    }
    
    public static String getConfPath() {
        if (StringUtils.isNotBlank(EnvUtil.confPath)) {
            return EnvUtil.confPath;
        }
        EnvUtil.confPath = Paths.get(getNacosHome(), DEFAULT_ADDITIONAL_PATH).toString();
        return confPath;
    }
    
    public static void setConfPath(final String confPath) {
        EnvUtil.confPath = confPath;
    }
    
    public static String getClusterConfFilePath() {
        return Paths.get(getNacosHome(), DEFAULT_ADDITIONAL_PATH, DEFAULT_ADDITIONAL_FILE).toString();
    }
    
    /**
     * read cluster.conf to ip list.
     *
     * @return ip list.
     * @throws IOException ioexception {@link IOException}
     */
    public static List readClusterConf() throws IOException {
        try (Reader reader = new InputStreamReader(new FileInputStream(new File(getClusterConfFilePath())),
                StandardCharsets.UTF_8)) {
            return analyzeClusterConf(reader);
        } catch (FileNotFoundException ignore) {
            List tmp = new ArrayList<>();
            String clusters = EnvUtil.getMemberList();
            if (StringUtils.isNotBlank(clusters)) {
                String[] details = clusters.split(",");
                for (String item : details) {
                    tmp.add(item.trim());
                }
            }
            return tmp;
        }
    }
    
    /**
     * read file stream to ip list.
     *
     * @param reader reader
     * @return ip list.
     * @throws IOException IOException
     */
    public static List analyzeClusterConf(Reader reader) throws IOException {
        List instanceList = new ArrayList();
        List lines = IoUtils.readLines(reader);
        String comment = "#";
        for (String line : lines) {
            String instance = line.trim();
            if (instance.startsWith(comment)) {
                // # it is ip
                continue;
            }
            if (instance.contains(comment)) {
                // 192.168.71.52:8848 # Instance A
                instance = instance.substring(0, instance.indexOf(comment));
                instance = instance.trim();
            }
            int multiIndex = instance.indexOf(Constants.COMMA_DIVISION);
            if (multiIndex > 0) {
                // support the format: ip1:port,ip2:port  # multi inline
                instanceList.addAll(Arrays.asList(instance.split(Constants.COMMA_DIVISION)));
            } else {
                //support the format: 192.168.71.52:8848
                instanceList.add(instance);
            }
        }
        return instanceList;
    }
    
    public static void writeClusterConf(String content) throws IOException {
        DiskUtils.writeFile(new File(getClusterConfFilePath()), content.getBytes(StandardCharsets.UTF_8), false);
    }
    
    public static String getMemberList() {
        String val;
        if (environment == null) {
            val = System.getenv(MEMBER_LIST_PROPERTY);
            if (StringUtils.isBlank(val)) {
                val = System.getProperty(MEMBER_LIST_PROPERTY);
            }
        } else {
            val = getProperty(MEMBER_LIST_PROPERTY);
        }
        return val;
    }
    
    /**
     * load resource to map.
     *
     * @param resource resource
     * @return Map<String, Object>
     * @throws IOException IOException
     */
    public static Map loadProperties(Resource resource) throws IOException {
        return new OriginTrackedPropertiesLoader(resource).load();
    }
    
    public static Resource getApplicationConfFileResource() {
        Resource customResource = getCustomFileResource();
        return customResource == null ? getDefaultResource() : customResource;
    }
    
    private static Resource getCustomFileResource() {
        String path = getProperty(CUSTOM_CONFIG_LOCATION_PROPERTY);
        if (StringUtils.isNotBlank(path) && path.contains(FILE_PREFIX)) {
            String[] paths = path.split(",", -1);
            path = paths[paths.length - 1].substring(FILE_PREFIX.length());
            return getRelativePathResource(path, DEFAULT_CONFIG_LOCATION);
        }
        return null;
    }
    
    private static Resource getRelativePathResource(String parentPath, String path) {
        try {
            InputStream inputStream = new FileInputStream(Paths.get(parentPath, path).toFile());
            return new InputStreamResource(inputStream);
        } catch (Exception ignore) {
        }
        return null;
    }
    
    private static Resource getDefaultResource() {
        InputStream inputStream = EnvUtil.class.getResourceAsStream(DEFAULT_RESOURCE_PATH);
        return new InputStreamResource(inputStream);
    }
    
    /**
     * Get available processor numbers from environment.
     *
     * 

* If there are setting of {@code nacos.core.sys.basic.processors} in config/JVM/system, use it. * If no setting, use the one time {@code ThreadUtils.getSuitableThreadCount()}. *

* * @return available processor numbers from environment, will not lower than 1. */ public static int getAvailableProcessors() { int result = getProperty(Constants.AVAILABLE_PROCESSORS_BASIC, int.class, ThreadUtils.getSuitableThreadCount(1)); return result > 0 ? result : 1; } /** * Get a multiple time of available processor numbers from environment. * * @param multiple multiple of available processor numbers * @return available processor numbers from environment, will not lower than 1. */ public static int getAvailableProcessors(int multiple) { if (multiple < 1) { throw new IllegalArgumentException("processors multiple must upper than 1"); } Integer processor = getProperty(Constants.AVAILABLE_PROCESSORS_BASIC, Integer.class); return null != processor && processor > 0 ? processor * multiple : ThreadUtils.getSuitableThreadCount(multiple); } /** * Get a scale of available processor numbers from environment. * * @param scale scale from 0 to 1. * @return available processor numbers from environment, will not lower than 1. */ public static int getAvailableProcessors(double scale) { if (scale < 0 || scale > 1) { throw new IllegalArgumentException("processors scale must between 0 and 1"); } double result = getProperty(Constants.AVAILABLE_PROCESSORS_BASIC, int.class, ThreadUtils.getSuitableThreadCount(1)) * scale; return result > 1 ? (int) result : 1; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy