format check on client labels (#11903)
* format check on client labels * log optimize * testcase fix
This commit is contained in:
parent
2df335d57e
commit
5fcef225be
@ -59,6 +59,8 @@ public class DefaultLabelsCollector implements LabelsCollector {
|
|||||||
public Map<String, String> collectLabels(Properties properties) {
|
public Map<String, String> collectLabels(Properties properties) {
|
||||||
|
|
||||||
//properties
|
//properties
|
||||||
|
LOGGER.info("default nacos collect properties raw labels: {}",
|
||||||
|
properties.getProperty(Constants.APP_CONN_LABELS_KEY));
|
||||||
Map<String, String> propertiesLabels = ConnLabelsUtils.parseRawLabels(
|
Map<String, String> propertiesLabels = ConnLabelsUtils.parseRawLabels(
|
||||||
properties.getProperty(Constants.APP_CONN_LABELS_KEY));
|
properties.getProperty(Constants.APP_CONN_LABELS_KEY));
|
||||||
if (properties.containsKey(Constants.CONFIG_GRAY_LABEL)) {
|
if (properties.containsKey(Constants.CONFIG_GRAY_LABEL)) {
|
||||||
@ -67,6 +69,7 @@ public class DefaultLabelsCollector implements LabelsCollector {
|
|||||||
LOGGER.info("default nacos collect properties labels: {}", propertiesLabels);
|
LOGGER.info("default nacos collect properties labels: {}", propertiesLabels);
|
||||||
|
|
||||||
//jvm
|
//jvm
|
||||||
|
LOGGER.info("default nacos collect jvm raw labels: {}", System.getProperty(Constants.APP_CONN_LABELS_KEY));
|
||||||
Map<String, String> jvmLabels = ConnLabelsUtils.parseRawLabels(
|
Map<String, String> jvmLabels = ConnLabelsUtils.parseRawLabels(
|
||||||
System.getProperty(Constants.APP_CONN_LABELS_KEY));
|
System.getProperty(Constants.APP_CONN_LABELS_KEY));
|
||||||
if (System.getProperty(Constants.CONFIG_GRAY_LABEL) != null) {
|
if (System.getProperty(Constants.CONFIG_GRAY_LABEL) != null) {
|
||||||
@ -75,6 +78,8 @@ public class DefaultLabelsCollector implements LabelsCollector {
|
|||||||
LOGGER.info("default nacos collect jvm labels: {}", jvmLabels);
|
LOGGER.info("default nacos collect jvm labels: {}", jvmLabels);
|
||||||
|
|
||||||
//env
|
//env
|
||||||
|
LOGGER.info("default nacos collect env raw labels: {}",
|
||||||
|
System.getenv(Constants.APP_CONN_LABELS_KEY.replaceAll(DOT, UNDERSCORE)));
|
||||||
Map<String, String> envLabels = ConnLabelsUtils.parseRawLabels(
|
Map<String, String> envLabels = ConnLabelsUtils.parseRawLabels(
|
||||||
System.getenv(Constants.APP_CONN_LABELS_KEY.replaceAll(DOT, UNDERSCORE)));
|
System.getenv(Constants.APP_CONN_LABELS_KEY.replaceAll(DOT, UNDERSCORE)));
|
||||||
if (System.getenv(Constants.CONFIG_GRAY_LABEL.replaceAll(DOT, UNDERSCORE)) != null) {
|
if (System.getenv(Constants.CONFIG_GRAY_LABEL.replaceAll(DOT, UNDERSCORE)) != null) {
|
||||||
|
@ -18,6 +18,7 @@ package com.alibaba.nacos.common.labels.impl;
|
|||||||
|
|
||||||
import com.alibaba.nacos.common.labels.LabelsCollector;
|
import com.alibaba.nacos.common.labels.LabelsCollector;
|
||||||
import com.alibaba.nacos.common.labels.LabelsCollectorManager;
|
import com.alibaba.nacos.common.labels.LabelsCollectorManager;
|
||||||
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -60,6 +61,11 @@ public class DefaultLabelsCollectorManager implements LabelsCollectorManager {
|
|||||||
|
|
||||||
LOGGER.info("Process LabelsCollector with [name:{}]", labelsCollector.getName());
|
LOGGER.info("Process LabelsCollector with [name:{}]", labelsCollector.getName());
|
||||||
for (Map.Entry<String, String> entry : labelsCollector.collectLabels(properties).entrySet()) {
|
for (Map.Entry<String, String> entry : labelsCollector.collectLabels(properties).entrySet()) {
|
||||||
|
if (!checkValidLabel(entry.getKey(), entry.getValue())) {
|
||||||
|
LOGGER.info(" ignore invalid label with [key:{}, value:{}] of collector [name:{}]", entry.getKey(),
|
||||||
|
entry.getValue(), labelsCollector.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (innerAddLabel(labels, entry.getKey(), entry.getValue())) {
|
if (innerAddLabel(labels, entry.getKey(), entry.getValue())) {
|
||||||
LOGGER.info("pick label with [key:{}, value:{}] of collector [name:{}]", entry.getKey(),
|
LOGGER.info("pick label with [key:{}, value:{}] of collector [name:{}]", entry.getKey(),
|
||||||
entry.getValue(), labelsCollector.getName());
|
entry.getValue(), labelsCollector.getName());
|
||||||
@ -73,6 +79,40 @@ public class DefaultLabelsCollectorManager implements LabelsCollectorManager {
|
|||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkValidLabel(String key, String value) {
|
||||||
|
return isValid(key) && isValid(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValid(String param) {
|
||||||
|
if (StringUtils.isBlank(param)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int length = param.length();
|
||||||
|
if (length > maxLength) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
char ch = param.charAt(i);
|
||||||
|
if (!Character.isLetterOrDigit(ch) && !isValidChar(ch)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static char[] validChars = new char[] {'_', '-', '.'};
|
||||||
|
|
||||||
|
private static int maxLength = 128;
|
||||||
|
|
||||||
|
private static boolean isValidChar(char ch) {
|
||||||
|
for (char c : validChars) {
|
||||||
|
if (c == ch) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private ArrayList<LabelsCollector> loadLabelsCollectors() {
|
private ArrayList<LabelsCollector> loadLabelsCollectors() {
|
||||||
ServiceLoader<LabelsCollector> labelsCollectors = ServiceLoader.load(LabelsCollector.class);
|
ServiceLoader<LabelsCollector> labelsCollectors = ServiceLoader.load(LabelsCollector.class);
|
||||||
ArrayList<LabelsCollector> labelsCollectorsList = new ArrayList<>();
|
ArrayList<LabelsCollector> labelsCollectorsList = new ArrayList<>();
|
||||||
|
@ -41,22 +41,22 @@ public class ConnLabelsUtils {
|
|||||||
|
|
||||||
public static final int TAG_V2_LABEL_KEY_VALUE_SPLIT_LENGTH = 2;
|
public static final int TAG_V2_LABEL_KEY_VALUE_SPLIT_LENGTH = 2;
|
||||||
|
|
||||||
public static final int TAG_V1_LABEL_KEY_VALUE_SPLIT_LENGTH = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parse property value to map.
|
* parse property value to map.
|
||||||
*
|
*
|
||||||
* @date 2024/1/29
|
* @param properties Properties
|
||||||
* @description will get a key-value map from properties, JVM OPTIONS, ENV by order of <tt>properties > JVM OPTIONS > ENV</tt>
|
* @param propertyName which key to get
|
||||||
* which will use the next level value when the current level value isn't setup.
|
* @return (String)key-(String)value map
|
||||||
* <p>eg: if the value of "nacos.app.conn.labels"(properties' key) is "k1=v1,k2=v2"(properties' value), the result will be
|
* @date 2024/1/29
|
||||||
|
* @description will get a key-value map from properties, JVM OPTIONS, ENV by order of <tt>properties > JVM OPTIONS
|
||||||
|
* > ENV</tt> which will use the next level value when the current level value isn't setup.
|
||||||
|
* <p>eg: if the value of "nacos.app.conn.labels"(properties' key) is "k1=v1,k2=v2"(properties' value), the result
|
||||||
|
* will be
|
||||||
* a Map with value{k1=v1,k2=v2}.</p>
|
* a Map with value{k1=v1,k2=v2}.</p>
|
||||||
* @param properties Properties
|
|
||||||
* @param propertyName which key to get
|
|
||||||
* @return (String)key-(String)value map
|
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parsePropertyValue2Map(Properties properties, String propertyName) {
|
public static Map<String, String> parsePropertyValue2Map(Properties properties, String propertyName) {
|
||||||
String rawLabels = properties.getProperty(propertyName, System.getProperty(propertyName, System.getenv(propertyName)));
|
String rawLabels = properties.getProperty(propertyName,
|
||||||
|
System.getProperty(propertyName, System.getenv(propertyName)));
|
||||||
if (StringUtils.isBlank(rawLabels)) {
|
if (StringUtils.isBlank(rawLabels)) {
|
||||||
LOGGER.info("no value found for property key: {}", propertyName);
|
LOGGER.info("no value found for property key: {}", propertyName);
|
||||||
return new HashMap<>(2);
|
return new HashMap<>(2);
|
||||||
@ -65,29 +65,24 @@ public class ConnLabelsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parse raw json labels into a key-value map.
|
* parse raw json labels into a key-value map.
|
||||||
*
|
*
|
||||||
* @date 2024/1/29
|
* @param rawLabels rawLabels to parse
|
||||||
* @description
|
* @return map parsed from rawLabels
|
||||||
* @param rawLabels rawLabels to parse
|
* @date 2024/1/29
|
||||||
* @return map parsed from rawLabels
|
* @description
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parseRawLabels(String rawLabels) {
|
public static Map<String, String> parseRawLabels(String rawLabels) {
|
||||||
if (StringUtils.isBlank(rawLabels)) {
|
if (StringUtils.isBlank(rawLabels)) {
|
||||||
return new HashMap<>(2);
|
return new HashMap<>(2);
|
||||||
}
|
}
|
||||||
HashMap<String, String> resultMap = new HashMap<>(2);
|
HashMap<String, String> resultMap = new HashMap<>(2);
|
||||||
try {
|
try {
|
||||||
Arrays.stream(rawLabels.split(LABEL_SPLIT_OPERATOR))
|
Arrays.stream(rawLabels.split(LABEL_SPLIT_OPERATOR)).filter(Objects::nonNull).map(String::trim)
|
||||||
.filter(Objects::nonNull)
|
.filter(StringUtils::isNotBlank).forEach(label -> {
|
||||||
.map(String::trim)
|
|
||||||
.filter(StringUtils::isNotBlank)
|
|
||||||
.forEach(label -> {
|
|
||||||
String[] kv = label.split(LABEL_EQUALS_OPERATOR);
|
String[] kv = label.split(LABEL_EQUALS_OPERATOR);
|
||||||
if (kv.length == TAG_V2_LABEL_KEY_VALUE_SPLIT_LENGTH) {
|
if (kv.length == TAG_V2_LABEL_KEY_VALUE_SPLIT_LENGTH) {
|
||||||
resultMap.put(kv[0].trim(), kv[1].trim());
|
resultMap.put(kv[0].trim(), kv[1].trim());
|
||||||
} else if (kv.length == TAG_V1_LABEL_KEY_VALUE_SPLIT_LENGTH) {
|
|
||||||
resultMap.put(kv[0].trim(), kv[0].trim());
|
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("unknown label format: {}", label);
|
LOGGER.error("unknown label format: {}", label);
|
||||||
}
|
}
|
||||||
@ -99,24 +94,32 @@ public class ConnLabelsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* merge two map into one by using the former value when key is duplicated.
|
* merge two map into one by using the former value when key is duplicated.
|
||||||
*
|
*
|
||||||
* @date 2024/1/29
|
* @param preferredMap preferredMap
|
||||||
* @description merge two map into one preferring using the first one when key is duplicated
|
* @param backwardMap backwardMap
|
||||||
* @param preferredMap preferredMap
|
* @date 2024/1/29
|
||||||
* @param backwardMap backwardMap
|
* @description merge two map into one preferring using the first one when key is duplicated
|
||||||
*/
|
*/
|
||||||
public static <T, R> Map<T, R> mergeMapByOrder(Map<T, R> preferredMap, Map<T, R> backwardMap) {
|
public static <T, R> Map<T, R> mergeMapByOrder(Map<T, R> preferredMap, Map<T, R> backwardMap) {
|
||||||
if (preferredMap == null || preferredMap.isEmpty()) {
|
if (preferredMap == null || preferredMap.isEmpty()) {
|
||||||
return new HashMap<T, R>(8) { {
|
return new HashMap<T, R>(8) {
|
||||||
putAll(backwardMap); } };
|
{
|
||||||
|
putAll(backwardMap);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (backwardMap == null || backwardMap.isEmpty()) {
|
if (backwardMap == null || backwardMap.isEmpty()) {
|
||||||
return new HashMap<T, R>(8) { {
|
return new HashMap<T, R>(8) {
|
||||||
putAll(preferredMap); } };
|
{
|
||||||
|
putAll(preferredMap);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
HashMap<T, R> resultMap = new HashMap<T, R>(8) {{
|
HashMap<T, R> resultMap = new HashMap<T, R>(8) {
|
||||||
putAll(preferredMap); } };
|
{
|
||||||
|
putAll(preferredMap);
|
||||||
|
} };
|
||||||
backwardMap.forEach((key, value) -> {
|
backwardMap.forEach((key, value) -> {
|
||||||
if (!resultMap.containsKey(key)) {
|
if (!resultMap.containsKey(key)) {
|
||||||
resultMap.put(key, value);
|
resultMap.put(key, value);
|
||||||
@ -126,19 +129,18 @@ public class ConnLabelsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add prefix for each key in map.
|
* add prefix for each key in map.
|
||||||
*
|
*
|
||||||
* @date 2024/1/29
|
* @param map map to add prefix
|
||||||
* @description add prefix for each key in map
|
* @param prefix prefix
|
||||||
* @param map map to add prefix
|
* @date 2024/1/29
|
||||||
* @param prefix prefix
|
* @description add prefix for each key in map
|
||||||
*/
|
*/
|
||||||
public static <T> Map<String, T> addPrefixForEachKey(Map<String, T> map, String prefix) {
|
public static <T> Map<String, T> addPrefixForEachKey(Map<String, T> map, String prefix) {
|
||||||
if (map == null || map.isEmpty()) {
|
if (map == null || map.isEmpty()) {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
return map.entrySet().stream().filter(Objects::nonNull)
|
return map.entrySet().stream().filter(Objects::nonNull).filter(elem -> !elem.getKey().trim().isEmpty())
|
||||||
.filter(elem -> !elem.getKey().trim().isEmpty())
|
|
||||||
.collect(Collectors.toMap(elem -> prefix + elem.getKey(), Map.Entry::getValue));
|
.collect(Collectors.toMap(elem -> prefix + elem.getKey(), Map.Entry::getValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public class ConnLabelsUtilsTest {
|
|||||||
String rawValue = "k1 = v1, k2 = v2";
|
String rawValue = "k1 = v1, k2 = v2";
|
||||||
properties.put(property, rawValue);
|
properties.put(property, rawValue);
|
||||||
String property1 = "property2";
|
String property1 = "property2";
|
||||||
String rawValue1 = "k1, kk2";
|
String rawValue1 = "k11=v11, kk2";
|
||||||
properties.put(property1, rawValue1);
|
properties.put(property1, rawValue1);
|
||||||
|
|
||||||
Map<String, String> m = ConnLabelsUtils.parsePropertyValue2Map(properties, property);
|
Map<String, String> m = ConnLabelsUtils.parsePropertyValue2Map(properties, property);
|
||||||
@ -48,15 +48,15 @@ public class ConnLabelsUtilsTest {
|
|||||||
assertEquals("v2", m.get("k2"));
|
assertEquals("v2", m.get("k2"));
|
||||||
|
|
||||||
Map<String, String> m1 = ConnLabelsUtils.parsePropertyValue2Map(properties, property1);
|
Map<String, String> m1 = ConnLabelsUtils.parsePropertyValue2Map(properties, property1);
|
||||||
assertEquals(2, m.size());
|
assertEquals(1, m1.size());
|
||||||
assertEquals("k1", m1.get("k1"));
|
assertEquals("v11", m1.get("k11"));
|
||||||
assertEquals("kk2", m1.get("kk2"));
|
assertEquals(null, m1.get("kk2"));
|
||||||
|
|
||||||
m = ConnLabelsUtils.mergeMapByOrder(m, m1);
|
m = ConnLabelsUtils.mergeMapByOrder(m, m1);
|
||||||
assertEquals(3, m.size());
|
assertEquals(3, m.size());
|
||||||
assertEquals("v1", m.get("k1"));
|
assertEquals("v1", m.get("k1"));
|
||||||
assertEquals("v2", m.get("k2"));
|
assertEquals("v2", m.get("k2"));
|
||||||
assertEquals("kk2", m.get("kk2"));
|
assertEquals("v11", m.get("k11"));
|
||||||
|
|
||||||
m = ConnLabelsUtils.addPrefixForEachKey(m, "test_prefix");
|
m = ConnLabelsUtils.addPrefixForEachKey(m, "test_prefix");
|
||||||
assertEquals(3, m.size());
|
assertEquals(3, m.size());
|
||||||
|
Loading…
Reference in New Issue
Block a user