diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/application.properties
index 9f9a734e..baa1dba3 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/application.properties
@@ -6,10 +6,17 @@ spring.cloud.sentinel.eager=true
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
spring.cloud.sentinel.datasource.ds1.file.data-type=json
-
-#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
-#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
-#spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter
+spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
spring.cloud.sentinel.datasource.ds2.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds2.file.data-type=json
+spring.cloud.sentinel.datasource.ds2.file.rule-type=degrade
+
+spring.cloud.sentinel.datasource.ds3.file.file=classpath: authority.json
+spring.cloud.sentinel.datasource.ds3.file.rule-type=authority
+
+spring.cloud.sentinel.datasource.ds4.file.file=classpath: system.json
+spring.cloud.sentinel.datasource.ds4.file.rule-type=system
+
+spring.cloud.sentinel.datasource.ds5.file.file=classpath: param-flow.json
+spring.cloud.sentinel.datasource.ds5.file.rule-type=param-flow
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/authority.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/authority.json
new file mode 100644
index 00000000..3fb4b249
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/authority.json
@@ -0,0 +1,17 @@
+[
+ {
+ "resource": "good",
+ "limitApp": "abc",
+ "strategy": 0
+ },
+ {
+ "resource": "bad",
+ "limitApp": "bcd",
+ "strategy": 1
+ },
+ {
+ "resource": "terrible",
+ "limitApp": "aaa",
+ "strategy": 1
+ }
+]
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/param-flow.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/param-flow.json
new file mode 100644
index 00000000..72e1c2dc
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/param-flow.json
@@ -0,0 +1,16 @@
+[
+ {
+ "resource": "hotResource",
+ "count": 0,
+ "grade": 1,
+ "limitApp": "default",
+ "paramIdx": 0,
+ "paramFlowItemList": [
+ {
+ "object": "2",
+ "classType": "int",
+ "count": 1
+ }
+ ]
+ }
+]
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/system.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/system.json
new file mode 100644
index 00000000..7aa623a7
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/resources/system.json
@@ -0,0 +1,8 @@
+[
+ {
+ "highestSystemLoad": -1,
+ "qps": 100,
+ "avgRt": -1,
+ "maxThread": 10
+ }
+]
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java
new file mode 100644
index 00000000..e59a5735
--- /dev/null
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java
@@ -0,0 +1,81 @@
+package org.springframework.cloud.alibaba.sentinel.datasource;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.springframework.cloud.alibaba.sentinel.datasource.config.AbstractDataSourceProperties;
+import org.springframework.util.StringUtils;
+
+import com.alibaba.csp.sentinel.slots.block.AbstractRule;
+import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
+import com.alibaba.csp.sentinel.slots.system.SystemRule;
+
+/**
+ * Enum for {@link AbstractRule} class, using in
+ * {@link AbstractDataSourceProperties#ruleType}
+ *
+ * @author Jim
+ */
+public enum RuleType {
+
+ /**
+ * flow
+ */
+ FLOW("flow", FlowRule.class),
+ /**
+ * degrade
+ */
+ DEGRADE("degrade", DegradeRule.class),
+ /**
+ * param flow
+ */
+ PARAM_FLOW("param-flow", ParamFlowRule.class),
+ /**
+ * system
+ */
+ SYSTEM("system", SystemRule.class),
+ /**
+ * authority
+ */
+ AUTHORITY("authority", AuthorityRule.class);
+
+ /**
+ * alias for {@link AbstractRule}
+ */
+ private final String name;
+
+ /**
+ * concrete {@link AbstractRule} class
+ */
+ private final Class clazz;
+
+ RuleType(String name, Class clazz) {
+ this.name = name;
+ this.clazz = clazz;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Class getClazz() {
+ return clazz;
+ }
+
+ public static Optional getByName(String name) {
+ if (StringUtils.isEmpty(name)) {
+ return Optional.empty();
+ }
+ return Arrays.stream(RuleType.values())
+ .filter(ruleType -> name.equals(ruleType.getName())).findFirst();
+ }
+
+ public static Optional getByClass(Class clazz) {
+ return Arrays.stream(RuleType.values())
+ .filter(ruleType -> clazz == ruleType.getClazz()).findFirst();
+ }
+
+}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java
index b8843537..0f74084e 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java
@@ -1,5 +1,14 @@
package org.springframework.cloud.alibaba.sentinel.datasource.config;
+import org.springframework.cloud.alibaba.sentinel.datasource.RuleType;
+
+import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
+import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
+import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
+
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
@@ -10,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
public class AbstractDataSourceProperties {
private String dataType = "json";
+ private RuleType ruleType;
private String converterClass;
@JsonIgnore
protected String factoryBeanName;
@@ -26,6 +36,14 @@ public class AbstractDataSourceProperties {
this.dataType = dataType;
}
+ public RuleType getRuleType() {
+ return ruleType;
+ }
+
+ public void setRuleType(RuleType ruleType) {
+ this.ruleType = ruleType;
+ }
+
public String getConverterClass() {
return converterClass;
}
@@ -42,8 +60,28 @@ public class AbstractDataSourceProperties {
this.factoryBeanName = factoryBeanName;
}
- public void preCheck() {
-
+ public void preCheck(String dataSourceName) {
}
+ public void postRegister(AbstractDataSource dataSource) {
+ switch (this.getRuleType()) {
+ case FLOW:
+ FlowRuleManager.register2Property(dataSource.getProperty());
+ break;
+ case DEGRADE:
+ DegradeRuleManager.register2Property(dataSource.getProperty());
+ break;
+ case PARAM_FLOW:
+ ParamFlowRuleManager.register2Property(dataSource.getProperty());
+ break;
+ case SYSTEM:
+ SystemRuleManager.register2Property(dataSource.getProperty());
+ break;
+ case AUTHORITY:
+ AuthorityRuleManager.register2Property(dataSource.getProperty());
+ break;
+ default:
+ break;
+ }
+ }
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/FileDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/FileDataSourceProperties.java
index d6594c2b..19c24aaa 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/FileDataSourceProperties.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/FileDataSourceProperties.java
@@ -56,16 +56,17 @@ public class FileDataSourceProperties extends AbstractDataSourceProperties {
}
@Override
- public void preCheck() {
- super.preCheck();
+ public void preCheck(String dataSourceName) {
+ super.preCheck(dataSourceName);
try {
this.setFile(
ResourceUtils.getFile(StringUtils.trimAllWhitespace(this.getFile()))
.getAbsolutePath());
}
catch (IOException e) {
- throw new RuntimeException("[Sentinel Starter] " + " handle file ["
- + this.getFile() + "] error: " + e.getMessage(), e);
+ throw new RuntimeException("[Sentinel Starter] DataSource " + dataSourceName
+ + " handle file [" + this.getFile() + "] error: " + e.getMessage(),
+ e);
}
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java
index 88831102..1b49ac76 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java
@@ -1,5 +1,6 @@
package org.springframework.cloud.alibaba.sentinel.datasource.config;
+import org.springframework.cloud.alibaba.sentinel.datasource.RuleType;
import org.springframework.cloud.alibaba.sentinel.datasource.SentinelDataSourceConstants;
import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.NacosDataSourceWithAuthorizationFactoryBean;
@@ -29,7 +30,7 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties {
}
@Override
- public void preCheck() {
+ public void preCheck(String dataSourceName) {
if (!StringUtils.isEmpty(System.getProperties()
.getProperty(SentinelDataSourceConstants.NACOS_DATASOURCE_ENDPOINT))) {
this.setServerAddr(null);
@@ -126,6 +127,12 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties {
result.setDataId(System.getProperties()
.getProperty(SentinelDataSourceConstants.PROJECT_NAME) + "-" + type);
result.setGroupId("nacos-sentinel");
+ if (type.equals(RuleType.FLOW.getName())) {
+ result.setRuleType(RuleType.FLOW);
+ }
+ else {
+ result.setRuleType(RuleType.DEGRADE);
+ }
return result;
}
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
index 5f64825b..ab4d2429 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
@@ -1,28 +1,11 @@
package org.springframework.cloud.alibaba.sentinel.datasource.converter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-import com.alibaba.csp.sentinel.datasource.Converter;
-import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
-import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
@@ -36,133 +19,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @see ParamFlowRule
* @see ObjectMapper
*/
-public class JsonConverter implements Converter> {
+public class JsonConverter extends SentinelConverter {
- private static final Logger logger = LoggerFactory.getLogger(JsonConverter.class);
-
- private final ObjectMapper objectMapper;
-
- public JsonConverter(ObjectMapper objectMapper) {
- this.objectMapper = objectMapper;
- }
-
- @Override
- public List convert(String source) {
- List ruleList = new ArrayList<>();
- if (StringUtils.isEmpty(source)) {
- logger.warn(
- "Sentinel JsonConverter can not convert rules because source is empty");
- return ruleList;
- }
- try {
- List jsonArray = objectMapper.readValue(source,
- new TypeReference>() {
- });
- jsonArray.stream().forEach(obj -> {
-
- String itemJson = null;
- try {
- itemJson = objectMapper.writeValueAsString(obj);
- }
- catch (JsonProcessingException e) {
- // won't be happen
- }
-
- List rules = Arrays.asList(convertFlowRule(itemJson),
- convertDegradeRule(itemJson), convertSystemRule(itemJson),
- convertAuthorityRule(itemJson), convertParamFlowRule(itemJson));
-
- List convertRuleList = rules.stream()
- .filter(rule -> !ObjectUtils.isEmpty(rule))
- .collect(Collectors.toList());
-
- if (convertRuleList.size() == 0) {
- logger.warn(
- "Sentinel JsonConverter can not convert {} to any rules, ignore",
- itemJson);
- }
- else if (convertRuleList.size() > 1) {
- logger.warn(
- "Sentinel JsonConverter convert {} and match multi rules, ignore",
- itemJson);
- }
- else {
- ruleList.add(convertRuleList.get(0));
- }
-
- });
- if (jsonArray.size() != ruleList.size()) {
- logger.warn(
- "Sentinel JsonConverter Source list size is not equals to Target List, maybe a "
- + "part of json is invalid. Source List: " + jsonArray
- + ", Target List: " + ruleList);
- }
- }
- catch (Exception e) {
- logger.error("Sentinel JsonConverter convert error: " + e.getMessage());
- throw new RuntimeException(
- "Sentinel JsonConverter convert error: " + e.getMessage(), e);
- }
- return ruleList;
- }
-
- private FlowRule convertFlowRule(String json) {
- try {
- FlowRule rule = objectMapper.readValue(json, FlowRule.class);
- if (FlowRuleUtil.isValidRule(rule)) {
- return rule;
- }
- }
- catch (Exception e) {
- // ignore
- }
- return null;
- }
-
- private DegradeRule convertDegradeRule(String json) {
- try {
- DegradeRule rule = objectMapper.readValue(json, DegradeRule.class);
- if (DegradeRuleManager.isValidRule(rule)) {
- return rule;
- }
- }
- catch (Exception e) {
- // ignore
- }
- return null;
- }
-
- private SystemRule convertSystemRule(String json) {
- SystemRule rule = null;
- try {
- rule = objectMapper.readValue(json, SystemRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
- }
-
- private AuthorityRule convertAuthorityRule(String json) {
- AuthorityRule rule = null;
- try {
- rule = objectMapper.readValue(json, AuthorityRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
- }
-
- private ParamFlowRule convertParamFlowRule(String json) {
- ParamFlowRule rule = null;
- try {
- rule = objectMapper.readValue(json, ParamFlowRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
+ public JsonConverter(ObjectMapper objectMapper, Class ruleClass) {
+ super(objectMapper, ruleClass);
}
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java
new file mode 100644
index 00000000..f499a16c
--- /dev/null
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java
@@ -0,0 +1,115 @@
+package org.springframework.cloud.alibaba.sentinel.datasource.converter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.alibaba.sentinel.datasource.RuleType;
+import org.springframework.util.StringUtils;
+
+import com.alibaba.csp.sentinel.datasource.Converter;
+import com.alibaba.csp.sentinel.slots.block.AbstractRule;
+import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
+import com.alibaba.csp.sentinel.slots.system.SystemRule;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Convert sentinel rules for json or xml array Using strict mode to parse json or xml
+ *
+ * @author Jim
+ * @see FlowRule
+ * @see DegradeRule
+ * @see SystemRule
+ * @see AuthorityRule
+ * @see ParamFlowRule
+ * @see ObjectMapper
+ */
+public abstract class SentinelConverter
+ implements Converter> {
+
+ private static final Logger logger = LoggerFactory.getLogger(SentinelConverter.class);
+
+ private final ObjectMapper objectMapper;
+
+ private final Class ruleClass;
+
+ public SentinelConverter(ObjectMapper objectMapper, Class ruleClass) {
+ this.objectMapper = objectMapper;
+ this.ruleClass = ruleClass;
+ }
+
+ @Override
+ public List convert(String source) {
+ List ruleList = new ArrayList<>();
+ if (StringUtils.isEmpty(source)) {
+ logger.warn("converter can not convert rules because source is empty");
+ return ruleList;
+ }
+ try {
+ List sourceArray = objectMapper.readValue(source,
+ new TypeReference>() {
+ });
+ sourceArray.stream().forEach(obj -> {
+
+ String item = null;
+ try {
+ item = objectMapper.writeValueAsString(obj);
+ }
+ catch (JsonProcessingException e) {
+ // won't be happen
+ }
+
+ Optional.ofNullable(convertRule(item))
+ .ifPresent(convertRule -> ruleList.add(convertRule));
+ });
+
+ if (ruleList.size() != sourceArray.size()) {
+ throw new IllegalArgumentException("convert " + ruleList.size()
+ + " rules but there are " + sourceArray.size()
+ + " rules from datasource. RuleClass: "
+ + ruleClass.getSimpleName());
+ }
+ }
+ catch (Exception e) {
+ throw new RuntimeException("convert error: " + e.getMessage(), e);
+ }
+ return ruleList;
+ }
+
+ private AbstractRule convertRule(String ruleStr) {
+ try {
+ final AbstractRule rule = objectMapper.readValue(ruleStr, ruleClass);
+ RuleType ruleType = RuleType.getByClass(ruleClass).get();
+ switch (ruleType) {
+ case FLOW:
+ if (!FlowRuleUtil.isValidRule((FlowRule) rule)) {
+ return null;
+ }
+ break;
+ case DEGRADE:
+ if (!DegradeRuleManager.isValidRule((DegradeRule) rule)) {
+ return null;
+ }
+ default:
+ break;
+ }
+ return rule;
+ }
+ catch (Exception e) {
+ // ignore
+ }
+ return null;
+ }
+
+}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
index 77f3b593..6c8485d4 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
@@ -1,28 +1,12 @@
package org.springframework.cloud.alibaba.sentinel.datasource.converter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-import com.alibaba.csp.sentinel.datasource.Converter;
-import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
-import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
/**
@@ -34,134 +18,12 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper;
* @see SystemRule
* @see AuthorityRule
* @see ParamFlowRule
+ * @see ObjectMapper
*/
-public class XmlConverter implements Converter> {
+public class XmlConverter extends SentinelConverter {
- private static final Logger logger = LoggerFactory.getLogger(XmlConverter.class);
-
- private final XmlMapper xmlMapper;
-
- public XmlConverter(XmlMapper xmlMapper) {
- this.xmlMapper = xmlMapper;
- }
-
- @Override
- public List convert(String source) {
- List ruleList = new ArrayList<>();
- if (StringUtils.isEmpty(source)) {
- logger.warn(
- "Sentinel XmlConverter can not convert rules because source is empty");
- return ruleList;
- }
- try {
- List xmlArray = xmlMapper.readValue(source,
- new TypeReference>() {
- });
- xmlArray.stream().forEach(obj -> {
-
- String itemXml = null;
- try {
- itemXml = xmlMapper.writeValueAsString(obj);
- }
- catch (JsonProcessingException e) {
- // won't be happen
- }
-
- List rules = Arrays.asList(convertFlowRule(itemXml),
- convertDegradeRule(itemXml), convertSystemRule(itemXml),
- convertAuthorityRule(itemXml), convertParamFlowRule(itemXml));
-
- List convertRuleList = rules.stream()
- .filter(rule -> !ObjectUtils.isEmpty(rule))
- .collect(Collectors.toList());
-
- if (convertRuleList.size() == 0) {
- logger.warn(
- "Sentinel XmlConverter can not convert {} to any rules, ignore",
- itemXml);
- }
- else if (convertRuleList.size() > 1) {
- logger.warn(
- "Sentinel XmlConverter convert {} and match multi rules, ignore",
- itemXml);
- }
- else {
- ruleList.add(convertRuleList.get(0));
- }
-
- });
- if (xmlArray.size() != ruleList.size()) {
- logger.warn(
- "Sentinel XmlConverter Source list size is not equals to Target List, maybe a "
- + "part of xml is invalid. Source List: " + xmlArray
- + ", Target List: " + ruleList);
- }
- }
- catch (Exception e) {
- logger.error("Sentinel XmlConverter convert error: " + e.getMessage());
- throw new RuntimeException(
- "Sentinel XmlConverter convert error: " + e.getMessage(), e);
- }
- return ruleList;
- }
-
- private FlowRule convertFlowRule(String xml) {
- try {
- FlowRule rule = xmlMapper.readValue(xml, FlowRule.class);
- if (FlowRuleUtil.isValidRule(rule)) {
- return rule;
- }
- }
- catch (Exception e) {
- // ignore
- }
- return null;
- }
-
- private DegradeRule convertDegradeRule(String xml) {
- try {
- DegradeRule rule = xmlMapper.readValue(xml, DegradeRule.class);
- if (DegradeRuleManager.isValidRule(rule)) {
- return rule;
- }
- }
- catch (Exception e) {
- // ignore
- }
- return null;
- }
-
- private SystemRule convertSystemRule(String xml) {
- SystemRule rule = null;
- try {
- rule = xmlMapper.readValue(xml, SystemRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
- }
-
- private AuthorityRule convertAuthorityRule(String xml) {
- AuthorityRule rule = null;
- try {
- rule = xmlMapper.readValue(xml, AuthorityRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
- }
-
- private ParamFlowRule convertParamFlowRule(String json) {
- ParamFlowRule rule = null;
- try {
- rule = xmlMapper.readValue(json, ParamFlowRule.class);
- }
- catch (Exception e) {
- // ignore
- }
- return rule;
+ public XmlConverter(XmlMapper xmlMapper, Class ruleClass) {
+ super(xmlMapper, ruleClass);
}
}
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
index 53347f7b..4349cf70 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
@@ -41,6 +41,11 @@ import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.init.InitExecutor;
import com.alibaba.csp.sentinel.log.LogBase;
+import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
+import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import com.alibaba.csp.sentinel.util.AppNameUtil;
@@ -154,25 +159,67 @@ public class SentinelAutoConfiguration {
return new SentinelDataSourceHandler();
}
- @Bean("sentinel-json-converter")
- public JsonConverter jsonConverter() {
- return new JsonConverter(objectMapper());
- }
+ protected static class SentinelConverterConfiguration {
+
+ private ObjectMapper objectMapper = new ObjectMapper();
+
+ @Bean("sentinel-json-flow-converter")
+ public JsonConverter jsonFlowConverter() {
+ return new JsonConverter(objectMapper, FlowRule.class);
+ }
+
+ @Bean("sentinel-json-degrade-converter")
+ public JsonConverter jsonDegradeConverter() {
+ return new JsonConverter(objectMapper, DegradeRule.class);
+ }
+
+ @Bean("sentinel-json-system-converter")
+ public JsonConverter jsonSystemConverter() {
+ return new JsonConverter(objectMapper, SystemRule.class);
+ }
+
+ @Bean("sentinel-json-authority-converter")
+ public JsonConverter jsonAuthorityConverter() {
+ return new JsonConverter(objectMapper, AuthorityRule.class);
+ }
+
+ @Bean("sentinel-json-param-flow-converter")
+ public JsonConverter jsonParamFlowConverter() {
+ return new JsonConverter(objectMapper, ParamFlowRule.class);
+ }
- private ObjectMapper objectMapper() {
- return new ObjectMapper();
}
@ConditionalOnClass(XmlMapper.class)
protected static class SentinelXmlConfiguration {
- @Bean("sentinel-xml-converter")
- public XmlConverter xmlConverter() {
- return new XmlConverter(xmlMapper());
+
+ private XmlMapper xmlMapper = new XmlMapper();
+
+ @Bean("sentinel-xml-flow-converter")
+ public XmlConverter xmlFlowConverter() {
+ return new XmlConverter(xmlMapper, FlowRule.class);
}
- private XmlMapper xmlMapper() {
- return new XmlMapper();
+ @Bean("sentinel-xml-degrade-converter")
+ public XmlConverter xmlDegradeConverter() {
+ return new XmlConverter(xmlMapper, DegradeRule.class);
}
+
+ @Bean("sentinel-xml-system-converter")
+ public XmlConverter xmlSystemConverter() {
+ return new XmlConverter(xmlMapper, SystemRule.class);
+ }
+
+ @Bean("sentinel-xml-authority-converter")
+ public XmlConverter xmlAuthorityConverter() {
+ return new XmlConverter(xmlMapper, AuthorityRule.class);
+ }
+
+ @Bean("sentinel-xml-param-flow-converter")
+ public XmlConverter xmlParamFlowConverter() {
+ return new XmlConverter(xmlMapper, ParamFlowRule.class);
+ }
+
}
}
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java
index 6a5feca4..f9776d27 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java
@@ -9,7 +9,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
-import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,17 +31,9 @@ import org.springframework.util.StringUtils;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
-import com.alibaba.csp.sentinel.property.SentinelProperty;
-import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
-import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
-import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
-import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
-import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
-import com.alibaba.csp.sentinel.slots.system.SystemRule;
-import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
/**
* Sentinel {@link ReadableDataSource} Handler Handle the configurations of
@@ -60,9 +51,6 @@ public class SentinelDataSourceHandler {
private List dataTypeList = Arrays.asList("json", "xml");
- private List rulesList = Arrays.asList(FlowRule.class, DegradeRule.class,
- SystemRule.class, AuthorityRule.class, ParamFlowRule.class);
-
private List dataSourceBeanNameList = Collections
.synchronizedList(new ArrayList<>());
@@ -102,55 +90,26 @@ public class SentinelDataSourceHandler {
sentinelProperties.getDatasource()
.forEach((dataSourceName, dataSourceProperties) -> {
- List validFields = dataSourceProperties.getValidField();
- if (validFields.size() != 1) {
- logger.error("[Sentinel Starter] DataSource " + dataSourceName
- + " multi datasource active and won't loaded: "
- + dataSourceProperties.getValidField());
- return;
+ try {
+ List validFields = dataSourceProperties.getValidField();
+ if (validFields.size() != 1) {
+ logger.error("[Sentinel Starter] DataSource " + dataSourceName
+ + " multi datasource active and won't loaded: "
+ + dataSourceProperties.getValidField());
+ return;
+ }
+ AbstractDataSourceProperties abstractDataSourceProperties = dataSourceProperties
+ .getValidDataSourceProperties();
+ abstractDataSourceProperties.preCheck(dataSourceName);
+ registerBean(beanFactory, abstractDataSourceProperties,
+ dataSourceName + "-sentinel-" + validFields.get(0)
+ + "-datasource");
+ }
+ catch (Exception e) {
+ logger.error("[Sentinel Starter] DataSource " + dataSourceName
+ + " build error: " + e.getMessage(), e);
}
-
- AbstractDataSourceProperties abstractDataSourceProperties = dataSourceProperties
- .getValidDataSourceProperties();
- abstractDataSourceProperties.preCheck();
- registerBean(beanFactory, abstractDataSourceProperties, dataSourceName
- + "-sentinel-" + validFields.get(0) + "-datasource");
});
-
- dataSourceBeanNameList.forEach(beanName -> {
- ReadableDataSource dataSource = beanFactory.getBean(beanName,
- ReadableDataSource.class);
- Object ruleConfig;
- try {
- logger.info("[Sentinel Starter] DataSource " + beanName
- + " start to loadConfig");
- ruleConfig = dataSource.loadConfig();
- }
- catch (Exception e) {
- logger.error("[Sentinel Starter] DataSource " + beanName
- + " loadConfig error: " + e.getMessage(), e);
- return;
- }
- SentinelProperty sentinelProperty = dataSource.getProperty();
- Class ruleType = getAndCheckRuleType(ruleConfig, beanName);
- if (ruleType != null) {
- if (ruleType == FlowRule.class) {
- FlowRuleManager.register2Property(sentinelProperty);
- }
- else if (ruleType == DegradeRule.class) {
- DegradeRuleManager.register2Property(sentinelProperty);
- }
- else if (ruleType == SystemRule.class) {
- SystemRuleManager.register2Property(sentinelProperty);
- }
- else if (ruleType == AuthorityRule.class) {
- AuthorityRuleManager.register2Property(sentinelProperty);
- }
- else {
- ParamFlowRuleManager.register2Property(sentinelProperty);
- }
- }
- });
}
private void registerBean(DefaultListableBeanFactory beanFactory,
@@ -236,9 +195,11 @@ public class SentinelDataSourceHandler {
}
// converter type now support xml or json.
// The bean name of these converters wrapped by
- // 'sentinel-{converterType}-converter'
+ // 'sentinel-{converterType}-{ruleType}-converter'
builder.addPropertyReference("converter",
- "sentinel-" + propertyValue.toString() + "-converter");
+ "sentinel-" + propertyValue.toString() + "-"
+ + dataSourceProperties.getRuleType().getName()
+ + "-converter");
}
}
else if (CONVERTERCLASS_FIELD.equals(propertyName)) {
@@ -256,6 +217,13 @@ public class SentinelDataSourceHandler {
// init in Spring
AbstractDataSource newDataSource = (AbstractDataSource) beanFactory
.getBean(dataSourceName);
+
+ logAndCheckRuleType(newDataSource, dataSourceName,
+ dataSourceProperties.getRuleType().getClazz());
+
+ // register property in RuleManager
+ dataSourceProperties.postRegister(newDataSource);
+
// commercialization
if (!StringUtils.isEmpty(System.getProperties()
.getProperty(SentinelDataSourceConstants.NACOS_DATASOURCE_ENDPOINT))) {
@@ -269,55 +237,50 @@ public class SentinelDataSourceHandler {
dataSourceBeanNameList.add(dataSourceName);
}
- private Class getAndCheckRuleType(Object ruleConfig, String dataSourceName) {
- if (rulesList.contains(ruleConfig.getClass())) {
- logger.info("[Sentinel Starter] DataSource {} load {} {}", dataSourceName, 1,
- ruleConfig.getClass().getSimpleName());
- return ruleConfig.getClass();
+ private void logAndCheckRuleType(AbstractDataSource dataSource, String dataSourceName,
+ Class extends AbstractRule> ruleClass) {
+ Object ruleConfig;
+ try {
+ ruleConfig = dataSource.loadConfig();
}
- else if (ruleConfig instanceof List) {
+ catch (Exception e) {
+ logger.error("[Sentinel Starter] DataSource " + dataSourceName
+ + " loadConfig error: " + e.getMessage(), e);
+ return;
+ }
+ if (ruleConfig instanceof List) {
List convertedRuleList = (List) ruleConfig;
if (CollectionUtils.isEmpty(convertedRuleList)) {
logger.warn("[Sentinel Starter] DataSource {} rule list is empty.",
dataSourceName);
- return null;
+ return;
}
if (convertedRuleList.stream()
- .allMatch(rule -> rulesList.contains(rule.getClass()))) {
- if (rulesList.contains(convertedRuleList.get(0).getClass())
- && convertedRuleList.stream()
- .filter(rule -> rule.getClass() == convertedRuleList
- .get(0).getClass())
- .toArray().length == convertedRuleList.size()) {
- logger.info("[Sentinel Starter] DataSource {} load {} {}",
- dataSourceName, convertedRuleList.size(),
- convertedRuleList.get(0).getClass().getSimpleName());
- return convertedRuleList.get(0).getClass();
- }
- else {
- logger.warn(
- "[Sentinel Starter] DataSource {} all rules are not same rule type and it will not be used. "
- + "Rule List: {}",
- dataSourceName, convertedRuleList.toString());
- }
+ .noneMatch(rule -> rule.getClass() == ruleClass)) {
+ logger.error("[Sentinel Starter] DataSource {} none rules are {} type.",
+ dataSourceName, ruleClass.getSimpleName());
+ throw new IllegalArgumentException("[Sentinel Starter] DataSource "
+ + dataSourceName + " none rules are " + ruleClass.getSimpleName()
+ + " type.");
+ }
+ else if (!convertedRuleList.stream()
+ .allMatch(rule -> rule.getClass() == ruleClass)) {
+ logger.warn("[Sentinel Starter] DataSource {} all rules are not {} type.",
+ dataSourceName, ruleClass.getSimpleName());
}
else {
- List classList = (List) convertedRuleList.stream()
- .map(Object::getClass).collect(Collectors.toList());
- logger.error("[Sentinel Starter] DataSource " + dataSourceName
- + " rule class is invalid. Class List: " + classList);
- throw new RuntimeException(
- "[Sentinel Starter] DataSource " + dataSourceName
- + " rule class is invalid. Class List: " + classList);
+ logger.info("[Sentinel Starter] DataSource {} load {} {}", dataSourceName,
+ convertedRuleList.size(), ruleClass.getSimpleName());
}
}
else {
logger.error("[Sentinel Starter] DataSource " + dataSourceName
- + " rule class is invalid. Class: " + ruleConfig.getClass());
- throw new RuntimeException("[Sentinel Starter] DataSource " + dataSourceName
- + " rule class is invalid. Class: " + ruleConfig.getClass());
+ + " rule class is not List<" + ruleClass.getSimpleName()
+ + ">. Class: " + ruleConfig.getClass());
+ throw new IllegalArgumentException("[Sentinel Starter] DataSource "
+ + dataSourceName + " rule class is not List<"
+ + ruleClass.getSimpleName() + ">. Class: " + ruleConfig.getClass());
}
- return null;
}
public List getDataSourceBeanNameList() {