argList = new ArrayList<>();
+ for (Class argClazz : args) {
+ argList.add(argClazz.getSimpleName());
+ }
+ String argsStr = Arrays.toString(argList.toArray());
+ Method foundMethod = ClassUtils.getStaticMethod(blockClass, blockMethod, args);
+ if (foundMethod == null) {
+ logger.error(
+ "{} static method can not be found in bean[{}]. The right method signature is {}#{}{}, please check your class name, method name and arguments",
+ type, beanName, blockClass.getName(), blockMethod, argsStr);
+ throw new IllegalArgumentException(type
+ + " static method can not be found in bean[" + beanName
+ + "]. The right method signature is " + blockClass.getName() + "#"
+ + blockMethod + argsStr
+ + ", please check your class name, method name and arguments");
+ }
+
+ if (!ClientHttpResponse.class.isAssignableFrom(foundMethod.getReturnType())) {
+ logger.error(
+ "{} method return value in bean[{}] is not ClientHttpResponse: {}#{}{}",
+ type, beanName, blockClass.getName(), blockMethod, argsStr);
+ throw new IllegalArgumentException(type + " method return value in bean["
+ + beanName + "] is not ClientHttpResponse: " + blockClass.getName()
+ + "#" + blockMethod + argsStr);
+ }
+ if (type.equals(SentinelConstants.BLOCK_TYPE)) {
+ BlockClassRegistry.updateBlockHandlerFor(blockClass, blockMethod,
+ foundMethod);
+ }
+ else {
+ BlockClassRegistry.updateFallbackFor(blockClass, blockMethod, foundMethod);
+ }
+ }
+
private boolean checkSentinelProtect(RootBeanDefinition beanDefinition,
Class> beanType) {
return beanType == RestTemplate.class
- && beanDefinition.getSource() instanceof StandardMethodMetadata
+ && (checkStandardMethodMetadata(beanDefinition)
+ || checkMethodMetadataReadingVisitor(beanDefinition));
+ }
+
+ private boolean checkStandardMethodMetadata(RootBeanDefinition beanDefinition) {
+ return beanDefinition.getSource() instanceof StandardMethodMetadata
&& ((StandardMethodMetadata) beanDefinition.getSource())
.isAnnotated(SentinelRestTemplate.class.getName());
}
+ private boolean checkMethodMetadataReadingVisitor(RootBeanDefinition beanDefinition) {
+ return beanDefinition.getSource() instanceof MethodMetadataReadingVisitor
+ && ((MethodMetadataReadingVisitor) beanDefinition.getSource())
+ .isAnnotated(SentinelRestTemplate.class.getName());
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(Object o, String s)
+ throws BeansException {
+ return o;
+ }
+
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
@@ -84,7 +195,7 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
SentinelProtectInterceptor sentinelProtectInterceptor = applicationContext
.getBean(interceptorBeanName.toString(),
SentinelProtectInterceptor.class);
- restTemplate.getInterceptors().add(sentinelProtectInterceptor);
+ restTemplate.getInterceptors().add(0, sentinelProtectInterceptor);
}
return bean;
}
@@ -103,10 +214,4 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
interceptorBeanDefinition);
}
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
- return bean;
- }
-
}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelCircuitBreakerConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelCircuitBreakerConfiguration.java
new file mode 100644
index 00000000..a13acf8a
--- /dev/null
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelCircuitBreakerConfiguration.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * 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 org.springframework.cloud.alibaba.sentinel.custom;
+
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lengleng
+ *
+ * support @EnableCircuitBreaker ,Do nothing
+ */
+@Configuration
+public class SentinelCircuitBreakerConfiguration {
+}
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 8489c7d8..447629df 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
@@ -17,47 +17,29 @@
package org.springframework.cloud.alibaba.sentinel.custom;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
-import org.springframework.cloud.alibaba.sentinel.SentinelConstants;
import org.springframework.cloud.alibaba.sentinel.SentinelProperties;
-import org.springframework.cloud.alibaba.sentinel.datasource.SentinelDataSourceConstants;
import org.springframework.cloud.alibaba.sentinel.datasource.config.AbstractDataSourceProperties;
import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration;
-import org.springframework.cloud.alibaba.sentinel.datasource.config.NacosDataSourceProperties;
import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter;
import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter;
-import org.springframework.context.event.EventListener;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
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.AbstractRule;
-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.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
@@ -68,113 +50,53 @@ import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
* @see JsonConverter
* @see XmlConverter
*/
-public class SentinelDataSourceHandler {
+public class SentinelDataSourceHandler implements SmartInitializingSingleton {
private static final Logger logger = LoggerFactory
.getLogger(SentinelDataSourceHandler.class);
private List dataTypeList = Arrays.asList("json", "xml");
- private List> rulesList = Arrays.asList(FlowRule.class,
- DegradeRule.class, SystemRule.class, AuthorityRule.class,
- ParamFlowRule.class);
+ private final String DATA_TYPE_FIELD = "dataType";
+ private final String CUSTOM_DATA_TYPE = "custom";
+ private final String CONVERTER_CLASS_FIELD = "converterClass";
- private List dataSourceBeanNameList = Collections
- .synchronizedList(new ArrayList());
+ private final DefaultListableBeanFactory beanFactory;
- private final String DATATYPE_FIELD = "dataType";
- private final String CUSTOM_DATATYPE = "custom";
- private final String CONVERTERCLASS_FIELD = "converterClass";
+ public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
@Autowired
private SentinelProperties sentinelProperties;
- @EventListener(classes = ApplicationReadyEvent.class)
- public void buildDataSource(ApplicationReadyEvent event) throws Exception {
-
- DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) event
- .getApplicationContext().getAutowireCapableBeanFactory();
-
- // commercialization
- if (!StringUtils.isEmpty(System.getProperties()
- .getProperty(SentinelDataSourceConstants.NACOS_DATASOURCE_ENDPOINT))) {
- Map newDataSourceMap = new TreeMap<>(
- String.CASE_INSENSITIVE_ORDER);
- for (Map.Entry entry : sentinelProperties
- .getDatasource().entrySet()) {
- if (entry.getValue().getValidDataSourceProperties()
- .getClass() != NacosDataSourceProperties.class) {
- newDataSourceMap.put(entry.getKey(), entry.getValue());
- }
- }
- newDataSourceMap.put(SentinelConstants.FLOW_DATASOURCE_NAME,
- new DataSourcePropertiesConfiguration(
- NacosDataSourceProperties.buildFlowByEDAS()));
- newDataSourceMap.put(SentinelConstants.DEGRADE_DATASOURCE_NAME,
- new DataSourcePropertiesConfiguration(
- NacosDataSourceProperties.buildDegradeByEDAS()));
- sentinelProperties.setDatasource(newDataSourceMap);
- }
-
- for (Map.Entry entry : sentinelProperties
- .getDatasource().entrySet()) {
- String dataSourceName = entry.getKey();
- DataSourcePropertiesConfiguration dataSourceProperties = entry.getValue();
-
- 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();
- registerBean(beanFactory, abstractDataSourceProperties,
- dataSourceName + "-sentinel-" + validFields.get(0) + "-datasource");
-
- }
-
- for (String beanName : dataSourceBeanNameList) {
- ReadableDataSource dataSource = beanFactory.getBean(beanName,
- ReadableDataSource.class);
- Object ruleConfig;
+ @Override
+ public void afterSingletonsInstantiated() {
+ for (String dataSourceName : sentinelProperties.getDatasource().keySet()) {
+ DataSourcePropertiesConfiguration dataSourceProperties = sentinelProperties
+ .getDatasource().get(dataSourceName);
try {
- logger.info("[Sentinel Starter] DataSource " + beanName
- + " start to loadConfig");
- ruleConfig = dataSource.loadConfig();
+ 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(abstractDataSourceProperties, dataSourceName + "-sentinel-"
+ + validFields.get(0) + "-datasource");
}
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);
- }
+ logger.error("[Sentinel Starter] DataSource " + dataSourceName
+ + " build error: " + e.getMessage(), e);
}
}
}
- private void registerBean(DefaultListableBeanFactory beanFactory,
- final AbstractDataSourceProperties dataSourceProperties,
+ private void registerBean(final AbstractDataSourceProperties dataSourceProperties,
String dataSourceName) {
Map propertyMap = new HashMap<>();
@@ -194,8 +116,9 @@ public class SentinelDataSourceHandler {
e);
}
}
- propertyMap.put(CONVERTERCLASS_FIELD, dataSourceProperties.getConverterClass());
- propertyMap.put(DATATYPE_FIELD, dataSourceProperties.getDataType());
+
+ propertyMap.put(CONVERTER_CLASS_FIELD, dataSourceProperties.getConverterClass());
+ propertyMap.put(DATA_TYPE_FIELD, dataSourceProperties.getDataType());
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(dataSourceProperties.getFactoryBeanName());
@@ -205,166 +128,136 @@ public class SentinelDataSourceHandler {
Object propertyValue = entry.getValue();
Field field = ReflectionUtils.findField(dataSourceProperties.getClass(),
propertyName);
- if (field != null) {
- if (DATATYPE_FIELD.equals(propertyName)) {
- String dataType = StringUtils
- .trimAllWhitespace(propertyValue.toString());
- if (CUSTOM_DATATYPE.equals(dataType)) {
- try {
- if (StringUtils
- .isEmpty(dataSourceProperties.getConverterClass())) {
- throw new RuntimeException(
- "[Sentinel Starter] DataSource " + dataSourceName
- + "dataType is custom, please set converter-class "
- + "property");
- }
- // construct custom Converter with 'converterClass'
- // configuration and register
- String customConvertBeanName = "sentinel-"
- + dataSourceProperties.getConverterClass();
- if (!beanFactory.containsBean(customConvertBeanName)) {
- beanFactory.registerBeanDefinition(customConvertBeanName,
- BeanDefinitionBuilder
- .genericBeanDefinition(
- Class.forName(dataSourceProperties
- .getConverterClass()))
- .getBeanDefinition());
- }
- builder.addPropertyReference("converter",
- customConvertBeanName);
- }
- catch (ClassNotFoundException e) {
- logger.error("[Sentinel Starter] DataSource " + dataSourceName
- + " handle "
- + dataSourceProperties.getClass().getSimpleName()
- + " error, class name: "
- + dataSourceProperties.getConverterClass());
- throw new RuntimeException(
- "[Sentinel Starter] DataSource " + dataSourceName
- + " handle "
- + dataSourceProperties.getClass()
- .getSimpleName()
- + " error, class name: "
- + dataSourceProperties.getConverterClass(),
- e);
- }
- }
- else {
- if (!dataTypeList.contains(StringUtils
- .trimAllWhitespace(propertyValue.toString()))) {
+ if (null == field) {
+ continue;
+ }
+ if (DATA_TYPE_FIELD.equals(propertyName)) {
+ String dataType = StringUtils.trimAllWhitespace(propertyValue.toString());
+ if (CUSTOM_DATA_TYPE.equals(dataType)) {
+ try {
+ if (StringUtils
+ .isEmpty(dataSourceProperties.getConverterClass())) {
throw new RuntimeException("[Sentinel Starter] DataSource "
- + dataSourceName + " dataType: " + propertyValue
- + " is not support now. please using these types: "
- + dataTypeList.toString());
+ + dataSourceName
+ + "dataType is custom, please set converter-class "
+ + "property");
}
- // converter type now support xml or json.
- // The bean name of these converters wrapped by
- // 'sentinel-{converterType}-converter'
- builder.addPropertyReference("converter",
- "sentinel-" + propertyValue.toString() + "-converter");
+ // construct custom Converter with 'converterClass'
+ // configuration and register
+ String customConvertBeanName = "sentinel-"
+ + dataSourceProperties.getConverterClass();
+ if (!this.beanFactory.containsBean(customConvertBeanName)) {
+ this.beanFactory.registerBeanDefinition(customConvertBeanName,
+ BeanDefinitionBuilder
+ .genericBeanDefinition(
+ Class.forName(dataSourceProperties
+ .getConverterClass()))
+ .getBeanDefinition());
+ }
+ builder.addPropertyReference("converter", customConvertBeanName);
+ }
+ catch (ClassNotFoundException e) {
+ logger.error("[Sentinel Starter] DataSource " + dataSourceName
+ + " handle "
+ + dataSourceProperties.getClass().getSimpleName()
+ + " error, class name: "
+ + dataSourceProperties.getConverterClass());
+ throw new RuntimeException("[Sentinel Starter] DataSource "
+ + dataSourceName + " handle "
+ + dataSourceProperties.getClass().getSimpleName()
+ + " error, class name: "
+ + dataSourceProperties.getConverterClass(), e);
}
- }
- else if (CONVERTERCLASS_FIELD.equals(propertyName)) {
- continue;
}
else {
- // wired properties
- if (propertyValue != null) {
- builder.addPropertyValue(propertyName, propertyValue);
+ if (!dataTypeList.contains(
+ StringUtils.trimAllWhitespace(propertyValue.toString()))) {
+ throw new RuntimeException("[Sentinel Starter] DataSource "
+ + dataSourceName + " dataType: " + propertyValue
+ + " is not support now. please using these types: "
+ + dataTypeList.toString());
}
+ // converter type now support xml or json.
+ // The bean name of these converters wrapped by
+ // 'sentinel-{converterType}-{ruleType}-converter'
+ builder.addPropertyReference("converter",
+ "sentinel-" + propertyValue.toString() + "-"
+ + dataSourceProperties.getRuleType().getName()
+ + "-converter");
+ }
+ }
+ else if (CONVERTER_CLASS_FIELD.equals(propertyName)) {
+ continue;
+ }
+ else {
+ // wired properties
+ if (propertyValue != null) {
+ builder.addPropertyValue(propertyName, propertyValue);
}
}
}
- beanFactory.registerBeanDefinition(dataSourceName, builder.getBeanDefinition());
+ this.beanFactory.registerBeanDefinition(dataSourceName,
+ builder.getBeanDefinition());
// init in Spring
- AbstractDataSource newDataSource = (AbstractDataSource) beanFactory
+ AbstractDataSource newDataSource = (AbstractDataSource) this.beanFactory
.getBean(dataSourceName);
- // commercialization
- if (!StringUtils.isEmpty(System.getProperties()
- .getProperty(SentinelDataSourceConstants.NACOS_DATASOURCE_ENDPOINT))) {
- if (dataSourceName.contains(SentinelConstants.FLOW_DATASOURCE_NAME)) {
- FlowRuleManager.register2Property(newDataSource.getProperty());
- }
- else if (dataSourceName.contains(SentinelConstants.DEGRADE_DATASOURCE_NAME)) {
- DegradeRuleManager.register2Property(newDataSource.getProperty());
- }
- }
- dataSourceBeanNameList.add(dataSourceName);
+
+ logAndCheckRuleType(newDataSource, dataSourceName,
+ dataSourceProperties.getRuleType().getClazz());
+
+ // register property in RuleManager
+ dataSourceProperties.postRegister(newDataSource);
}
- 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 (checkRuleTypeValid(convertedRuleList)) {
- if (checkAllRuleTypeSame(convertedRuleList)) {
- 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());
+ int matchCount = 0;
+ for (Object rule : convertedRuleList) {
+ if (rule.getClass() == ruleClass) {
+ matchCount++;
}
}
+ if (matchCount == 0) {
+ 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 (matchCount != convertedRuleList.size()) {
+ logger.warn("[Sentinel Starter] DataSource {} all rules are not {} type.",
+ dataSourceName, ruleClass.getSimpleName());
+ }
else {
- List classList = new ArrayList<>();
- for (Object rule : convertedRuleList) {
- classList.add(rule.getClass());
- }
- 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;
- }
-
- private boolean checkRuleTypeValid(List convertedRuleList) {
- int matchCount = 0;
- for (Object rule : convertedRuleList) {
- if (rulesList.contains(rule.getClass())) {
- matchCount++;
- }
- }
- return matchCount == convertedRuleList.size();
- }
-
- private boolean checkAllRuleTypeSame(List convertedRuleList) {
- int matchCount = 0;
- for (Object rule : convertedRuleList) {
- if (rulesList.contains(rule.getClass())
- && rule.getClass() == convertedRuleList.get(0).getClass()) {
- matchCount++;
- }
- }
- return matchCount == convertedRuleList.size();
- }
-
- public List getDataSourceBeanNameList() {
- return dataSourceBeanNameList;
}
}
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
index a1ab9e22..49bd003f 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
@@ -17,9 +17,9 @@
package org.springframework.cloud.alibaba.sentinel.custom;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
-import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,7 +29,6 @@ import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.util.ClassUtils;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
@@ -37,19 +36,18 @@ import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
-import com.alibaba.csp.sentinel.util.StringUtil;
/**
* Interceptor using by SentinelRestTemplate
*
- * @author fangjian
+ * @author Jim
*/
public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor {
private static final Logger logger = LoggerFactory
.getLogger(SentinelProtectInterceptor.class);
- private SentinelRestTemplate sentinelRestTemplate;
+ private final SentinelRestTemplate sentinelRestTemplate;
public SentinelProtectInterceptor(SentinelRestTemplate sentinelRestTemplate) {
this.sentinelRestTemplate = sentinelRestTemplate;
@@ -82,18 +80,7 @@ public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor
throw new IllegalStateException(e);
}
else {
- try {
- return handleBlockException(request, body, execution,
- (BlockException) e);
- }
- catch (Exception ex) {
- if (ex instanceof IllegalStateException) {
- throw (IllegalStateException) ex;
- }
- throw new IllegalStateException(
- "sentinel handle BlockException error: " + ex.getMessage(),
- ex);
- }
+ return handleBlockException(request, body, execution, (BlockException) e);
}
}
finally {
@@ -109,84 +96,49 @@ public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor
}
private ClientHttpResponse handleBlockException(HttpRequest request, byte[] body,
- ClientHttpRequestExecution execution, BlockException ex) throws Exception {
+ ClientHttpRequestExecution execution, BlockException ex) {
Object[] args = new Object[] { request, body, execution, ex };
// handle degrade
if (isDegradeFailure(ex)) {
- Method method = extractFallbackMethod(sentinelRestTemplate.fallback(),
+ Method fallbackMethod = extractFallbackMethod(sentinelRestTemplate.fallback(),
sentinelRestTemplate.fallbackClass());
- if (method != null) {
- return (ClientHttpResponse) method.invoke(null, args);
+ if (fallbackMethod != null) {
+ return methodInvoke(fallbackMethod, args);
}
else {
return new SentinelClientHttpResponse();
}
}
- // handle block
+ // handle flow
Method blockHandler = extractBlockHandlerMethod(
sentinelRestTemplate.blockHandler(),
sentinelRestTemplate.blockHandlerClass());
if (blockHandler != null) {
- return (ClientHttpResponse) blockHandler.invoke(null, args);
+ return methodInvoke(blockHandler, args);
}
else {
return new SentinelClientHttpResponse();
}
}
+ private ClientHttpResponse methodInvoke(Method method, Object... args) {
+ try {
+ return (ClientHttpResponse) method.invoke(null, args);
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private Method extractFallbackMethod(String fallback, Class> fallbackClass) {
- if (StringUtil.isBlank(fallback) || fallbackClass == void.class) {
- return null;
- }
- Method cachedMethod = BlockClassRegistry.lookupFallback(fallbackClass, fallback);
- Class[] args = new Class[] { HttpRequest.class, byte[].class,
- ClientHttpRequestExecution.class, BlockException.class };
- if (cachedMethod == null) {
- cachedMethod = ClassUtils.getStaticMethod(fallbackClass, fallback, args);
- if (cachedMethod != null) {
- if (!ClientHttpResponse.class
- .isAssignableFrom(cachedMethod.getReturnType())) {
- throw new IllegalStateException(String.format(
- "the return type of method [%s] in class [%s] is not ClientHttpResponse in degrade",
- cachedMethod.getName(), fallbackClass.getCanonicalName()));
- }
- BlockClassRegistry.updateFallbackFor(fallbackClass, fallback,
- cachedMethod);
- }
- else {
- throw new IllegalStateException(String.format(
- "Cannot find method [%s] in class [%s] with parameters %s in degrade",
- fallback, fallbackClass.getCanonicalName(), Arrays.asList(args)));
- }
- }
- return cachedMethod;
+ return BlockClassRegistry.lookupFallback(fallbackClass, fallback);
}
private Method extractBlockHandlerMethod(String block, Class> blockClass) {
- if (StringUtil.isBlank(block) || blockClass == void.class) {
- return null;
- }
- Method cachedMethod = BlockClassRegistry.lookupBlockHandler(blockClass, block);
- Class[] args = new Class[] { HttpRequest.class, byte[].class,
- ClientHttpRequestExecution.class, BlockException.class };
- if (cachedMethod == null) {
- cachedMethod = ClassUtils.getStaticMethod(blockClass, block, args);
- if (cachedMethod != null) {
- if (!ClientHttpResponse.class
- .isAssignableFrom(cachedMethod.getReturnType())) {
- throw new IllegalStateException(String.format(
- "the return type of method [%s] in class [%s] is not ClientHttpResponse in flow control",
- cachedMethod.getName(), blockClass.getCanonicalName()));
- }
- BlockClassRegistry.updateBlockHandlerFor(blockClass, block, cachedMethod);
- }
- else {
- throw new IllegalStateException(String.format(
- "Cannot find method [%s] in class [%s] with parameters %s in flow control",
- block, blockClass.getCanonicalName(), Arrays.asList(args)));
- }
- }
- return cachedMethod;
+ return BlockClassRegistry.lookupBlockHandler(blockClass, block);
}
private boolean isDegradeFailure(BlockException ex) {
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
index d7e3e9da..cbd8d044 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
@@ -17,24 +17,20 @@
package org.springframework.cloud.alibaba.sentinel.endpoint;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.cloud.alibaba.sentinel.SentinelProperties;
-import org.springframework.cloud.alibaba.sentinel.custom.SentinelDataSourceHandler;
-import org.springframework.context.ApplicationContext;
-import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
-import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
+import com.alibaba.csp.sentinel.config.SentinelConfig;
+import com.alibaba.csp.sentinel.log.LogBase;
+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.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;
+import com.alibaba.csp.sentinel.transport.config.TransportConfig;
/**
* Endpoint for Sentinel, contains ans properties and rules
@@ -42,45 +38,39 @@ import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
*/
public class SentinelEndpoint extends AbstractEndpoint