Skip to content

Commit

Permalink
optimize: seata server startup mode support nacos yaml config ability (
Browse files Browse the repository at this point in the history
  • Loading branch information
Smile committed Sep 14, 2021
1 parent 207b09d commit a38b873
Show file tree
Hide file tree
Showing 18 changed files with 530 additions and 72 deletions.
2 changes: 2 additions & 0 deletions changes/1.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [[#3982](https://github.com/seata/seata/pull/3982)] 优化 readme 文档和升级POM依赖
- [[#3991](https://github.com/seata/seata/pull/3991)] 关闭spring boot下无用的fileListener
- [[#3327](https://github.com/seata/seata/pull/3327)] 支持从etcd3单一key中读取所有配置
- [[#4001](https://github.com/seata/seata/pull/4001)] 支持从nacos,zk,consul,etcd3中读取yml
- [[#4017](https://github.com/seata/seata/pull/4017)] 优化文件配置


Expand Down Expand Up @@ -147,6 +148,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [lvekee](https://github.com/lvekee)
- [elrond-g](https://github.com/elrond-g)
- [Rubbernecker](https://github.com/Rubbernecker)
- [zhixing](https://github.com/chenlei3641)


同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。
Expand Down
3 changes: 2 additions & 1 deletion changes/en-us/1.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
- [[#3949](https://github.com/seata/seata/pull/3949)] `nacos-config.py` support default parameters and optional input parameters
- [[#3991](https://github.com/seata/seata/pull/3991)] disable listening in the FileConfiguration center in Springboot
- [[#3327](https://github.com/seata/seata/pull/3327)] supports reading all configurations from a single Etcd3 key
- [[#4001](https://github.com/seata/seata/pull/4001)] support to read YML from NACOS, ZK, Consul, ETCD3
- [[#4017](https://github.com/seata/seata/pull/4017)] optimize file configuration

### test:
Expand Down Expand Up @@ -144,7 +145,7 @@
- [jsbxyyx](https://github.com/jsbxyyx)
- [lvekee](https://github.com/lvekee)
- [elrond-g](https://github.com/elrond-g)

- [zhixing](https://github.com/chenlei3641)

Also, we receive many valuable issues, questions and advices from our community. Thanks for you all.

Expand Down
105 changes: 105 additions & 0 deletions common/src/main/java/io/seata/common/util/MapUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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.common.util;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Map Util
*
* @author zhixing
*/
public class MapUtil {

/**
* obj convert to Map
*
* @param object
* @return Map<String,Object>
*/
public static Map<String, Object> asMap(Object object) {
// YAML can have numbers as keys
Map<String, Object> result = new LinkedHashMap<>();
if (!(object instanceof Map)) {
// A document can be a text literal
result.put("document", object);
return result;
}

Map<Object, Object> map = (Map<Object, Object>) object;
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object value = entry.getValue();
if (value instanceof Map) {
value = asMap(value);
}
Object key = entry.getKey();
if (key instanceof CharSequence) {
result.put(key.toString(), value);
} else {
// It has to be a map key in this case
result.put("[" + key.toString() + "]", value);
}
}
return result;
}
/**
* get flattened Map
*
* @param source
* @return Map<String,Object>
*/
public static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, null);
return result;
}

private static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
for (Map.Entry<String, Object> entry : source.entrySet()) {
String key = entry.getKey();
if (StringUtils.isNotBlank(path)) {
if (key.startsWith("[")) {
key = path + key;
} else {
key = path + '.' + key;
}
}
Object value = entry.getValue();
if (value instanceof String) {
result.put(key, value);
} else if (value instanceof Map) {
// Need a compound key
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) value;
buildFlattenedMap(result, map, key);
} else if (value instanceof Collection) {
// Need a compound key
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) value;
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result,
Collections.singletonMap("[" + (count++) + "]", object), key);
}
} else {
result.put(key, value != null ? value : "");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@
*/
package io.seata.config.consul;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
Expand Down Expand Up @@ -48,6 +44,7 @@
import io.seata.config.ConfigurationChangeEvent;
import io.seata.config.ConfigurationChangeListener;
import io.seata.config.ConfigurationFactory;
import io.seata.config.processor.ConfigProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -266,8 +263,8 @@ private void initSeataConfig() {
String config = kvValue.getValue().getDecodedValue();

if (StringUtils.isNotBlank(config)) {
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(config.getBytes()), StandardCharsets.UTF_8)) {
seataConfig.load(reader);
try {
seataConfig = ConfigProcessor.processConfig(config, getConsulDataType());
} catch (IOException e) {
LOGGER.error("init config properties error", e);
}
Expand All @@ -277,6 +274,10 @@ private void initSeataConfig() {
consulListener.onProcessEvent(new ConfigurationChangeEvent());
}

private static String getConsulDataType() {
return ConfigProcessor.resolverConfigDataType(getConsulConfigKey());
}

private static String getConsulConfigKey() {
return FILE_CONFIG.getConfig(FILE_CONFIG_KEY_PREFIX + CONSUL_CONFIG_KEY, DEFAULT_CONSUL_CONFIG_KEY_VALUE);
}
Expand Down Expand Up @@ -329,9 +330,9 @@ public void onChangeEvent(ConfigurationChangeEvent event) {
consulIndex = currentIndex;
if (dataId.equals(getConsulConfigKey())) {
// The new config change listener
Properties seataConfigNew = new Properties();
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(value.getBytes()), StandardCharsets.UTF_8)) {
seataConfigNew.load(reader);
Properties seataConfigNew;
try {
seataConfigNew = ConfigProcessor.processConfig(value, getConsulDataType());
} catch (IOException e) {
LOGGER.error("load config properties error", e);
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ public interface ConfigurationKeys {
* The constant FILE_ROOT_TYPE.
*/
String FILE_ROOT_TYPE = "type";
/**
* The constant DATA_TYPE.
*/
String DATA_TYPE = "dataType";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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.processor;

/**
* The enum Config Data type.
*
* @author zhixing
*/
public enum ConfigDataType {
/**
* data type yaml
*/
yaml("yaml","yml"),
/**
* data type properties
*/
properties("properties");


/**
* suffix support data type
*/
private String[] suffix;

ConfigDataType(String... suffix) {
this.suffix = suffix;
}

/**
* Gets type.
*
* @param name the name
* @return the type
*/
public static ConfigDataType getType(String name) {
for (ConfigDataType configDataType : values()) {
if (configDataType.name().equalsIgnoreCase(name)) {
return configDataType;
}
}
throw new IllegalArgumentException("not support config data type type: " + name);
}

/**
* Gets type by suffix.
*
* @param suffix the suffix
* @return the type
*/
public static ConfigDataType getTypeBySuffix(String suffix) {
for (ConfigDataType configDataType : values()) {
for (String sfx : configDataType.suffix) {
if (sfx.equals(suffix)) {
return configDataType;
}
}
}
throw new IllegalArgumentException("not support config data type suffix: " + suffix);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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.processor;

import io.seata.common.loader.EnhancedServiceLoader;
import io.seata.common.util.StringUtils;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
import io.seata.config.ConfigurationKeys;

import java.io.IOException;
import java.util.Properties;

/**
* The Config Processor.
*
* @author zhixing
*/
public class ConfigProcessor {
private static final String SEPARATOR = ".";
private static final Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE;
private static final String DEFAULT_DATA_TYPE = "properties";
/**
* processing configuration
*
* @param config config string
* @param dataType the data type
* @return the properties
* @throws IOException IOException
*/
public static Properties processConfig(String config, String dataType) throws IOException {
return EnhancedServiceLoader.load(Processor.class, dataType).processor(config);
}

/**
* resolver config data type
*
* @param dataId the configured data id
* @return data type
*/
public static String resolverConfigDataType(String dataId) {
return resolverConfigDataType(FILE_CONFIG.getConfig(getDataTypeKey()),dataId,DEFAULT_DATA_TYPE);
}

/**
* resolver config data type
*
* @param dataType the configured data type
* @param dataId the configured data id
* @param defaultDataType the default data type
* @return data type
*/
public static String resolverConfigDataType(String dataType,String dataId,String defaultDataType) {
if (StringUtils.isNotBlank(dataType)) {
return dataType;
}
if (!dataId.contains(SEPARATOR)) {
return defaultDataType;
}
String[] splitString = dataId.split("\\" + SEPARATOR);
try {
ConfigDataType configDataType = ConfigDataType.getTypeBySuffix(splitString[splitString.length - 1]);
return configDataType.name();
} catch (IllegalArgumentException e) {
return defaultDataType;
}

}

private static String getDataTypeKey() {
return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, ConfigurationKeys.DATA_TYPE);
}

}
Loading

0 comments on commit a38b873

Please sign in to comment.