----初始化项目

This commit is contained in:
2025-09-19 20:49:14 +08:00
parent b345d2828d
commit df7765c400
2867 changed files with 359313 additions and 89 deletions

71
sys/pom.xml Normal file
View 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>

View 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";
}

View 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;
}
}

View 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&lt;String, Object&gt;
* @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;
}
}

View 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;
}
}
}

View 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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View 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.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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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);
}
}
}

View 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 + '\'' + '}';
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View 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 calculationCurrently 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);
}
}
}

View 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

View File

@ -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

View File

@ -0,0 +1,3 @@
# ApplicationContextInitializer
org.springframework.context.ApplicationContextInitializer=\
com.alibaba.nacos.sys.utils.ApplicationUtils

View 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));
}
}

View 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);
}
}

View 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);
}
}

View File

@ -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"));
}
}

View File

@ -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");
}
}

View File

@ -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;
}
}

View 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());
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}
}

View File

@ -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());
}
}

View File

@ -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

View 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.
#

View 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

View 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

View 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