chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
40
config/seata-config-nacos/pom.xml
Normal file
40
config/seata-config-nacos/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ 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>io.seata</groupId>
|
||||
<artifactId>seata-config</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>seata-config-nacos</artifactId>
|
||||
<name>seata-config-nacos ${project.version}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-config-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* 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 io.seata.config.nacos;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.AbstractConfiguration;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationChangeEvent;
|
||||
import io.seata.config.ConfigurationChangeListener;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.config.ConfigurationKeys;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* The type Nacos configuration.
|
||||
*
|
||||
* @author slievrly
|
||||
*/
|
||||
public class NacosConfiguration extends AbstractConfiguration {
|
||||
private static volatile NacosConfiguration instance;
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfiguration.class);
|
||||
private static final String DEFAULT_GROUP = "SEATA_GROUP";
|
||||
private static final String DEFAULT_DATA_ID = "seata.properties";
|
||||
private static final String GROUP_KEY = "group";
|
||||
private static final String PRO_SERVER_ADDR_KEY = "serverAddr";
|
||||
private static final String NACOS_DATA_ID_KEY = "dataId";
|
||||
private static final String ENDPOINT_KEY = "endpoint";
|
||||
private static final String CONFIG_TYPE = "nacos";
|
||||
private static final String DEFAULT_NAMESPACE = "";
|
||||
private static final String PRO_NAMESPACE_KEY = "namespace";
|
||||
private static final String USER_NAME = "username";
|
||||
private static final String PASSWORD = "password";
|
||||
private static final String ACCESS_KEY = "accessKey";
|
||||
private static final String SECRET_KEY = "secretKey";
|
||||
private static final Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE;
|
||||
private static volatile ConfigService configService;
|
||||
private static final int MAP_INITIAL_CAPACITY = 8;
|
||||
private static final ConcurrentMap<String, ConcurrentMap<ConfigurationChangeListener, NacosListener>> CONFIG_LISTENERS_MAP
|
||||
= new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
|
||||
private static volatile Properties seataConfig = new Properties();
|
||||
|
||||
/**
|
||||
* Get instance of NacosConfiguration
|
||||
*
|
||||
* @return instance
|
||||
*/
|
||||
public static NacosConfiguration getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (NacosConfiguration.class) {
|
||||
if (instance == null) {
|
||||
instance = new NacosConfiguration();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Nacos configuration.
|
||||
*/
|
||||
private NacosConfiguration() {
|
||||
if (configService == null) {
|
||||
try {
|
||||
configService = NacosFactory.createConfigService(getConfigProperties());
|
||||
initSeataConfig();
|
||||
} catch (NacosException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLatestConfig(String dataId, String defaultValue, long timeoutMills) {
|
||||
String value = getConfigFromSysPro(dataId);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value = seataConfig.getProperty(dataId);
|
||||
|
||||
if (null == value) {
|
||||
try {
|
||||
value = configService.getConfig(dataId, getNacosGroup(), timeoutMills);
|
||||
} catch (NacosException exx) {
|
||||
LOGGER.error(exx.getErrMsg());
|
||||
}
|
||||
}
|
||||
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putConfig(String dataId, String content, long timeoutMills) {
|
||||
boolean result = false;
|
||||
try {
|
||||
if (!seataConfig.isEmpty()) {
|
||||
seataConfig.setProperty(dataId, content);
|
||||
result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr());
|
||||
} else {
|
||||
result = configService.publishConfig(dataId, getNacosGroup(), content);
|
||||
}
|
||||
} catch (NacosException exx) {
|
||||
LOGGER.error(exx.getErrMsg());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putConfigIfAbsent(String dataId, String content, long timeoutMills) {
|
||||
throw new NotSupportYetException("not support atomic operation putConfigIfAbsent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeConfig(String dataId, long timeoutMills) {
|
||||
boolean result = false;
|
||||
try {
|
||||
if (!seataConfig.isEmpty()) {
|
||||
seataConfig.remove(dataId);
|
||||
result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr());
|
||||
} else {
|
||||
result = configService.removeConfig(dataId, getNacosGroup());
|
||||
}
|
||||
} catch (NacosException exx) {
|
||||
LOGGER.error(exx.getErrMsg());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addConfigListener(String dataId, ConfigurationChangeListener listener) {
|
||||
if (StringUtils.isBlank(dataId) || listener == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
NacosListener nacosListener = new NacosListener(dataId, listener);
|
||||
CONFIG_LISTENERS_MAP.computeIfAbsent(dataId, key -> new ConcurrentHashMap<>())
|
||||
.put(listener, nacosListener);
|
||||
configService.addListener(dataId, getNacosGroup(), nacosListener);
|
||||
} catch (Exception exx) {
|
||||
LOGGER.error("add nacos listener error:{}", exx.getMessage(), exx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeConfigListener(String dataId, ConfigurationChangeListener listener) {
|
||||
if (StringUtils.isBlank(dataId) || listener == null) {
|
||||
return;
|
||||
}
|
||||
Set<ConfigurationChangeListener> configChangeListeners = getConfigListeners(dataId);
|
||||
if (CollectionUtils.isNotEmpty(configChangeListeners)) {
|
||||
for (ConfigurationChangeListener entry : configChangeListeners) {
|
||||
if (listener.equals(entry)) {
|
||||
NacosListener nacosListener = null;
|
||||
Map<ConfigurationChangeListener, NacosListener> configListeners = CONFIG_LISTENERS_MAP.get(dataId);
|
||||
if (configListeners != null) {
|
||||
nacosListener = configListeners.get(listener);
|
||||
configListeners.remove(entry);
|
||||
}
|
||||
if (nacosListener != null) {
|
||||
configService.removeListener(dataId, getNacosGroup(), nacosListener);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ConfigurationChangeListener> getConfigListeners(String dataId) {
|
||||
Map<ConfigurationChangeListener, NacosListener> configListeners = CONFIG_LISTENERS_MAP.get(dataId);
|
||||
if (CollectionUtils.isNotEmpty(configListeners)) {
|
||||
return configListeners.keySet();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties getConfigProperties() {
|
||||
Properties properties = new Properties();
|
||||
if (System.getProperty(ENDPOINT_KEY) != null) {
|
||||
properties.setProperty(ENDPOINT_KEY, System.getProperty(ENDPOINT_KEY));
|
||||
properties.put(ACCESS_KEY, Objects.toString(System.getProperty(ACCESS_KEY), ""));
|
||||
properties.put(SECRET_KEY, Objects.toString(System.getProperty(SECRET_KEY), ""));
|
||||
} else if (System.getProperty(PRO_SERVER_ADDR_KEY) != null) {
|
||||
properties.setProperty(PRO_SERVER_ADDR_KEY, System.getProperty(PRO_SERVER_ADDR_KEY));
|
||||
} else {
|
||||
String address = FILE_CONFIG.getConfig(getNacosAddrFileKey());
|
||||
if (address != null) {
|
||||
properties.setProperty(PRO_SERVER_ADDR_KEY, address);
|
||||
}
|
||||
}
|
||||
|
||||
if (System.getProperty(PRO_NAMESPACE_KEY) != null) {
|
||||
properties.setProperty(PRO_NAMESPACE_KEY, System.getProperty(PRO_NAMESPACE_KEY));
|
||||
} else {
|
||||
String namespace = FILE_CONFIG.getConfig(getNacosNameSpaceFileKey());
|
||||
if (namespace == null) {
|
||||
namespace = DEFAULT_NAMESPACE;
|
||||
}
|
||||
properties.setProperty(PRO_NAMESPACE_KEY, namespace);
|
||||
}
|
||||
String userName = StringUtils.isNotBlank(System.getProperty(USER_NAME)) ? System.getProperty(USER_NAME)
|
||||
: FILE_CONFIG.getConfig(getNacosUserName());
|
||||
if (StringUtils.isNotBlank(userName)) {
|
||||
String password = StringUtils.isNotBlank(System.getProperty(PASSWORD)) ? System.getProperty(PASSWORD)
|
||||
: FILE_CONFIG.getConfig(getNacosPassword());
|
||||
if (StringUtils.isNotBlank(password)) {
|
||||
properties.setProperty(USER_NAME, userName);
|
||||
properties.setProperty(PASSWORD, password);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static String getNacosNameSpaceFileKey() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, PRO_NAMESPACE_KEY);
|
||||
}
|
||||
|
||||
private static String getNacosAddrFileKey() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, PRO_SERVER_ADDR_KEY);
|
||||
}
|
||||
|
||||
private static String getNacosGroupKey() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, GROUP_KEY);
|
||||
}
|
||||
|
||||
private static String getNacosDataIdKey() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, NACOS_DATA_ID_KEY);
|
||||
}
|
||||
|
||||
private static String getNacosUserName() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE,
|
||||
USER_NAME);
|
||||
}
|
||||
|
||||
private static String getNacosPassword() {
|
||||
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE,
|
||||
PASSWORD);
|
||||
}
|
||||
|
||||
private static String getNacosGroup() {
|
||||
return FILE_CONFIG.getConfig(getNacosGroupKey(), DEFAULT_GROUP);
|
||||
}
|
||||
|
||||
private static String getNacosDataId() {
|
||||
return FILE_CONFIG.getConfig(getNacosDataIdKey(), DEFAULT_DATA_ID);
|
||||
}
|
||||
|
||||
private static String getSeataConfigStr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
Enumeration<?> enumeration = seataConfig.propertyNames();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
String key = (String) enumeration.nextElement();
|
||||
String property = seataConfig.getProperty(key);
|
||||
sb.append(key).append("=").append(property).append("\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void initSeataConfig() {
|
||||
try {
|
||||
String nacosDataId = getNacosDataId();
|
||||
String config = configService.getConfig(nacosDataId, getNacosGroup(), DEFAULT_CONFIG_TIMEOUT);
|
||||
if (StringUtils.isNotBlank(config)) {
|
||||
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(config.getBytes()), StandardCharsets.UTF_8)) {
|
||||
seataConfig.load(reader);
|
||||
}
|
||||
NacosListener nacosListener = new NacosListener(nacosDataId, null);
|
||||
configService.addListener(nacosDataId, getNacosGroup(), nacosListener);
|
||||
}
|
||||
} catch (NacosException | IOException e) {
|
||||
LOGGER.error("init config properties error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return CONFIG_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-blocking subscriptions prohibit adding subscriptions in the thread pool to prevent thread termination
|
||||
*/
|
||||
public static class NacosListener extends AbstractSharedListener {
|
||||
private final String dataId;
|
||||
private final ConfigurationChangeListener listener;
|
||||
|
||||
/**
|
||||
* Instantiates a new Nacos listener.
|
||||
*
|
||||
* @param dataId the data id
|
||||
* @param listener the listener
|
||||
*/
|
||||
public NacosListener(String dataId, ConfigurationChangeListener listener) {
|
||||
this.dataId = dataId;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets target listener.
|
||||
*
|
||||
* @return the target listener
|
||||
*/
|
||||
public ConfigurationChangeListener getTargetListener() {
|
||||
return this.listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void innerReceive(String dataId, String group, String configInfo) {
|
||||
//The new configuration method to puts all configurations into a dateId
|
||||
if (getNacosDataId().equals(dataId)) {
|
||||
Properties seataConfigNew = new Properties();
|
||||
if (StringUtils.isNotBlank(configInfo)) {
|
||||
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(configInfo.getBytes()), StandardCharsets.UTF_8)) {
|
||||
seataConfigNew.load(reader);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("load config properties error", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Get all the monitored dataids and judge whether it has been modified
|
||||
for (Map.Entry<String, ConcurrentMap<ConfigurationChangeListener, NacosListener>> entry : CONFIG_LISTENERS_MAP.entrySet()) {
|
||||
String listenedDataId = entry.getKey();
|
||||
String propertyOld = seataConfig.getProperty(listenedDataId, "");
|
||||
String propertyNew = seataConfigNew.getProperty(listenedDataId, "");
|
||||
if (!propertyOld.equals(propertyNew)) {
|
||||
ConfigurationChangeEvent event = new ConfigurationChangeEvent()
|
||||
.setDataId(listenedDataId)
|
||||
.setNewValue(propertyNew)
|
||||
.setNamespace(group);
|
||||
|
||||
ConcurrentMap<ConfigurationChangeListener, NacosListener> configListeners = entry.getValue();
|
||||
for (ConfigurationChangeListener configListener : configListeners.keySet()) {
|
||||
configListener.onProcessEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seataConfig = seataConfigNew;
|
||||
return;
|
||||
}
|
||||
|
||||
//Compatible with old writing
|
||||
ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(dataId).setNewValue(configInfo)
|
||||
.setNamespace(group);
|
||||
listener.onProcessEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* 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 io.seata.config.nacos;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationProvider;
|
||||
|
||||
/**
|
||||
* @author xingfudeshi@gmail.com
|
||||
*/
|
||||
@LoadLevel(name = "Nacos", order = 1)
|
||||
public class NacosConfigurationProvider implements ConfigurationProvider {
|
||||
@Override
|
||||
public Configuration provide() {
|
||||
return NacosConfiguration.getInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.config.nacos.NacosConfigurationProvider
|
||||
Reference in New Issue
Block a user