----初始化项目
This commit is contained in:
71
sys/pom.xml
Normal file
71
sys/pom.xml
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>nacos-sys</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>nacos-sys ${project.version}</name>
|
||||
<url>https://nacos.io</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-custom-environment-plugin</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
83
sys/src/main/java/com/alibaba/nacos/sys/env/Constants.java
vendored
Normal file
83
sys/src/main/java/com/alibaba/nacos/sys/env/Constants.java
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Nacos common constants.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 0.2.2
|
||||
*/
|
||||
public interface Constants {
|
||||
|
||||
String SYS_MODULE = "sys";
|
||||
|
||||
/**
|
||||
* Spring Profile : "standalone".
|
||||
*/
|
||||
String STANDALONE_SPRING_PROFILE = "standalone";
|
||||
|
||||
/**
|
||||
* The System property name of Standalone mode.
|
||||
*/
|
||||
String STANDALONE_MODE_PROPERTY_NAME = "nacos.standalone";
|
||||
|
||||
String STARTUP_MODE_STATE = "startup_mode";
|
||||
|
||||
/**
|
||||
* The System property name of Function mode.
|
||||
*/
|
||||
String FUNCTION_MODE_PROPERTY_NAME = "nacos.functionMode";
|
||||
|
||||
String FUNCTION_MODE_STATE = "function_mode";
|
||||
|
||||
/**
|
||||
* The System property name of prefer hostname over ip.
|
||||
*/
|
||||
String PREFER_HOSTNAME_OVER_IP_PROPERTY_NAME = "nacos.preferHostnameOverIp";
|
||||
|
||||
/**
|
||||
* the root context path.
|
||||
*/
|
||||
String ROOT_WEB_CONTEXT_PATH = "/";
|
||||
|
||||
String NACOS_VERSION = "version";
|
||||
|
||||
String NACOS_SERVER_IP = "nacos.server.ip";
|
||||
|
||||
String NACOS_SERVER_IP_STATE = "nacos_server_ip";
|
||||
|
||||
String SERVER_PORT_STATE = "server_port";
|
||||
|
||||
String USE_ONLY_SITE_INTERFACES = "nacos.inetutils.use-only-site-local-interfaces";
|
||||
String PREFERRED_NETWORKS = "nacos.inetutils.preferred-networks";
|
||||
String IGNORED_INTERFACES = "nacos.inetutils.ignored-interfaces";
|
||||
String AUTO_REFRESH_TIME = "nacos.core.inet.auto-refresh";
|
||||
String IP_ADDRESS = "nacos.inetutils.ip-address";
|
||||
String PREFER_HOSTNAME_OVER_IP = "nacos.inetutils.prefer-hostname-over-ip";
|
||||
String SYSTEM_PREFER_HOSTNAME_OVER_IP = "nacos.preferHostnameOverIp";
|
||||
String WEB_CONTEXT_PATH = "server.servlet.context-path";
|
||||
String COMMA_DIVISION = ",";
|
||||
|
||||
String NACOS_SERVER_HEADER = "Nacos-Server";
|
||||
|
||||
String REQUEST_PATH_SEPARATOR = "-->";
|
||||
|
||||
String AVAILABLE_PROCESSORS_BASIC = "nacos.core.sys.basic.processors";
|
||||
|
||||
String SUPPORT_UPGRADE_FROM_1X = "nacos.core.support.upgrade.from.1x";
|
||||
}
|
||||
41
sys/src/main/java/com/alibaba/nacos/sys/env/EnvModuleStateBuilder.java
vendored
Normal file
41
sys/src/main/java/com/alibaba/nacos/sys/env/EnvModuleStateBuilder.java
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.utils.VersionUtils;
|
||||
import com.alibaba.nacos.sys.module.ModuleState;
|
||||
import com.alibaba.nacos.sys.module.ModuleStateBuilder;
|
||||
|
||||
/**
|
||||
* Module state builder for env module.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class EnvModuleStateBuilder implements ModuleStateBuilder {
|
||||
|
||||
@Override
|
||||
public ModuleState build() {
|
||||
ModuleState state = new ModuleState(Constants.SYS_MODULE);
|
||||
state.newState(Constants.STARTUP_MODE_STATE,
|
||||
EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER);
|
||||
state.newState(Constants.FUNCTION_MODE_STATE, EnvUtil.getFunctionMode());
|
||||
state.newState(Constants.NACOS_VERSION, VersionUtils.version);
|
||||
|
||||
state.newState(Constants.SERVER_PORT_STATE, EnvUtil.getPort());
|
||||
return state;
|
||||
}
|
||||
}
|
||||
489
sys/src/main/java/com/alibaba/nacos/sys/env/EnvUtil.java
vendored
Normal file
489
sys/src/main/java/com/alibaba/nacos/sys/env/EnvUtil.java
vendored
Normal file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
* 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.plugin.environment.CustomEnvironmentPluginManager;
|
||||
import com.alibaba.nacos.sys.utils.DiskUtils;
|
||||
import com.alibaba.nacos.sys.utils.InetUtils;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
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.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;
|
||||
import java.util.Set;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Its own configuration information manipulation tool class.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
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 volatile 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";
|
||||
|
||||
private static final String NACOS_CUSTOM_ENVIRONMENT_ENABLED = "nacos.custom.environment.enabled";
|
||||
|
||||
private static final String NACOS_CUSTOM_CONFIG_NAME = "customFirstNacosConfig";
|
||||
|
||||
@JustForTest
|
||||
private static String confPath = "";
|
||||
|
||||
@JustForTest
|
||||
private static String nacosHomePath = null;
|
||||
|
||||
private static ConfigurableEnvironment environment;
|
||||
|
||||
/**
|
||||
* customEnvironment.
|
||||
*/
|
||||
public static void customEnvironment() {
|
||||
boolean enableCustom = getProperty(NACOS_CUSTOM_ENVIRONMENT_ENABLED, Boolean.class, false);
|
||||
if (enableCustom) {
|
||||
Set<String> propertyKeys = CustomEnvironmentPluginManager.getInstance().getPropertyKeys();
|
||||
Map<String, Object> sourcePropertyMap = new HashMap<>(propertyKeys.size());
|
||||
for (String key : propertyKeys) {
|
||||
sourcePropertyMap.put(key, getProperty(key, Object.class));
|
||||
}
|
||||
Map<String, Object> targetMap = CustomEnvironmentPluginManager.getInstance()
|
||||
.getCustomValues(sourcePropertyMap);
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
propertySources.addFirst(new MapPropertySource(NACOS_CUSTOM_CONFIG_NAME, targetMap));
|
||||
}
|
||||
}
|
||||
|
||||
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> T getProperty(String key, Class<T> targetType) {
|
||||
return environment.getProperty(key, targetType);
|
||||
}
|
||||
|
||||
public static <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
|
||||
return environment.getProperty(key, targetType, defaultValue);
|
||||
}
|
||||
|
||||
public static String getRequiredProperty(String key) throws IllegalStateException {
|
||||
return environment.getRequiredProperty(key);
|
||||
}
|
||||
|
||||
public static <T> T getRequiredProperty(String key, Class<T> 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<String> getPropertyList(String key) {
|
||||
List<String> 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 void systemExit() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
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<String> getIPsBySystemEnv(String key) {
|
||||
String env = getSystemEnv(key);
|
||||
List<String> 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) OperatingSystemBeanManager.getOperatingSystemBean().getSystemLoadAverage();
|
||||
}
|
||||
|
||||
public static float getCpu() {
|
||||
return (float) OperatingSystemBeanManager.getSystemCpuUsage();
|
||||
}
|
||||
|
||||
public static float getMem() {
|
||||
return (float) (1
|
||||
- OperatingSystemBeanManager.getFreePhysicalMem() / OperatingSystemBeanManager.getTotalPhysicalMem());
|
||||
}
|
||||
|
||||
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<String> readClusterConf() throws IOException {
|
||||
try (Reader reader = new InputStreamReader(new FileInputStream(getClusterConfFilePath()),
|
||||
StandardCharsets.UTF_8)) {
|
||||
return analyzeClusterConf(reader);
|
||||
} catch (FileNotFoundException ignore) {
|
||||
List<String> 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<String> analyzeClusterConf(Reader reader) throws IOException {
|
||||
List<String> instanceList = new ArrayList<String>();
|
||||
List<String> 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<String, ?> 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.
|
||||
*
|
||||
* <p>
|
||||
* 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()}.
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
116
sys/src/main/java/com/alibaba/nacos/sys/env/OperatingSystemBeanManager.java
vendored
Normal file
116
sys/src/main/java/com/alibaba/nacos/sys/env/OperatingSystemBeanManager.java
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.sys.utils.MethodUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* OperatingSystemBeanManager related.
|
||||
*
|
||||
* @author yanhom
|
||||
*/
|
||||
public class OperatingSystemBeanManager {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(OperatingSystemBeanManager.class);
|
||||
|
||||
/**
|
||||
* com.ibm for J9
|
||||
* com.sun for HotSpot
|
||||
*/
|
||||
private static final List<String> OPERATING_SYSTEM_BEAN_CLASS_NAMES = Arrays.asList(
|
||||
"com.sun.management.OperatingSystemMXBean", "com.ibm.lang.management.OperatingSystemMXBean");
|
||||
|
||||
private static final OperatingSystemMXBean OPERATING_SYSTEM_BEAN;
|
||||
|
||||
private static final Class<?> OPERATING_SYSTEM_BEAN_CLASS;
|
||||
|
||||
private static final Method SYSTEM_CPU_USAGE_METHOD;
|
||||
|
||||
private static final Method PROCESS_CPU_USAGE_METHOD;
|
||||
|
||||
private static final Method FREE_PHYSICAL_MEM_METHOD;
|
||||
|
||||
private static final Method TOTAL_PHYSICAL_MEM_METHOD;
|
||||
|
||||
static {
|
||||
OPERATING_SYSTEM_BEAN = ManagementFactory.getOperatingSystemMXBean();
|
||||
OPERATING_SYSTEM_BEAN_CLASS = loadOne(OPERATING_SYSTEM_BEAN_CLASS_NAMES);
|
||||
SYSTEM_CPU_USAGE_METHOD = deduceMethod("getSystemCpuLoad");
|
||||
PROCESS_CPU_USAGE_METHOD = deduceMethod("getProcessCpuLoad");
|
||||
|
||||
Method totalPhysicalMem = deduceMethod("getTotalPhysicalMemorySize");
|
||||
// getTotalPhysicalMemory for ibm jdk 7.
|
||||
TOTAL_PHYSICAL_MEM_METHOD = totalPhysicalMem != null ? totalPhysicalMem :
|
||||
deduceMethod("getTotalPhysicalMemory");
|
||||
|
||||
FREE_PHYSICAL_MEM_METHOD = deduceMethod("getFreePhysicalMemorySize");
|
||||
}
|
||||
|
||||
private OperatingSystemBeanManager() {}
|
||||
|
||||
public static OperatingSystemMXBean getOperatingSystemBean() {
|
||||
return OPERATING_SYSTEM_BEAN;
|
||||
}
|
||||
|
||||
public static double getSystemCpuUsage() {
|
||||
return MethodUtil.invokeAndReturnDouble(SYSTEM_CPU_USAGE_METHOD, OPERATING_SYSTEM_BEAN);
|
||||
}
|
||||
|
||||
public static double getProcessCpuUsage() {
|
||||
return MethodUtil.invokeAndReturnDouble(PROCESS_CPU_USAGE_METHOD, OPERATING_SYSTEM_BEAN);
|
||||
}
|
||||
|
||||
public static long getTotalPhysicalMem() {
|
||||
return MethodUtil.invokeAndReturnLong(TOTAL_PHYSICAL_MEM_METHOD, OPERATING_SYSTEM_BEAN);
|
||||
}
|
||||
|
||||
public static long getFreePhysicalMem() {
|
||||
return MethodUtil.invokeAndReturnLong(FREE_PHYSICAL_MEM_METHOD, OPERATING_SYSTEM_BEAN);
|
||||
}
|
||||
|
||||
private static Class<?> loadOne(List<String> classNames) {
|
||||
for (String className : classNames) {
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOGGER.warn("[OperatingSystemBeanManager] Failed to load operating system bean class.", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method deduceMethod(String name) {
|
||||
if (Objects.isNull(OPERATING_SYSTEM_BEAN_CLASS)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
OPERATING_SYSTEM_BEAN_CLASS.cast(OPERATING_SYSTEM_BEAN);
|
||||
return OPERATING_SYSTEM_BEAN_CLASS.getDeclaredMethod(name);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
259
sys/src/main/java/com/alibaba/nacos/sys/env/OriginTrackedPropertiesLoader.java
vendored
Normal file
259
sys/src/main/java/com/alibaba/nacos/sys/env/OriginTrackedPropertiesLoader.java
vendored
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.origin.Origin;
|
||||
import org.springframework.boot.origin.OriginTrackedValue;
|
||||
import org.springframework.boot.origin.TextResourceOrigin;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* copy from springboot to load properties file.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.UndefineMagicConstantRule")
|
||||
public class OriginTrackedPropertiesLoader {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
/**
|
||||
* Create a new {@link OriginTrackedPropertiesLoader} instance.
|
||||
*
|
||||
* @param resource the resource of the {@code .properties} data
|
||||
*/
|
||||
OriginTrackedPropertiesLoader(Resource resource) {
|
||||
Assert.notNull(resource, "Resource must not be null");
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load {@code .properties} data and return a map of {@code String} -> {@link OriginTrackedValue}.
|
||||
*
|
||||
* @return the loaded properties
|
||||
* @throws IOException on read error
|
||||
*/
|
||||
public Map<String, OriginTrackedValue> load() throws IOException {
|
||||
return load(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load {@code .properties} data and return a map of {@code String} -> {@link OriginTrackedValue}.
|
||||
*
|
||||
* @param expandLists if list {@code name[]=a,b,c} shortcuts should be expanded
|
||||
* @return the loaded properties
|
||||
* @throws IOException on read error
|
||||
*/
|
||||
public Map<String, OriginTrackedValue> load(boolean expandLists) throws IOException {
|
||||
try (OriginTrackedPropertiesLoader.CharacterReader reader = new CharacterReader(this.resource)) {
|
||||
Map<String, OriginTrackedValue> result = new LinkedHashMap<>();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
while (reader.read()) {
|
||||
String key = loadKey(buffer, reader).trim();
|
||||
if (expandLists && key.endsWith("[]")) {
|
||||
key = key.substring(0, key.length() - 2);
|
||||
int index = 0;
|
||||
do {
|
||||
OriginTrackedValue value = loadValue(buffer, reader, true);
|
||||
put(result, key + "[" + (index++) + "]", value);
|
||||
if (!reader.isEndOfLine()) {
|
||||
reader.read();
|
||||
}
|
||||
} while (!reader.isEndOfLine());
|
||||
} else {
|
||||
OriginTrackedValue value = loadValue(buffer, reader, false);
|
||||
put(result, key, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private void put(Map<String, OriginTrackedValue> result, String key, OriginTrackedValue value) {
|
||||
if (!key.isEmpty()) {
|
||||
result.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
private String loadKey(StringBuilder buffer, OriginTrackedPropertiesLoader.CharacterReader reader)
|
||||
throws IOException {
|
||||
buffer.setLength(0);
|
||||
boolean previousWhitespace = false;
|
||||
while (!reader.isEndOfLine()) {
|
||||
if (reader.isPropertyDelimiter()) {
|
||||
reader.read();
|
||||
return buffer.toString();
|
||||
}
|
||||
if (!reader.isWhiteSpace() && previousWhitespace) {
|
||||
return buffer.toString();
|
||||
}
|
||||
previousWhitespace = reader.isWhiteSpace();
|
||||
buffer.append(reader.getCharacter());
|
||||
reader.read();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private OriginTrackedValue loadValue(StringBuilder buffer, OriginTrackedPropertiesLoader.CharacterReader reader,
|
||||
boolean splitLists) throws IOException {
|
||||
buffer.setLength(0);
|
||||
while (reader.isWhiteSpace() && !reader.isEndOfLine()) {
|
||||
reader.read();
|
||||
}
|
||||
TextResourceOrigin.Location location = reader.getLocation();
|
||||
while (!reader.isEndOfLine() && !(splitLists && reader.isListDelimiter())) {
|
||||
buffer.append(reader.getCharacter());
|
||||
reader.read();
|
||||
}
|
||||
Origin origin = new TextResourceOrigin(this.resource, location);
|
||||
return OriginTrackedValue.of(buffer.toString(), origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads characters from the source resource, taking care of skipping comments, handling multi-line values and
|
||||
* tracking {@code '\'} escapes.
|
||||
*/
|
||||
private static class CharacterReader implements Closeable {
|
||||
|
||||
private final String[] escapes = {"trnf", "\t\r\n\f"};
|
||||
|
||||
private final LineNumberReader reader;
|
||||
|
||||
private int columnNumber = -1;
|
||||
|
||||
private boolean escaped;
|
||||
|
||||
private int character;
|
||||
|
||||
CharacterReader(Resource resource) throws IOException {
|
||||
this.reader = new LineNumberReader(
|
||||
new InputStreamReader(resource.getInputStream(), StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.reader.close();
|
||||
}
|
||||
|
||||
public boolean read() throws IOException {
|
||||
return read(false);
|
||||
}
|
||||
|
||||
public boolean read(boolean wrappedLine) throws IOException {
|
||||
this.escaped = false;
|
||||
this.character = this.reader.read();
|
||||
this.columnNumber++;
|
||||
if (this.columnNumber == 0) {
|
||||
skipLeadingWhitespace();
|
||||
if (!wrappedLine) {
|
||||
skipComment();
|
||||
}
|
||||
}
|
||||
if (this.character == '\\') {
|
||||
this.escaped = true;
|
||||
readEscaped();
|
||||
} else if (this.character == '\n') {
|
||||
this.columnNumber = -1;
|
||||
}
|
||||
return !isEndOfFile();
|
||||
}
|
||||
|
||||
private void skipLeadingWhitespace() throws IOException {
|
||||
while (isWhiteSpace()) {
|
||||
this.character = this.reader.read();
|
||||
this.columnNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipComment() throws IOException {
|
||||
if (this.character == '#' || this.character == '!') {
|
||||
while (this.character != '\n' && this.character != -1) {
|
||||
this.character = this.reader.read();
|
||||
}
|
||||
this.columnNumber = -1;
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private void readEscaped() throws IOException {
|
||||
this.character = this.reader.read();
|
||||
int escapeIndex = escapes[0].indexOf(this.character);
|
||||
if (escapeIndex != -1) {
|
||||
this.character = escapes[1].charAt(escapeIndex);
|
||||
} else if (this.character == '\n') {
|
||||
this.columnNumber = -1;
|
||||
read(true);
|
||||
} else if (this.character == 'u') {
|
||||
readUnicode();
|
||||
}
|
||||
}
|
||||
|
||||
private void readUnicode() throws IOException {
|
||||
this.character = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int digit = this.reader.read();
|
||||
if (digit >= '0' && digit <= '9') {
|
||||
this.character = (this.character << 4) + digit - '0';
|
||||
} else if (digit >= 'a' && digit <= 'f') {
|
||||
this.character = (this.character << 4) + digit - 'a' + 10;
|
||||
} else if (digit >= 'A' && digit <= 'F') {
|
||||
this.character = (this.character << 4) + digit - 'A' + 10;
|
||||
} else {
|
||||
throw new IllegalStateException("Malformed \\uxxxx encoding.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWhiteSpace() {
|
||||
return !this.escaped && (this.character == ' ' || this.character == '\t' || this.character == '\f');
|
||||
}
|
||||
|
||||
public boolean isEndOfFile() {
|
||||
return this.character == -1;
|
||||
}
|
||||
|
||||
public boolean isEndOfLine() {
|
||||
return this.character == -1 || (!this.escaped && this.character == '\n');
|
||||
}
|
||||
|
||||
public boolean isListDelimiter() {
|
||||
return !this.escaped && this.character == ',';
|
||||
}
|
||||
|
||||
public boolean isPropertyDelimiter() {
|
||||
return !this.escaped && (this.character == '=' || this.character == ':');
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return (char) this.character;
|
||||
}
|
||||
|
||||
public TextResourceOrigin.Location getLocation() {
|
||||
return new TextResourceOrigin.Location(this.reader.getLineNumber(), this.columnNumber);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.file;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* file change event.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class FileChangeEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4255584033113954765L;
|
||||
|
||||
private String paths;
|
||||
|
||||
private Object context;
|
||||
|
||||
public static FileChangeEventBuilder builder() {
|
||||
return new FileChangeEventBuilder();
|
||||
}
|
||||
|
||||
public String getPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
public void setPaths(String paths) {
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
public Object getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(Object context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FileChangeEvent{" + "paths='" + paths + '\'' + ", context=" + context + '}';
|
||||
}
|
||||
|
||||
public static final class FileChangeEventBuilder {
|
||||
|
||||
private String paths;
|
||||
|
||||
private Object context;
|
||||
|
||||
private FileChangeEventBuilder() {
|
||||
}
|
||||
|
||||
public FileChangeEventBuilder paths(String paths) {
|
||||
this.paths = paths;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileChangeEventBuilder context(Object context) {
|
||||
this.context = context;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* build FileChangeEvent.
|
||||
*
|
||||
* @return {@link FileChangeEvent}
|
||||
*/
|
||||
public FileChangeEvent build() {
|
||||
FileChangeEvent fileChangeEvent = new FileChangeEvent();
|
||||
fileChangeEvent.setPaths(paths);
|
||||
fileChangeEvent.setContext(context);
|
||||
return fileChangeEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.file;
|
||||
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* file watcher.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class FileWatcher {
|
||||
|
||||
/**
|
||||
* Triggered when a file change occurs.
|
||||
*
|
||||
* @param event {@link FileChangeEvent}
|
||||
*/
|
||||
public abstract void onChange(FileChangeEvent event);
|
||||
|
||||
/**
|
||||
* WatchEvent context information.
|
||||
*
|
||||
* @param context {@link WatchEvent#context()}
|
||||
* @return is this watcher interest context
|
||||
*/
|
||||
public abstract boolean interest(String context);
|
||||
|
||||
/**
|
||||
* If the FileWatcher has its own thread pool, use this thread pool to execute, otherwise use the WatchFileManager
|
||||
* thread.
|
||||
*
|
||||
* @return {@link Executor}
|
||||
*/
|
||||
public Executor executor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* 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.file;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
|
||||
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.ClosedWatchServiceException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardWatchEventKinds;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Unified file change monitoring management center, which uses {@link WatchService} internally. One file directory
|
||||
* corresponds to one {@link WatchService}. It can only monitor up to 32 file directories. When a file change occurs, a
|
||||
* {@link FileChangeEvent} will be issued
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class WatchFileCenter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WatchFileCenter.class);
|
||||
|
||||
/**
|
||||
* Maximum number of monitored file directories.
|
||||
*/
|
||||
private static final int MAX_WATCH_FILE_JOB = Integer.getInteger("nacos.watch-file.max-dirs", 16);
|
||||
|
||||
private static final Map<String, WatchDirJob> MANAGER = new HashMap<>(MAX_WATCH_FILE_JOB);
|
||||
|
||||
private static final FileSystem FILE_SYSTEM = FileSystems.getDefault();
|
||||
|
||||
private static final AtomicBoolean CLOSED = new AtomicBoolean(false);
|
||||
|
||||
static {
|
||||
ThreadUtils.addShutdownHook(WatchFileCenter::shutdown);
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of directories that are currently monitored.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:StaticVariableName")
|
||||
private static int NOW_WATCH_JOB_CNT = 0;
|
||||
|
||||
/**
|
||||
* Register {@link FileWatcher} in this directory.
|
||||
*
|
||||
* @param paths directory
|
||||
* @param watcher {@link FileWatcher}
|
||||
* @return register is success
|
||||
* @throws NacosException NacosException
|
||||
*/
|
||||
public static synchronized boolean registerWatcher(final String paths, FileWatcher watcher) throws NacosException {
|
||||
checkState();
|
||||
if (NOW_WATCH_JOB_CNT == MAX_WATCH_FILE_JOB) {
|
||||
return false;
|
||||
}
|
||||
WatchDirJob job = MANAGER.get(paths);
|
||||
if (job == null) {
|
||||
job = new WatchDirJob(paths);
|
||||
job.start();
|
||||
MANAGER.put(paths, job);
|
||||
NOW_WATCH_JOB_CNT++;
|
||||
}
|
||||
job.addSubscribe(watcher);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregister all {@link FileWatcher} in this directory.
|
||||
*
|
||||
* @param path directory
|
||||
* @return deregister is success
|
||||
*/
|
||||
public static synchronized boolean deregisterAllWatcher(final String path) {
|
||||
WatchDirJob job = MANAGER.get(path);
|
||||
if (job != null) {
|
||||
job.shutdown();
|
||||
MANAGER.remove(path);
|
||||
NOW_WATCH_JOB_CNT--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* close {@link WatchFileCenter}.
|
||||
*/
|
||||
public static void shutdown() {
|
||||
if (!CLOSED.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
LOGGER.warn("[WatchFileCenter] start close");
|
||||
for (Map.Entry<String, WatchDirJob> entry : MANAGER.entrySet()) {
|
||||
LOGGER.warn("[WatchFileCenter] start to shutdown this watcher which is watch : " + entry.getKey());
|
||||
try {
|
||||
entry.getValue().shutdown();
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error("[WatchFileCenter] shutdown has error : ", e);
|
||||
}
|
||||
}
|
||||
MANAGER.clear();
|
||||
NOW_WATCH_JOB_CNT = 0;
|
||||
LOGGER.warn("[WatchFileCenter] already closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregister {@link FileWatcher} in this directory.
|
||||
*
|
||||
* @param path directory
|
||||
* @param watcher {@link FileWatcher}
|
||||
* @return deregister is success
|
||||
*/
|
||||
public static synchronized boolean deregisterWatcher(final String path, final FileWatcher watcher) {
|
||||
WatchDirJob job = MANAGER.get(path);
|
||||
if (job != null) {
|
||||
job.watchers.remove(watcher);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class WatchDirJob extends Thread {
|
||||
|
||||
private final ExecutorService callBackExecutor;
|
||||
|
||||
private final String paths;
|
||||
|
||||
private final WatchService watchService;
|
||||
|
||||
private volatile boolean watch = true;
|
||||
|
||||
private final Set<FileWatcher> watchers = new ConcurrentHashSet<>();
|
||||
|
||||
public WatchDirJob(String paths) throws NacosException {
|
||||
setName(paths);
|
||||
this.paths = paths;
|
||||
final Path p = Paths.get(paths);
|
||||
if (!p.toFile().isDirectory()) {
|
||||
throw new IllegalArgumentException("Must be a file directory : " + paths);
|
||||
}
|
||||
|
||||
this.callBackExecutor = ExecutorFactory.newSingleExecutorService(
|
||||
new NameThreadFactory("com.alibaba.nacos.sys.file.watch-" + paths));
|
||||
|
||||
try {
|
||||
WatchService service = FILE_SYSTEM.newWatchService();
|
||||
p.register(service, StandardWatchEventKinds.OVERFLOW, StandardWatchEventKinds.ENTRY_MODIFY,
|
||||
StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
|
||||
this.watchService = service;
|
||||
} catch (Throwable ex) {
|
||||
throw new NacosException(NacosException.SERVER_ERROR, ex);
|
||||
}
|
||||
}
|
||||
|
||||
void addSubscribe(final FileWatcher watcher) {
|
||||
watchers.add(watcher);
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
watch = false;
|
||||
|
||||
//fix issue[https://github.com/alibaba/nacos/issues/9393]
|
||||
try {
|
||||
watchService.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
|
||||
ThreadUtils.shutdownThreadPool(this.callBackExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (watch && !this.isInterrupted()) {
|
||||
try {
|
||||
final WatchKey watchKey = watchService.take();
|
||||
final List<WatchEvent<?>> events = watchKey.pollEvents();
|
||||
watchKey.reset();
|
||||
if (callBackExecutor.isShutdown()) {
|
||||
return;
|
||||
}
|
||||
if (events.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
callBackExecutor.execute(() -> {
|
||||
for (WatchEvent<?> event : events) {
|
||||
WatchEvent.Kind<?> kind = event.kind();
|
||||
|
||||
// Since the OS's event cache may be overflow, a backstop is needed
|
||||
if (StandardWatchEventKinds.OVERFLOW.equals(kind)) {
|
||||
eventOverflow();
|
||||
} else {
|
||||
eventProcess(event.context());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException | ClosedWatchServiceException ignore) {
|
||||
Thread.interrupted();
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.error("An exception occurred during file listening : ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void eventProcess(Object context) {
|
||||
final FileChangeEvent fileChangeEvent = FileChangeEvent.builder().paths(paths).context(context).build();
|
||||
final String str = String.valueOf(context);
|
||||
for (final FileWatcher watcher : watchers) {
|
||||
if (watcher.interest(str)) {
|
||||
Runnable job = () -> watcher.onChange(fileChangeEvent);
|
||||
Executor executor = watcher.executor();
|
||||
if (executor == null) {
|
||||
try {
|
||||
job.run();
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.error("File change event callback error : ", ex);
|
||||
}
|
||||
} else {
|
||||
executor.execute(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void eventOverflow() {
|
||||
File dir = Paths.get(paths).toFile();
|
||||
for (File file : Objects.requireNonNull(dir.listFiles())) {
|
||||
// Subdirectories do not participate in listening
|
||||
if (file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
eventProcess(file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void checkState() {
|
||||
if (CLOSED.get()) {
|
||||
throw new IllegalStateException("WatchFileCenter already shutdown");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.filter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Nacos server module execute filter.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface NacosPackageExcludeFilter {
|
||||
|
||||
/**
|
||||
* Get the responsible module package prefix of filter.
|
||||
*
|
||||
* @return package prefix
|
||||
*/
|
||||
String getResponsiblePackagePrefix();
|
||||
|
||||
/**
|
||||
* According the class name and annotations to judge whether the class should be excluded by spring bean.
|
||||
*
|
||||
* @param className name of this class
|
||||
* @param annotationNames annotations of this class
|
||||
* @return {@code true} if should be excluded, otherwise {@code false}
|
||||
*/
|
||||
boolean isExcluded(String className, Set<String> annotationNames);
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.filter;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Nacos server execute filter. To exclude some beans or features by config
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class NacosTypeExcludeFilter implements TypeFilter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosTypeExcludeFilter.class);
|
||||
|
||||
private final Map<String, NacosPackageExcludeFilter> packageExcludeFilters;
|
||||
|
||||
public NacosTypeExcludeFilter() {
|
||||
this.packageExcludeFilters = new HashMap<>(2);
|
||||
for (NacosPackageExcludeFilter each : NacosServiceLoader.load(NacosPackageExcludeFilter.class)) {
|
||||
packageExcludeFilters.put(each.getResponsiblePackagePrefix(), each);
|
||||
LOGGER.info("Load Nacos package exclude filter success, package prefix {}, filter {}",
|
||||
each.getResponsiblePackagePrefix(), each.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException {
|
||||
// If no exclude filters, all classes should be load.
|
||||
if (packageExcludeFilters.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean isSpringBootApplication = metadataReader.getAnnotationMetadata()
|
||||
.hasAnnotation(SpringBootApplication.class.getCanonicalName());
|
||||
String className = metadataReader.getClassMetadata().getClassName();
|
||||
if (isSpringBootApplication) {
|
||||
LOGGER.info("Skip @SpringBootApplication annotation for class {} to avoid duplicate scan", className);
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<String, NacosPackageExcludeFilter> entry : packageExcludeFilters.entrySet()) {
|
||||
// If match the package exclude filter, judged by filter.
|
||||
if (className.startsWith(entry.getKey())) {
|
||||
Set<String> annotations = metadataReader.getAnnotationMetadata().getAnnotationTypes();
|
||||
return entry.getValue().isExcluded(className, annotations);
|
||||
}
|
||||
}
|
||||
// No match filter, load class
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2021 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.module;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Module state.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class ModuleState {
|
||||
|
||||
private final String moduleName;
|
||||
|
||||
private final Map<String, Object> states;
|
||||
|
||||
public ModuleState(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
this.states = new HashMap<>();
|
||||
}
|
||||
|
||||
public String getModuleName() {
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
public ModuleState newState(String stateName, Object stateValue) {
|
||||
this.states.put(stateName, stateValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<String, Object> getStates() {
|
||||
return states;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public <T> T getState(String stateName, T defaultValue) {
|
||||
return (T) states.getOrDefault(stateName, defaultValue);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.module;
|
||||
|
||||
/**
|
||||
* Module state builder.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface ModuleStateBuilder {
|
||||
|
||||
/**
|
||||
* Build module state.
|
||||
*
|
||||
* @return ModuleState
|
||||
*/
|
||||
ModuleState build();
|
||||
|
||||
/**
|
||||
* Whether module is ignored, default return false.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
default boolean isIgnore() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 1999-2021 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.module;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Module State Holder.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class ModuleStateHolder {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ModuleStateHolder.class);
|
||||
|
||||
private static final ModuleStateHolder INSTANCE = new ModuleStateHolder();
|
||||
|
||||
private final Map<String, ModuleState> moduleStates;
|
||||
|
||||
private ModuleStateHolder() {
|
||||
this.moduleStates = new HashMap<>();
|
||||
for (ModuleStateBuilder each : NacosServiceLoader.load(ModuleStateBuilder.class)) {
|
||||
if (each.isIgnore()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
ModuleState moduleState = each.build();
|
||||
moduleStates.put(moduleState.getModuleName(), moduleState);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Build ModuleState failed in builder:{}", each.getClass().getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ModuleStateHolder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Optional<ModuleState> getModuleState(String moduleName) {
|
||||
return Optional.ofNullable(moduleStates.get(moduleName));
|
||||
}
|
||||
|
||||
public Set<ModuleState> getAllModuleStates() {
|
||||
return new HashSet<>(moduleStates.values());
|
||||
}
|
||||
|
||||
public String getStateValueByName(String moduleName, String stateName) {
|
||||
return getStateValueByName(moduleName, stateName, StringUtils.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get State Value by module name and state name.
|
||||
*
|
||||
* @param moduleName module name of state
|
||||
* @param stateName state name
|
||||
* @param defaultValue default value when can't find module or state
|
||||
* @return state value
|
||||
*/
|
||||
public <T> T getStateValueByName(String moduleName, String stateName, T defaultValue) {
|
||||
Optional<ModuleState> moduleState = getModuleState(moduleName);
|
||||
if (!moduleState.isPresent()) {
|
||||
return defaultValue;
|
||||
}
|
||||
return moduleState.get().getState(stateName, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search State Value by state name one by one.
|
||||
*
|
||||
* @param stateName state name
|
||||
* @param defaultValue default value when can't find module or state
|
||||
* @return state value
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public <T> T searchStateValue(String stateName, T defaultValue) {
|
||||
T result = null;
|
||||
for (ModuleState each : getAllModuleStates()) {
|
||||
if (each.getStates().containsKey(stateName)) {
|
||||
result = (T) each.getStates().get(stateName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null == result ? defaultValue : result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Nacos global tool class.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class ApplicationUtils implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
private static boolean started = false;
|
||||
|
||||
public static String getId() {
|
||||
return applicationContext.getId();
|
||||
}
|
||||
|
||||
public static String getApplicationName() {
|
||||
return applicationContext.getApplicationName();
|
||||
}
|
||||
|
||||
public static String getDisplayName() {
|
||||
return applicationContext.getDisplayName();
|
||||
}
|
||||
|
||||
public static long getStartupDate() {
|
||||
return applicationContext.getStartupDate();
|
||||
}
|
||||
|
||||
public static ApplicationContext getParent() {
|
||||
return applicationContext.getParent();
|
||||
}
|
||||
|
||||
public static AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
|
||||
return applicationContext.getAutowireCapableBeanFactory();
|
||||
}
|
||||
|
||||
public static boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public static void setStarted(boolean started) {
|
||||
ApplicationUtils.started = started;
|
||||
}
|
||||
|
||||
public static BeanFactory getParentBeanFactory() {
|
||||
return applicationContext.getParentBeanFactory();
|
||||
}
|
||||
|
||||
public static boolean containsLocalBean(String name) {
|
||||
return applicationContext.containsLocalBean(name);
|
||||
}
|
||||
|
||||
public static boolean containsBeanDefinition(String beanName) {
|
||||
return applicationContext.containsLocalBean(beanName);
|
||||
}
|
||||
|
||||
public static int getBeanDefinitionCount() {
|
||||
return applicationContext.getBeanDefinitionCount();
|
||||
}
|
||||
|
||||
public static String[] getBeanDefinitionNames() {
|
||||
return applicationContext.getBeanDefinitionNames();
|
||||
}
|
||||
|
||||
public static String[] getBeanNamesForType(ResolvableType type) {
|
||||
return applicationContext.getBeanNamesForType(type);
|
||||
}
|
||||
|
||||
public static String[] getBeanNamesForType(Class<?> type) {
|
||||
return applicationContext.getBeanNamesForType(type);
|
||||
}
|
||||
|
||||
public static String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
|
||||
return applicationContext.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
|
||||
}
|
||||
|
||||
public static <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
|
||||
return applicationContext.getBeansOfType(type);
|
||||
}
|
||||
|
||||
public static <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
|
||||
throws BeansException {
|
||||
return applicationContext.getBeansOfType(type, includeNonSingletons, allowEagerInit);
|
||||
}
|
||||
|
||||
public static String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
|
||||
return applicationContext.getBeanNamesForAnnotation(annotationType);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
|
||||
throws BeansException {
|
||||
return applicationContext.getBeansWithAnnotation(annotationType);
|
||||
}
|
||||
|
||||
public static <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.findAnnotationOnBean(beanName, annotationType);
|
||||
}
|
||||
|
||||
public static Object getBean(String name) throws BeansException {
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> requiredType) throws BeansException {
|
||||
return applicationContext.getBean(name, requiredType);
|
||||
}
|
||||
|
||||
public static Object getBean(String name, Object... args) throws BeansException {
|
||||
return applicationContext.getBean(name, args);
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> requiredType) throws BeansException {
|
||||
return applicationContext.getBean(requiredType);
|
||||
}
|
||||
|
||||
public static <T> void getBeanIfExist(Class<T> requiredType, Consumer<T> consumer) throws BeansException {
|
||||
try {
|
||||
T bean = applicationContext.getBean(requiredType);
|
||||
consumer.accept(bean);
|
||||
} catch (NoSuchBeanDefinitionException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
|
||||
return applicationContext.getBean(requiredType, args);
|
||||
}
|
||||
|
||||
public static <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
|
||||
return applicationContext.getBeanProvider(requiredType);
|
||||
}
|
||||
|
||||
public static <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
|
||||
return applicationContext.getBeanProvider(requiredType);
|
||||
}
|
||||
|
||||
public static boolean containsBean(String name) {
|
||||
return applicationContext.containsBean(name);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.isSingleton(name);
|
||||
}
|
||||
|
||||
public static boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.isPrototype(name);
|
||||
}
|
||||
|
||||
public static boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.isTypeMatch(name, typeToMatch);
|
||||
}
|
||||
|
||||
public static boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.isTypeMatch(name, typeToMatch);
|
||||
}
|
||||
|
||||
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
|
||||
return applicationContext.getType(name);
|
||||
}
|
||||
|
||||
public static String[] getAliases(String name) {
|
||||
return applicationContext.getAliases(name);
|
||||
}
|
||||
|
||||
public static void publishEvent(Object event) {
|
||||
applicationContext.publishEvent(event);
|
||||
}
|
||||
|
||||
public static String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
|
||||
return applicationContext.getMessage(code, args, defaultMessage, locale);
|
||||
}
|
||||
|
||||
public static String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
|
||||
return applicationContext.getMessage(code, args, locale);
|
||||
}
|
||||
|
||||
public static String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
|
||||
return applicationContext.getMessage(resolvable, locale);
|
||||
}
|
||||
|
||||
public static Resource[] getResources(String locationPattern) throws IOException {
|
||||
return applicationContext.getResources(locationPattern);
|
||||
}
|
||||
|
||||
public static Resource getResource(String location) {
|
||||
return applicationContext.getResource(location);
|
||||
}
|
||||
|
||||
public static ClassLoader getClassLoader() {
|
||||
return applicationContext.getClassLoader();
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
public static void injectContext(ConfigurableApplicationContext context) {
|
||||
ApplicationUtils.applicationContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext context) {
|
||||
applicationContext = context;
|
||||
}
|
||||
}
|
||||
558
sys/src/main/java/com/alibaba/nacos/sys/utils/DiskUtils.java
Normal file
558
sys/src/main/java/com/alibaba/nacos/sys/utils/DiskUtils.java
Normal file
@ -0,0 +1,558 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.ByteUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.CheckedInputStream;
|
||||
import java.util.zip.CheckedOutputStream;
|
||||
import java.util.zip.Checksum;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* IO operates on the utility class.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public final class DiskUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DiskUtils.class);
|
||||
|
||||
private static final String NO_SPACE_CN = "设备上没有空间";
|
||||
|
||||
private static final String NO_SPACE_EN = "No space left on device";
|
||||
|
||||
private static final String DISK_QUOTA_CN = "超出磁盘限额";
|
||||
|
||||
private static final String DISK_QUOTA_EN = "Disk quota exceeded";
|
||||
|
||||
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
private static final CharsetDecoder DECODER = CHARSET.newDecoder();
|
||||
|
||||
public static void touch(String path, String fileName) throws IOException {
|
||||
FileUtils.touch(Paths.get(path, fileName).toFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the same behaviour as the "touch" utility on Unix. It creates a new file with size 0 or, if the file
|
||||
* exists already, it is opened and closed without modifying it, but updating the file date and time.
|
||||
*
|
||||
* <p>NOTE: As from v1.3, this method throws an IOException if the last
|
||||
* modified date of the file cannot be set. Also, as from v1.3 this method creates parent directories if they do not
|
||||
* exist.
|
||||
*
|
||||
* @param file the File to touch
|
||||
* @throws IOException If an I/O problem occurs
|
||||
*/
|
||||
public static void touch(File file) throws IOException {
|
||||
FileUtils.touch(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its
|
||||
* name. The resulting {@code Path} is associated with the same {@code FileSystem} as the given directory.
|
||||
*
|
||||
* <p>The details as to how the name of the file is constructed is
|
||||
* implementation dependent and therefore not specified. Where possible the {@code prefix} and {@code suffix} are
|
||||
* used to construct candidate names in the same manner as the {@link java.io.File#createTempFile(String, String,
|
||||
* File)} method.
|
||||
*
|
||||
* @param dir the path to directory in which to create the file
|
||||
* @param prefix the prefix string to be used in generating the file's name; may be {@code null}
|
||||
* @param suffix the suffix string to be used in generating the file's name; may be {@code null}, in which case
|
||||
* "{@code .tmp}" is used
|
||||
* @return the path to the newly created file that did not exist before this method was invoked
|
||||
* @throws IllegalArgumentException if the prefix or suffix parameters cannot be used to generate a candidate
|
||||
* file name
|
||||
* @throws UnsupportedOperationException if the array contains an attribute that cannot be set atomically when
|
||||
* creating the directory
|
||||
* @throws IOException if an I/O error occurs or {@code dir} does not exist
|
||||
* @throws SecurityException In the case of the default provider, and a security manager is installed,
|
||||
* the {@link SecurityManager#checkWrite(String) checkWrite} method is invoked
|
||||
* to check write access to the file.
|
||||
*/
|
||||
public static File createTmpFile(String dir, String prefix, String suffix) throws IOException {
|
||||
return Files.createTempFile(Paths.get(dir), prefix, suffix).toFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its
|
||||
* name. The resulting {@code Path} is associated with the default {@code FileSystem}.
|
||||
*
|
||||
* @param prefix the prefix string to be used in generating the file's name; may be {@code null}
|
||||
* @param suffix the suffix string to be used in generating the file's name; may be {@code null}, in which case
|
||||
* "{@code .tmp}" is used
|
||||
* @return the path to the newly created file that did not exist before this method was invoked
|
||||
* @throws IllegalArgumentException if the prefix or suffix parameters cannot be used to generate a candidate
|
||||
* file name
|
||||
* @throws UnsupportedOperationException if the array contains an attribute that cannot be set atomically when
|
||||
* creating the directory
|
||||
* @throws IOException if an I/O error occurs or the temporary-file directory does not exist
|
||||
* @throws SecurityException In the case of the default provider, and a security manager is installed,
|
||||
* the {@link SecurityManager#checkWrite(String) checkWrite} method is invoked
|
||||
* to check write access to the file.
|
||||
*/
|
||||
public static File createTmpFile(String prefix, String suffix) throws IOException {
|
||||
return Files.createTempFile(prefix, suffix).toFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* read file which under the path.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(String path, String fileName) {
|
||||
File file = openFile(path, fileName);
|
||||
if (file.exists()) {
|
||||
return readFile(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* read file content by {@link InputStream}.
|
||||
*
|
||||
* @param is {@link InputStream}
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(InputStream is) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
String lineTxt = null;
|
||||
while ((lineTxt = reader.readLine()) != null) {
|
||||
textBuilder.append(lineTxt);
|
||||
}
|
||||
return textBuilder.toString();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read this file content.
|
||||
*
|
||||
* @param file {@link File}
|
||||
* @return content
|
||||
*/
|
||||
public static String readFile(File file) {
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
FileChannel fileChannel = fis.getChannel()) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4096);
|
||||
CharBuffer charBuffer = CharBuffer.allocate(4096);
|
||||
while (fileChannel.read(buffer) != -1) {
|
||||
buffer.flip();
|
||||
DECODER.decode(buffer, charBuffer, false);
|
||||
charBuffer.flip();
|
||||
while (charBuffer.hasRemaining()) {
|
||||
text.append(charBuffer.get());
|
||||
}
|
||||
buffer.clear();
|
||||
charBuffer.clear();
|
||||
}
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read this file content then return bytes.
|
||||
*
|
||||
* @param file {@link File}
|
||||
* @return content bytes
|
||||
*/
|
||||
public static byte[] readFileBytes(File file) {
|
||||
if (file.exists()) {
|
||||
String result = readFile(file);
|
||||
if (result != null) {
|
||||
return ByteUtils.toBytes(result);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] readFileBytes(String path, String fileName) {
|
||||
File file = openFile(path, fileName);
|
||||
return readFileBytes(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents to the target file.
|
||||
*
|
||||
* @param file target file
|
||||
* @param content content
|
||||
* @param append write append mode
|
||||
* @return write success
|
||||
*/
|
||||
public static boolean writeFile(File file, byte[] content, boolean append) {
|
||||
try (FileOutputStream fos = new FileOutputStream(file, append);
|
||||
FileChannel fileChannel = fos.getChannel()) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(content);
|
||||
fileChannel.write(buffer);
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
if (ioe.getMessage() != null) {
|
||||
String errMsg = ioe.getMessage();
|
||||
if (NO_SPACE_CN.equals(errMsg) || NO_SPACE_EN.equals(errMsg) || errMsg.contains(DISK_QUOTA_CN) || errMsg
|
||||
.contains(DISK_QUOTA_EN)) {
|
||||
LOGGER.warn("磁盘满,自杀退出");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void deleteQuietly(File file) {
|
||||
Objects.requireNonNull(file, "file");
|
||||
FileUtils.deleteQuietly(file);
|
||||
}
|
||||
|
||||
public static void deleteQuietly(Path path) {
|
||||
Objects.requireNonNull(path, "path");
|
||||
FileUtils.deleteQuietly(path.toFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* delete target file.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @return delete success
|
||||
*/
|
||||
public static boolean deleteFile(String path, String fileName) {
|
||||
File file = Paths.get(path, fileName).toFile();
|
||||
if (file.exists()) {
|
||||
return file.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void deleteDirectory(String path) throws IOException {
|
||||
FileUtils.deleteDirectory(new File(path));
|
||||
}
|
||||
|
||||
public static void forceMkdir(String path) throws IOException {
|
||||
FileUtils.forceMkdir(new File(path));
|
||||
}
|
||||
|
||||
public static void forceMkdir(File file) throws IOException {
|
||||
FileUtils.forceMkdir(file);
|
||||
}
|
||||
|
||||
public static void deleteDirThenMkdir(String path) throws IOException {
|
||||
deleteDirectory(path);
|
||||
forceMkdir(path);
|
||||
}
|
||||
|
||||
public static void copyDirectory(File srcDir, File destDir) throws IOException {
|
||||
FileUtils.copyDirectory(srcDir, destDir);
|
||||
}
|
||||
|
||||
public static void copyFile(File src, File target) throws IOException {
|
||||
FileUtils.copyFile(src, target);
|
||||
}
|
||||
|
||||
public static File openFile(String path, String fileName) {
|
||||
return openFile(path, fileName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* open file.
|
||||
*
|
||||
* @param path directory
|
||||
* @param fileName filename
|
||||
* @param rewrite if rewrite is true, will delete old file and create new one
|
||||
* @return {@link File}
|
||||
*/
|
||||
public static File openFile(String path, String fileName, boolean rewrite) {
|
||||
File directory = new File(path);
|
||||
boolean mkdirs = true;
|
||||
if (!directory.exists()) {
|
||||
mkdirs = directory.mkdirs();
|
||||
}
|
||||
if (!mkdirs) {
|
||||
LOGGER.error("[DiskUtils] can't create directory");
|
||||
return null;
|
||||
}
|
||||
File file = new File(path, fileName);
|
||||
try {
|
||||
boolean create = true;
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
if (file.exists()) {
|
||||
if (rewrite) {
|
||||
file.delete();
|
||||
} else {
|
||||
create = false;
|
||||
}
|
||||
}
|
||||
if (create) {
|
||||
file.createNewFile();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
/**
|
||||
* Compress a folder in a directory.
|
||||
*
|
||||
* @param rootDir directory
|
||||
* @param sourceDir folder
|
||||
* @param outputFile output file
|
||||
* @param checksum checksum
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static void compress(final String rootDir, final String sourceDir, final String outputFile,
|
||||
final Checksum checksum) throws IOException {
|
||||
try (final FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
final CheckedOutputStream cos = new CheckedOutputStream(fos, checksum);
|
||||
final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(cos))) {
|
||||
compressDirectoryToZipFile(rootDir, sourceDir, zos);
|
||||
zos.flush();
|
||||
fos.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
private static void compressDirectoryToZipFile(final String rootDir, final String sourceDir,
|
||||
final ZipOutputStream zos) throws IOException {
|
||||
final String dir = Paths.get(rootDir, sourceDir).toString();
|
||||
final File[] files = Objects.requireNonNull(new File(dir).listFiles(), "files");
|
||||
for (final File file : files) {
|
||||
final String child = Paths.get(sourceDir, file.getName()).toString();
|
||||
if (file.isDirectory()) {
|
||||
compressDirectoryToZipFile(rootDir, child, zos);
|
||||
} else {
|
||||
try (final FileInputStream fis = new FileInputStream(file);
|
||||
final BufferedInputStream bis = new BufferedInputStream(fis)) {
|
||||
compressIntoZipFile(child, bis, zos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress an input stream to zip file.
|
||||
*
|
||||
* @param childName child name in zip file
|
||||
* @param inputStream input stream needed compress
|
||||
* @param outputFile output file
|
||||
* @param checksum check sum
|
||||
* @throws IOException IOException during compress
|
||||
*/
|
||||
public static void compressIntoZipFile(final String childName, final InputStream inputStream,
|
||||
final String outputFile, final Checksum checksum) throws IOException {
|
||||
try (final FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
|
||||
final CheckedOutputStream checkedOutputStream = new CheckedOutputStream(fileOutputStream, checksum);
|
||||
final ZipOutputStream zipStream = new ZipOutputStream(new BufferedOutputStream(checkedOutputStream))) {
|
||||
compressIntoZipFile(childName, inputStream, zipStream);
|
||||
zipStream.flush();
|
||||
fileOutputStream.getFD().sync();
|
||||
}
|
||||
}
|
||||
|
||||
private static void compressIntoZipFile(final String childName, final InputStream inputStream,
|
||||
final ZipOutputStream zipOutputStream) throws IOException {
|
||||
zipOutputStream.putNextEntry(new ZipEntry(childName));
|
||||
IOUtils.copy(inputStream, zipOutputStream);
|
||||
}
|
||||
|
||||
// copy from sofa-jraft
|
||||
|
||||
/**
|
||||
* Unzip the target file to the specified folder.
|
||||
*
|
||||
* @param sourceFile target file
|
||||
* @param outputDir specified folder
|
||||
* @param checksum checksum
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static void decompress(final String sourceFile, final String outputDir, final Checksum checksum)
|
||||
throws IOException {
|
||||
try (final FileInputStream fis = new FileInputStream(sourceFile);
|
||||
final CheckedInputStream cis = new CheckedInputStream(fis, checksum);
|
||||
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
final String fileName = entry.getName();
|
||||
final File entryFile = new File(Paths.get(outputDir, fileName).toString());
|
||||
FileUtils.forceMkdir(entryFile.getParentFile());
|
||||
try (final FileOutputStream fos = new FileOutputStream(entryFile);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
IOUtils.copy(zis, bos);
|
||||
bos.flush();
|
||||
fos.getFD().sync();
|
||||
}
|
||||
}
|
||||
// Continue to read all remaining bytes(extra metadata of ZipEntry) directly from the checked stream,
|
||||
// Otherwise, the checksum value maybe unexpected.
|
||||
//
|
||||
// See https://coderanch.com/t/279175/java/ZipInputStream
|
||||
IOUtils.copy(cis, NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip the target file to byte array.
|
||||
*
|
||||
* @param sourceFile target file
|
||||
* @param checksum checksum
|
||||
* @return decompress byte array
|
||||
* @throws IOException IOException during decompress
|
||||
*/
|
||||
public static byte[] decompress(final String sourceFile, final Checksum checksum) throws IOException {
|
||||
byte[] result;
|
||||
try (final FileInputStream fis = new FileInputStream(sourceFile);
|
||||
final CheckedInputStream cis = new CheckedInputStream(fis, checksum);
|
||||
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(cis));
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream(1024)) {
|
||||
while (zis.getNextEntry() != null) {
|
||||
IOUtils.copy(zis, bos);
|
||||
bos.flush();
|
||||
}
|
||||
IOUtils.copy(cis, NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
result = bos.toByteArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the lines in a <code>File</code>.
|
||||
* <p>
|
||||
* This method opens an <code>InputStream</code> for the file. When you have finished with the iterator you should
|
||||
* close the stream to free internal resources. This can be done by calling the {@link
|
||||
* org.apache.commons.io.LineIterator#close()} or {@link org.apache.commons.io.LineIterator#closeQuietly(org.apache.commons.io.LineIterator)}
|
||||
* method.
|
||||
* </p>
|
||||
* The recommended usage pattern is:
|
||||
* <pre>
|
||||
* LineIterator it = FileUtils.lineIterator(file, "UTF-8");
|
||||
* try {
|
||||
* while (it.hasNext()) {
|
||||
* String line = it.nextLine();
|
||||
* /// do something with line
|
||||
* }
|
||||
* } finally {
|
||||
* LineIterator.closeQuietly(iterator);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* If an exception occurs during the creation of the iterator, the underlying stream is closed.
|
||||
* </p>
|
||||
*
|
||||
* @param file the file to open for input, must not be <code>null</code>
|
||||
* @param encoding the encoding to use, <code>null</code> means platform default
|
||||
* @return an Iterator of the lines in the file, never <code>null</code>
|
||||
* @throws IOException in case of an I/O error (file closed)
|
||||
* @since 1.2
|
||||
*/
|
||||
public static LineIterator lineIterator(File file, String encoding) throws IOException {
|
||||
return new LineIterator(FileUtils.lineIterator(file, encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the lines in a <code>File</code> using the default encoding for the VM.
|
||||
*
|
||||
* @param file the file to open for input, must not be <code>null</code>
|
||||
* @return an Iterator of the lines in the file, never <code>null</code>
|
||||
* @throws IOException in case of an I/O error (file closed)
|
||||
* @see #lineIterator(File, String)
|
||||
* @since 1.3
|
||||
*/
|
||||
public static LineIterator lineIterator(File file) throws IOException {
|
||||
return new LineIterator(FileUtils.lineIterator(file, null));
|
||||
}
|
||||
|
||||
public static class LineIterator implements AutoCloseable {
|
||||
|
||||
private final org.apache.commons.io.LineIterator target;
|
||||
|
||||
/**
|
||||
* Constructs an iterator of the lines for a <code>Reader</code>.
|
||||
*
|
||||
* @param target {@link org.apache.commons.io.LineIterator}
|
||||
*/
|
||||
LineIterator(org.apache.commons.io.LineIterator target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return target.hasNext();
|
||||
}
|
||||
|
||||
public String next() {
|
||||
return target.next();
|
||||
}
|
||||
|
||||
public String nextLine() {
|
||||
return target.nextLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
target.close();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
target.remove();
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super String> action) {
|
||||
target.forEachRemaining(action);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
297
sys/src/main/java/com/alibaba/nacos/sys/utils/InetUtils.java
Normal file
297
sys/src/main/java/com/alibaba/nacos/sys/utils/InetUtils.java
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import com.alibaba.nacos.common.executor.ExecutorFactory;
|
||||
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.notify.SlowEvent;
|
||||
import com.alibaba.nacos.common.utils.InternetAddressUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.sys.env.Constants;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.sys.env.Constants.IP_ADDRESS;
|
||||
import static com.alibaba.nacos.sys.env.Constants.NACOS_SERVER_IP;
|
||||
import static com.alibaba.nacos.sys.env.Constants.PREFER_HOSTNAME_OVER_IP;
|
||||
import static com.alibaba.nacos.sys.env.Constants.SYSTEM_PREFER_HOSTNAME_OVER_IP;
|
||||
import static com.alibaba.nacos.sys.env.Constants.USE_ONLY_SITE_INTERFACES;
|
||||
|
||||
/**
|
||||
* Network card operation tool class.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class InetUtils {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InetUtils.class);
|
||||
|
||||
private static final List<String> PREFERRED_NETWORKS = new ArrayList<>();
|
||||
|
||||
private static final List<String> IGNORED_INTERFACES = new ArrayList<>();
|
||||
|
||||
private static final ScheduledExecutorService INET_AUTO_REFRESH_EXECUTOR = ExecutorFactory.Managed.newSingleScheduledExecutorService(
|
||||
InetUtils.class.getCanonicalName(), new NameThreadFactory("com.alibaba.inet.ip.auto-refresh"));
|
||||
|
||||
private static volatile String selfIP;
|
||||
|
||||
private static boolean useOnlySiteLocalInterface = false;
|
||||
|
||||
private static boolean preferHostnameOverIP = false;
|
||||
|
||||
static {
|
||||
NotifyCenter.registerToSharePublisher(IPChangeEvent.class);
|
||||
|
||||
useOnlySiteLocalInterface = Boolean.parseBoolean(EnvUtil.getProperty(USE_ONLY_SITE_INTERFACES));
|
||||
|
||||
List<String> networks = EnvUtil.getPropertyList(Constants.PREFERRED_NETWORKS);
|
||||
PREFERRED_NETWORKS.addAll(networks);
|
||||
|
||||
List<String> interfaces = EnvUtil.getPropertyList(Constants.IGNORED_INTERFACES);
|
||||
IGNORED_INTERFACES.addAll(interfaces);
|
||||
|
||||
refreshIp();
|
||||
|
||||
final long delayMs = Long.getLong(Constants.AUTO_REFRESH_TIME, 30_000L);
|
||||
|
||||
INET_AUTO_REFRESH_EXECUTOR.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
InetUtils.refreshIp();
|
||||
} catch (Exception e) {
|
||||
LOG.error("refresh ip error", e);
|
||||
}
|
||||
}, delayMs, delayMs, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* refresh ip address.
|
||||
*/
|
||||
private static void refreshIp() {
|
||||
|
||||
String tmpSelfIp = getNacosIp();
|
||||
|
||||
if (StringUtils.isBlank(tmpSelfIp)) {
|
||||
tmpSelfIp = getPreferHostnameOverIP();
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(tmpSelfIp)) {
|
||||
tmpSelfIp = Objects.requireNonNull(findFirstNonLoopbackAddress()).getHostAddress();
|
||||
}
|
||||
|
||||
if (InternetAddressUtil.PREFER_IPV6_ADDRESSES && !tmpSelfIp.startsWith(InternetAddressUtil.IPV6_START_MARK)
|
||||
&& !tmpSelfIp.endsWith(InternetAddressUtil.IPV6_END_MARK)) {
|
||||
tmpSelfIp = InternetAddressUtil.IPV6_START_MARK + tmpSelfIp + InternetAddressUtil.IPV6_END_MARK;
|
||||
if (StringUtils.contains(tmpSelfIp, InternetAddressUtil.PERCENT_SIGN_IN_IPV6)) {
|
||||
tmpSelfIp = tmpSelfIp.substring(0, tmpSelfIp.indexOf(InternetAddressUtil.PERCENT_SIGN_IN_IPV6))
|
||||
+ InternetAddressUtil.IPV6_END_MARK;
|
||||
}
|
||||
}
|
||||
if (!Objects.equals(selfIP, tmpSelfIp) && Objects.nonNull(selfIP)) {
|
||||
IPChangeEvent event = new IPChangeEvent();
|
||||
event.setOldIP(selfIP);
|
||||
event.setNewIP(tmpSelfIp);
|
||||
NotifyCenter.publishEvent(event);
|
||||
}
|
||||
selfIP = tmpSelfIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ip address from environment
|
||||
* System property nacos.server.ip
|
||||
* Spring property nacos.inetutils.ip-address.
|
||||
*
|
||||
* @return ip address
|
||||
*/
|
||||
public static String getNacosIp() {
|
||||
String nacosIp = System.getProperty(NACOS_SERVER_IP);
|
||||
if (StringUtils.isBlank(nacosIp)) {
|
||||
nacosIp = EnvUtil.getProperty(IP_ADDRESS);
|
||||
}
|
||||
if (!StringUtils.isBlank(nacosIp)) {
|
||||
if (!(InternetAddressUtil.isIP(nacosIp) || InternetAddressUtil.isDomain(nacosIp))) {
|
||||
throw new RuntimeException("nacos address " + nacosIp + " is not ip");
|
||||
}
|
||||
}
|
||||
|
||||
return nacosIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ip address.
|
||||
*
|
||||
* @return ip address
|
||||
*/
|
||||
private static String getPreferHostnameOverIP() {
|
||||
preferHostnameOverIP = Boolean.getBoolean(SYSTEM_PREFER_HOSTNAME_OVER_IP);
|
||||
|
||||
if (!preferHostnameOverIP) {
|
||||
preferHostnameOverIP = Boolean.parseBoolean(EnvUtil.getProperty(PREFER_HOSTNAME_OVER_IP));
|
||||
}
|
||||
|
||||
if (!preferHostnameOverIP) {
|
||||
return null;
|
||||
}
|
||||
String preferHostnameOverIp = null;
|
||||
InetAddress inetAddress;
|
||||
try {
|
||||
inetAddress = InetAddress.getLocalHost();
|
||||
if (inetAddress.getHostName().equals(inetAddress.getCanonicalHostName())) {
|
||||
preferHostnameOverIp = inetAddress.getHostName();
|
||||
} else {
|
||||
preferHostnameOverIp = inetAddress.getCanonicalHostName();
|
||||
}
|
||||
} catch (UnknownHostException ignore) {
|
||||
LOG.warn("Unable to retrieve localhost");
|
||||
}
|
||||
return preferHostnameOverIp;
|
||||
}
|
||||
|
||||
public static String getSelfIP() {
|
||||
return selfIP;
|
||||
}
|
||||
|
||||
/**
|
||||
* findFirstNonLoopbackAddress.
|
||||
*
|
||||
* @return {@link InetAddress}
|
||||
*/
|
||||
public static InetAddress findFirstNonLoopbackAddress() {
|
||||
InetAddress result = null;
|
||||
|
||||
try {
|
||||
int lowest = Integer.MAX_VALUE;
|
||||
for (Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
|
||||
nics.hasMoreElements(); ) {
|
||||
NetworkInterface ifc = nics.nextElement();
|
||||
if (ifc.isUp()) {
|
||||
LOG.debug("Testing interface: " + ifc.getDisplayName());
|
||||
if (ifc.getIndex() < lowest || result == null) {
|
||||
lowest = ifc.getIndex();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ignoreInterface(ifc.getDisplayName())) {
|
||||
for (Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements(); ) {
|
||||
InetAddress address = addrs.nextElement();
|
||||
boolean isLegalIpVersion =
|
||||
InternetAddressUtil.PREFER_IPV6_ADDRESSES ? address instanceof Inet6Address
|
||||
: address instanceof Inet4Address;
|
||||
if (isLegalIpVersion && !address.isLoopbackAddress() && isPreferredAddress(address)) {
|
||||
LOG.debug("Found non-loopback interface: " + ifc.getDisplayName());
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Cannot get first non-loopback address", ex);
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
return InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
LOG.error("Unable to retrieve localhost", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isPreferredAddress(InetAddress address) {
|
||||
if (useOnlySiteLocalInterface) {
|
||||
final boolean siteLocalAddress = address.isSiteLocalAddress();
|
||||
if (!siteLocalAddress) {
|
||||
LOG.debug("Ignoring address: " + address.getHostAddress());
|
||||
}
|
||||
return siteLocalAddress;
|
||||
}
|
||||
if (PREFERRED_NETWORKS.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (String regex : PREFERRED_NETWORKS) {
|
||||
final String hostAddress = address.getHostAddress();
|
||||
if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean ignoreInterface(String interfaceName) {
|
||||
for (String regex : IGNORED_INTERFACES) {
|
||||
if (interfaceName.matches(regex)) {
|
||||
LOG.debug("Ignoring interface: " + interfaceName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link com.alibaba.nacos.core.cluster.ServerMemberManager} is listener.
|
||||
*/
|
||||
@SuppressWarnings({"PMD.ClassNamingShouldBeCamelRule", "checkstyle:AbbreviationAsWordInName"})
|
||||
public static class IPChangeEvent extends SlowEvent {
|
||||
|
||||
private String oldIP;
|
||||
|
||||
private String newIP;
|
||||
|
||||
public String getOldIP() {
|
||||
return oldIP;
|
||||
}
|
||||
|
||||
public void setOldIP(String oldIP) {
|
||||
this.oldIP = oldIP;
|
||||
}
|
||||
|
||||
public String getNewIP() {
|
||||
return newIP;
|
||||
}
|
||||
|
||||
public void setNewIP(String newIP) {
|
||||
this.newIP = newIP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IPChangeEvent{" + "oldIP='" + oldIP + '\'' + ", newIP='" + newIP + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* MethodUtil related.
|
||||
*
|
||||
* @author yanhom
|
||||
*/
|
||||
public final class MethodUtil {
|
||||
|
||||
private MethodUtil() {}
|
||||
|
||||
/**
|
||||
* Invoke method and return double value.
|
||||
*
|
||||
* @param method target method
|
||||
* @param targetObj the object the underlying method is invoked from
|
||||
* @return result
|
||||
*/
|
||||
public static double invokeAndReturnDouble(Method method, Object targetObj) {
|
||||
try {
|
||||
return method != null ? (double) method.invoke(targetObj) : Double.NaN;
|
||||
} catch (Exception e) {
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke method and return long value.
|
||||
*
|
||||
* @param method target method
|
||||
* @param targetObj the object the underlying method is invoked from
|
||||
* @return result
|
||||
*/
|
||||
public static long invokeAndReturnLong(Method method, Object targetObj) {
|
||||
try {
|
||||
return method != null ? (long) method.invoke(targetObj) : -1;
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 1999-2021 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.utils;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Properties util.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class PropertiesUtil {
|
||||
|
||||
public static Properties getPropertiesWithPrefix(Environment environment, String prefix) {
|
||||
return handleSpringBinder(environment, prefix, Properties.class);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getPropertiesWithPrefixForMap(Environment environment, String prefix) {
|
||||
return handleSpringBinder(environment, prefix, Map.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle spring binder to bind object.
|
||||
*
|
||||
* @param environment spring environment
|
||||
* @param prefix properties prefix
|
||||
* @param targetClass target class
|
||||
* @param <T> target class
|
||||
* @return binder object
|
||||
*/
|
||||
public static <T> T handleSpringBinder(Environment environment, String prefix, Class<T> targetClass) {
|
||||
String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
|
||||
return Binder.get(environment).bind(prefixParam, Bindable.of(targetClass)).orElse(null);
|
||||
}
|
||||
}
|
||||
152
sys/src/main/java/com/alibaba/nacos/sys/utils/TimerContext.java
Normal file
152
sys/src/main/java/com/alibaba/nacos/sys/utils/TimerContext.java
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.LoggerUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Simple task time calculation,Currently only the task time statistics task that supports synchronizing code blocks is
|
||||
* supported.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class TimerContext {
|
||||
|
||||
private static final ThreadLocal<Map<String, Long>> TIME_RECORD = ThreadLocal.withInitial(() -> new HashMap<>(2));
|
||||
|
||||
/**
|
||||
* Record context start time.
|
||||
*
|
||||
* @param name context name
|
||||
*/
|
||||
public static void start(final String name) {
|
||||
TIME_RECORD.get().put(name, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static void end(final String name, final Logger logger) {
|
||||
end(name, logger, LoggerUtils.DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* End the task and print based on the log level.
|
||||
*
|
||||
* @param name context name
|
||||
* @param logger logger
|
||||
* @param level logger level
|
||||
*/
|
||||
public static void end(final String name, final Logger logger, final String level) {
|
||||
Map<String, Long> record = TIME_RECORD.get();
|
||||
long contextTime = System.currentTimeMillis() - record.remove(name);
|
||||
if (record.isEmpty()) {
|
||||
TIME_RECORD.remove();
|
||||
}
|
||||
switch (level) {
|
||||
case LoggerUtils.DEBUG:
|
||||
LoggerUtils.printIfDebugEnabled(logger, "{} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
case LoggerUtils.INFO:
|
||||
LoggerUtils.printIfInfoEnabled(logger, "{} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
case LoggerUtils.TRACE:
|
||||
LoggerUtils.printIfTraceEnabled(logger, "{} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
case LoggerUtils.ERROR:
|
||||
LoggerUtils.printIfErrorEnabled(logger, "{} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
case LoggerUtils.WARN:
|
||||
LoggerUtils.printIfWarnEnabled(logger, "{} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
default:
|
||||
LoggerUtils.printIfErrorEnabled(logger, "level not found , {} cost time : {} ms", name, contextTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution with time-consuming calculations for {@link Runnable}.
|
||||
*
|
||||
* @param job runnable
|
||||
* @param name job name
|
||||
* @param logger logger
|
||||
*/
|
||||
public static void run(final Runnable job, final String name, final Logger logger) {
|
||||
start(name);
|
||||
try {
|
||||
job.run();
|
||||
} finally {
|
||||
end(name, logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution with time-consuming calculations for {@link Supplier}.
|
||||
*
|
||||
* @param job Supplier
|
||||
* @param name job name
|
||||
* @param logger logger
|
||||
*/
|
||||
public static <V> V run(final Supplier<V> job, final String name, final Logger logger) {
|
||||
start(name);
|
||||
try {
|
||||
return job.get();
|
||||
} finally {
|
||||
end(name, logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution with time-consuming calculations for {@link Function}.
|
||||
*
|
||||
* @param job Function
|
||||
* @param args args
|
||||
* @param name job name
|
||||
* @param logger logger
|
||||
*/
|
||||
public static <T, R> R run(final Function<T, R> job, T args, final String name, final Logger logger) {
|
||||
start(name);
|
||||
try {
|
||||
return job.apply(args);
|
||||
} finally {
|
||||
end(name, logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution with time-consuming calculations for {@link Consumer}.
|
||||
*
|
||||
* @param job Consumer
|
||||
* @param args args
|
||||
* @param name job name
|
||||
* @param logger logger
|
||||
*/
|
||||
public static <T> void run(final Consumer<T> job, T args, final String name, final Logger logger) {
|
||||
start(name);
|
||||
try {
|
||||
job.accept(args);
|
||||
} finally {
|
||||
end(name, logger);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
sys/src/main/resources/META-INF/nacos-default.properties
Normal file
36
sys/src/main/resources/META-INF/nacos-default.properties
Normal file
@ -0,0 +1,36 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# Nacos Default Properties
|
||||
|
||||
nacos.version=${project.version}
|
||||
|
||||
## Web Server
|
||||
server.servlet.contextPath=/nacos
|
||||
server.port=8848
|
||||
server.tomcat.uri-encoding=UTF-8
|
||||
|
||||
## HTTP Encoding
|
||||
spring.http.encoding.force=true
|
||||
spring.http.encoding.enabled=true
|
||||
|
||||
## i18n
|
||||
spring.messages.encoding=UTF-8
|
||||
|
||||
## Exclude Spring Boot Auto-Configuration class(es)
|
||||
spring.autoconfigure.exclude=\
|
||||
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
|
||||
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 1999-2023 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.
|
||||
#
|
||||
|
||||
com.alibaba.nacos.sys.env.EnvModuleStateBuilder
|
||||
3
sys/src/main/resources/META-INF/spring.factories
Normal file
3
sys/src/main/resources/META-INF/spring.factories
Normal file
@ -0,0 +1,3 @@
|
||||
# ApplicationContextInitializer
|
||||
org.springframework.context.ApplicationContextInitializer=\
|
||||
com.alibaba.nacos.sys.utils.ApplicationUtils
|
||||
49
sys/src/test/java/com/alibaba/nacos/sys/env/EnvModuleStateBuilderTest.java
vendored
Normal file
49
sys/src/test/java/com/alibaba/nacos/sys/env/EnvModuleStateBuilderTest.java
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.utils.VersionUtils;
|
||||
import com.alibaba.nacos.sys.module.ModuleState;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class EnvModuleStateBuilderTest {
|
||||
|
||||
private static ConfigurableEnvironment environment;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
environment = new MockEnvironment();
|
||||
EnvUtil.setEnvironment(environment);
|
||||
System.setProperty(Constants.STANDALONE_MODE_PROPERTY_NAME, "true");
|
||||
EnvUtil.setIsStandalone(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuild() {
|
||||
ModuleState actual = new EnvModuleStateBuilder().build();
|
||||
assertEquals(Constants.SYS_MODULE, actual.getModuleName());
|
||||
assertEquals(EnvUtil.STANDALONE_MODE_ALONE, actual.getStates().get(Constants.STARTUP_MODE_STATE));
|
||||
assertNull(EnvUtil.FUNCTION_MODE_NAMING, actual.getStates().get(Constants.FUNCTION_MODE_STATE));
|
||||
assertEquals(VersionUtils.version, actual.getStates().get(Constants.NACOS_VERSION));
|
||||
}
|
||||
}
|
||||
63
sys/src/test/java/com/alibaba/nacos/sys/env/EnvUtilWithConfigTest.java
vendored
Normal file
63
sys/src/test/java/com/alibaba/nacos/sys/env/EnvUtilWithConfigTest.java
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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 org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles("test")
|
||||
@SpringBootTest(classes = EnvUtilWithConfigTest.class)
|
||||
public class EnvUtilWithConfigTest {
|
||||
|
||||
private static final int SETTING_PROCESSORS = 10;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
EnvUtil.setEnvironment((ConfigurableEnvironment) environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessors() {
|
||||
int actual = EnvUtil.getAvailableProcessors();
|
||||
assertEquals(SETTING_PROCESSORS, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessorsWithMultiple() {
|
||||
int actual = EnvUtil.getAvailableProcessors(2);
|
||||
assertEquals(SETTING_PROCESSORS * 2, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessorsWithScale() {
|
||||
int actual = EnvUtil.getAvailableProcessors(0.5);
|
||||
assertEquals((int) (SETTING_PROCESSORS * 0.5), actual);
|
||||
}
|
||||
}
|
||||
65
sys/src/test/java/com/alibaba/nacos/sys/env/EnvUtilWithoutConfigTest.java
vendored
Normal file
65
sys/src/test/java/com/alibaba/nacos/sys/env/EnvUtilWithoutConfigTest.java
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 1999-2020 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.utils.ThreadUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles("empty")
|
||||
@SpringBootTest(classes = EnvUtilWithConfigTest.class)
|
||||
public class EnvUtilWithoutConfigTest {
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
EnvUtil.setEnvironment((ConfigurableEnvironment) environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessors() {
|
||||
int expected = ThreadUtils.getSuitableThreadCount(1);
|
||||
int actual = EnvUtil.getAvailableProcessors();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessorsWithMultiple() {
|
||||
int expected = ThreadUtils.getSuitableThreadCount(2);
|
||||
int actual = EnvUtil.getAvailableProcessors(2);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAvailableProcessorsWithScale() {
|
||||
int expected = ThreadUtils.getSuitableThreadCount(1);
|
||||
int actual = EnvUtil.getAvailableProcessors(0.5);
|
||||
assertEquals((int) (expected * 0.5), actual);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 1999-2021 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.module;
|
||||
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class ModuleStateHolderTest {
|
||||
|
||||
private Map<String, ModuleState> moduleStateMap;
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
environment = new MockEnvironment();
|
||||
EnvUtil.setEnvironment(environment);
|
||||
moduleStateMap = (Map<String, ModuleState>) ReflectionTestUtils
|
||||
.getField(ModuleStateHolder.getInstance(), ModuleStateHolder.class, "moduleStates");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetModuleState() {
|
||||
assertNotNull(ModuleStateHolder.getInstance().getModuleState("mock"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllModuleStates() {
|
||||
assertEquals(2, ModuleStateHolder.getInstance().getAllModuleStates().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateValueByNameFound() {
|
||||
assertEquals("test", ModuleStateHolder.getInstance().getStateValueByName("mock", "test"));
|
||||
assertEquals("test", ModuleStateHolder.getInstance().getStateValueByName("mock", "test", "aaa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateValueByNameWithoutModuleState() {
|
||||
assertEquals("", ModuleStateHolder.getInstance().getStateValueByName("non-exist", "test"));
|
||||
assertEquals("aaa", ModuleStateHolder.getInstance().getStateValueByName("non-exist", "test", "aaa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateValueByNameWithoutStateName() {
|
||||
assertEquals("", ModuleStateHolder.getInstance().getStateValueByName("mock", "non-exist"));
|
||||
assertEquals("aaa", ModuleStateHolder.getInstance().getStateValueByName("mock", "non-exist", "aaa"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchStateValue() {
|
||||
assertEquals("test", ModuleStateHolder.getInstance().searchStateValue("test", "aaa"));
|
||||
assertEquals("aaa", ModuleStateHolder.getInstance().searchStateValue("non-exist", "aaa"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.module.mock;
|
||||
|
||||
import com.alibaba.nacos.sys.module.ModuleState;
|
||||
import com.alibaba.nacos.sys.module.ModuleStateBuilder;
|
||||
|
||||
public class ExceptionMockModuleStateBuilder implements ModuleStateBuilder {
|
||||
|
||||
@Override
|
||||
public ModuleState build() {
|
||||
throw new RuntimeException("test");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2023 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.module.mock;
|
||||
|
||||
import com.alibaba.nacos.sys.module.ModuleState;
|
||||
import com.alibaba.nacos.sys.module.ModuleStateBuilder;
|
||||
|
||||
public class MockModuleStateBuilder implements ModuleStateBuilder {
|
||||
|
||||
@Override
|
||||
public ModuleState build() {
|
||||
ModuleState result = new ModuleState("mock");
|
||||
result.newState("test", "test").newState("mock", true);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
242
sys/src/test/java/com/alibaba/nacos/sys/utils/DiskUtilsTest.java
Normal file
242
sys/src/test/java/com/alibaba/nacos/sys/utils/DiskUtilsTest.java
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright 1999-2022 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.utils;
|
||||
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DiskUtilsTest {
|
||||
|
||||
private static File testFile;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws IOException {
|
||||
testFile = DiskUtils.createTmpFile("nacostmp", ".ut");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws IOException {
|
||||
testFile.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTouch() throws IOException {
|
||||
File file = Paths.get(EnvUtil.getNacosTmpDir(), "touch.ut").toFile();
|
||||
Assert.assertFalse(file.exists());
|
||||
DiskUtils.touch(file);
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTouchWithFileName() throws IOException {
|
||||
File file = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString()).toFile();
|
||||
Assert.assertFalse(file.exists());
|
||||
DiskUtils.touch(file.getParent(), file.getName());
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTmpFile() throws IOException {
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = DiskUtils.createTmpFile("nacos1", ".ut");
|
||||
Assert.assertTrue(tmpFile.getName().startsWith("nacos1"));
|
||||
Assert.assertTrue(tmpFile.getName().endsWith(".ut"));
|
||||
} finally {
|
||||
if (tmpFile != null) {
|
||||
tmpFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTmpFileWithPath() throws IOException {
|
||||
File tmpFile = null;
|
||||
try {
|
||||
tmpFile = DiskUtils.createTmpFile(EnvUtil.getNacosTmpDir(), "nacos1", ".ut");
|
||||
Assert.assertEquals(EnvUtil.getNacosTmpDir(), tmpFile.getParent());
|
||||
Assert.assertTrue(tmpFile.getName().startsWith("nacos1"));
|
||||
Assert.assertTrue(tmpFile.getName().endsWith(".ut"));
|
||||
} finally {
|
||||
if (tmpFile != null) {
|
||||
tmpFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFile() {
|
||||
Assert.assertNotNull(DiskUtils.readFile(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileWithInputStream() throws FileNotFoundException {
|
||||
Assert.assertNotNull(DiskUtils.readFile(new FileInputStream(testFile)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileWithPath() {
|
||||
Assert.assertNotNull(DiskUtils.readFile(testFile.getParent(), testFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileBytes() {
|
||||
Assert.assertNotNull(DiskUtils.readFileBytes(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFileBytesWithPath() {
|
||||
Assert.assertNotNull(DiskUtils.readFileBytes(testFile.getParent(), testFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeFile() {
|
||||
Assert.assertTrue(DiskUtils.writeFile(testFile, "unit test".getBytes(StandardCharsets.UTF_8), false));
|
||||
Assert.assertEquals("unit test", DiskUtils.readFile(testFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteQuietly() throws IOException {
|
||||
File tmpFile = DiskUtils.createTmpFile(UUID.randomUUID().toString(), ".ut");
|
||||
DiskUtils.deleteQuietly(tmpFile);
|
||||
Assert.assertFalse(tmpFile.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteQuietlyWithPath() throws IOException {
|
||||
String dir = EnvUtil.getNacosTmpDir() + "/" + "diskutils";
|
||||
DiskUtils.forceMkdir(dir);
|
||||
DiskUtils.createTmpFile(dir, "nacos", ".ut");
|
||||
Path path = Paths.get(dir);
|
||||
DiskUtils.deleteQuietly(path);
|
||||
|
||||
Assert.assertFalse(path.toFile().exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile() throws IOException {
|
||||
File tmpFile = DiskUtils.createTmpFile(UUID.randomUUID().toString(), ".ut");
|
||||
Assert.assertTrue(DiskUtils.deleteFile(tmpFile.getParent(), tmpFile.getName()));
|
||||
Assert.assertFalse(DiskUtils.deleteFile(tmpFile.getParent(), tmpFile.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDirectory() throws IOException {
|
||||
Path diskutils = Paths.get(EnvUtil.getNacosTmpDir(), "diskutils");
|
||||
File file = diskutils.toFile();
|
||||
if (!file.exists()) {
|
||||
file.mkdir();
|
||||
}
|
||||
|
||||
Assert.assertTrue(file.exists());
|
||||
DiskUtils.deleteDirectory(diskutils.toString());
|
||||
Assert.assertFalse(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceMkdir() throws IOException {
|
||||
File dir = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString(), UUID.randomUUID().toString())
|
||||
.toFile();
|
||||
DiskUtils.forceMkdir(dir);
|
||||
Assert.assertTrue(dir.exists());
|
||||
dir.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceMkdirWithPath() throws IOException {
|
||||
Path path = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(path.toString());
|
||||
File file = path.toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDirThenMkdir() throws IOException {
|
||||
Path path = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(path.toString());
|
||||
|
||||
DiskUtils.createTmpFile(path.toString(), UUID.randomUUID().toString(), ".ut");
|
||||
DiskUtils.createTmpFile(path.toString(), UUID.randomUUID().toString(), ".ut");
|
||||
|
||||
DiskUtils.deleteDirThenMkdir(path.toString());
|
||||
|
||||
File file = path.toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
Assert.assertTrue(file.isDirectory());
|
||||
Assert.assertTrue(file.list() == null || file.list().length == 0);
|
||||
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyDirectory() throws IOException {
|
||||
Path srcPath = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString());
|
||||
DiskUtils.forceMkdir(srcPath.toString());
|
||||
File nacos = DiskUtils.createTmpFile(srcPath.toString(), "nacos", ".ut");
|
||||
|
||||
Path destPath = Paths.get(EnvUtil.getNacosTmpDir(), UUID.randomUUID().toString());
|
||||
DiskUtils.copyDirectory(srcPath.toFile(), destPath.toFile());
|
||||
|
||||
File file = Paths.get(destPath.toString(), nacos.getName()).toFile();
|
||||
Assert.assertTrue(file.exists());
|
||||
|
||||
DiskUtils.deleteDirectory(srcPath.toString());
|
||||
DiskUtils.deleteDirectory(destPath.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFile() throws IOException {
|
||||
File nacos = DiskUtils.createTmpFile("nacos", ".ut");
|
||||
DiskUtils.copyFile(testFile, nacos);
|
||||
|
||||
Assert.assertEquals(DiskUtils.readFile(testFile), DiskUtils.readFile(nacos));
|
||||
|
||||
nacos.deleteOnExit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openFile() {
|
||||
File file = DiskUtils.openFile(testFile.getParent(), testFile.getName());
|
||||
Assert.assertNotNull(file);
|
||||
Assert.assertEquals(testFile.getPath(), file.getPath());
|
||||
Assert.assertEquals(testFile.getName(), file.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenFileWithPath() {
|
||||
File file = DiskUtils.openFile(testFile.getParent(), testFile.getName(), false);
|
||||
Assert.assertNotNull(file);
|
||||
Assert.assertEquals(testFile.getPath(), file.getPath());
|
||||
Assert.assertEquals(testFile.getName(), file.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.sys.env.Constants;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.sys.env.Constants.NACOS_SERVER_IP;
|
||||
|
||||
public class InetUtilsTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
EnvUtil.setEnvironment(new MockEnvironment());
|
||||
System.setProperty(NACOS_SERVER_IP, "1.1.1.1");
|
||||
System.setProperty(Constants.AUTO_REFRESH_TIME, "100");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshIp() throws InterruptedException {
|
||||
Assert.assertEquals("1.1.1.1", InetUtils.getSelfIP());
|
||||
|
||||
System.setProperty(NACOS_SERVER_IP, "1.1.1.2");
|
||||
TimeUnit.MILLISECONDS.sleep(300L);
|
||||
|
||||
Assert.assertTrue(StringUtils.equalsIgnoreCase(InetUtils.getSelfIP(), "1.1.1.2"));
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
System.clearProperty(NACOS_SERVER_IP);
|
||||
System.clearProperty(Constants.AUTO_REFRESH_TIME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSelfIP() {
|
||||
Assert.assertNotNull(InetUtils.getSelfIP());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findFirstNonLoopbackAddress() {
|
||||
InetAddress address = InetUtils.findFirstNonLoopbackAddress();
|
||||
|
||||
Assert.assertNotNull(address);
|
||||
Assert.assertFalse(address.isLoopbackAddress());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 1999-2022 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.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MethodUtilTest {
|
||||
|
||||
private static final Method DOUBLE_METHOD;
|
||||
|
||||
private static final Method LONG_METHOD;
|
||||
|
||||
static {
|
||||
try {
|
||||
DOUBLE_METHOD = InternalMethod.class.getMethod("getD");
|
||||
LONG_METHOD = InternalMethod.class.getMethod("getL");
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeAndReturnDouble() {
|
||||
InternalMethod internalMethod = new InternalMethod();
|
||||
Assert.assertNotEquals(Double.NaN, MethodUtil.invokeAndReturnDouble(DOUBLE_METHOD, internalMethod), 0.000001d);
|
||||
|
||||
Assert.assertEquals(Double.NaN, MethodUtil.invokeAndReturnDouble(LONG_METHOD, internalMethod), 0.000001d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeAndReturnLong() {
|
||||
InternalMethod internalMethod = new InternalMethod();
|
||||
Assert.assertEquals(100L, MethodUtil.invokeAndReturnLong(LONG_METHOD, internalMethod));
|
||||
Assert.assertNotEquals(100L, MethodUtil.invokeAndReturnLong(DOUBLE_METHOD, internalMethod));
|
||||
}
|
||||
|
||||
public static class InternalMethod {
|
||||
|
||||
private double d = 1.1d;
|
||||
|
||||
private long l = 100L;
|
||||
|
||||
public double getD() {
|
||||
return d;
|
||||
}
|
||||
|
||||
public long getL() {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 1999-2021 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.utils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles("prefix")
|
||||
@SpringBootTest(classes = PropertiesUtilTest.class)
|
||||
public class PropertiesUtilTest {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetPropertiesWithPrefixForMap() {
|
||||
Map<String, Object> actual = PropertiesUtil.getPropertiesWithPrefixForMap(environment, "nacos.prefix");
|
||||
assertEquals(3, actual.size());
|
||||
for (Map.Entry<String, Object> entry : actual.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Map<String, Object> subMap = (Map<String, Object>) entry.getValue();
|
||||
switch (key) {
|
||||
case "one":
|
||||
assertEquals("1", subMap.get("value"));
|
||||
break;
|
||||
case "two":
|
||||
assertEquals("2", subMap.get("value"));
|
||||
break;
|
||||
case "three":
|
||||
assertEquals("3", subMap.get("value"));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPropertiesWithPrefix() {
|
||||
Properties actual = PropertiesUtil.getPropertiesWithPrefix(environment, "nacos.prefix");
|
||||
assertEquals(3, actual.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSpringBinder() {
|
||||
Map properties = PropertiesUtil.handleSpringBinder(environment, "nacos.prefix", Map.class);
|
||||
assertEquals(3, properties.size());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 1999-2023 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.
|
||||
#
|
||||
|
||||
com.alibaba.nacos.sys.module.mock.MockModuleStateBuilder
|
||||
com.alibaba.nacos.sys.module.mock.ExceptionMockModuleStateBuilder
|
||||
15
sys/src/test/resources/application-empty.properties
Normal file
15
sys/src/test/resources/application-empty.properties
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
20
sys/src/test/resources/application-prefix.properties
Normal file
20
sys/src/test/resources/application-prefix.properties
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
nacos.prefix.one.value=1
|
||||
nacos.prefix.two.value=2
|
||||
nacos.prefix.three.value=3
|
||||
nacos.other.prefix.one.value=1
|
||||
17
sys/src/test/resources/application-test.properties
Normal file
17
sys/src/test/resources/application-test.properties
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
nacos.core.sys.basic.processors=10
|
||||
17
sys/src/test/resources/application.properties
Normal file
17
sys/src/test/resources/application.properties
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
name=test-1
|
||||
Reference in New Issue
Block a user