Polish #51. Add a new module spring-cloud-alibaba-sentinel-datasource separate from spring-cloud-alibaba-sentinel.

pull/55/head
fangjian0423 6 years ago
parent 1ce28f00f3
commit 1d15cdaee5

@ -74,7 +74,7 @@
<modules> <modules>
<module>spring-cloud-alibaba-dependencies</module> <module>spring-cloud-alibaba-dependencies</module>
<module>spring-cloud-alibaba-sentinel</module> <module>spring-cloud-alibaba-sentinel</module>
<module>spring-cloud-alibaba-sentinel-datasource</module>
<module>spring-cloud-alibaba-nacos-config</module> <module>spring-cloud-alibaba-nacos-config</module>
<module>spring-cloud-alibaba-nacos-discovery</module> <module>spring-cloud-alibaba-nacos-discovery</module>
<module>spring-cloud-alibaba-examples</module> <module>spring-cloud-alibaba-examples</module>

@ -95,6 +95,11 @@
<artifactId>spring-cloud-alibaba-sentinel</artifactId> <artifactId>spring-cloud-alibaba-sentinel</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alicloud-oss</artifactId> <artifactId>spring-cloud-alicloud-oss</artifactId>

@ -222,7 +222,7 @@ Sentinel starter 整合了目前存在的几类 DataSource。只需要在配置
`spring.cloud.sentinel.datasource.converter`代表 `Converter` 在 Spring 容器里的 name。如果没找到会抛出异常。 `spring.cloud.sentinel.datasource.converter`代表 `Converter` 在 Spring 容器里的 name。如果没找到会抛出异常。
type目前支持file, nacos, zk, apollo。 type目前支持file, nacos, zk, apollo。其中nacoszkapollo的使用需要加上对应的依赖`sentinel-datasource-nacos`, `sentinel-datasource-zookeeper`, `sentinel-datasource-apollo`
### 自定义DataSource ### 自定义DataSource

@ -193,7 +193,8 @@ spring.cloud.sentinel.datasource.recommendRefreshMs means the recommendRefreshMs
spring.cloud.sentinel.datasource.converter means the name of spring bean that type is Converter. If the bean is not exists, will throw exception. spring.cloud.sentinel.datasource.converter means the name of spring bean that type is Converter. If the bean is not exists, will throw exception.
Now datasource type support 4 categories: file, nacos, zk, apollo. Now datasource type support 4 categories: file, nacos, zk, apollo. If you want to using nacos, zk or apollo, you should add `sentinel-datasource-nacos`, `sentinel-datasource-zookeeper` or `sentinel-datasource-apollo` dependency.
### User-defined DataSource ### User-defined DataSource

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>0.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
<name>Spring Cloud Alibaba Sentinel DataSource</name>
<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,152 @@
/*
* 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.datasource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import static org.springframework.core.io.support.ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
/**
* {@link ReadableDataSource} Loader
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class DataSourceLoader {
private static final Logger logger = LoggerFactory.getLogger(DataSourceLoader.class);
private final static String PROPERTIES_RESOURCE_LOCATION = "META-INF/sentinel-datasource.properties";
private final static String ALL_PROPERTIES_RESOURCES_LOCATION = CLASSPATH_ALL_URL_PREFIX
+ PROPERTIES_RESOURCE_LOCATION;
private final static ConcurrentMap<String, Class<? extends ReadableDataSource>> dataSourceClassesCache
= new ConcurrentHashMap<String, Class<? extends ReadableDataSource>>(
4);
static void loadAllDataSourceClassesCache() {
Map<String, Class<? extends ReadableDataSource>> dataSourceClassesMap = loadAllDataSourceClassesCache(
ALL_PROPERTIES_RESOURCES_LOCATION);
dataSourceClassesCache.putAll(dataSourceClassesMap);
}
static Map<String, Class<? extends ReadableDataSource>> loadAllDataSourceClassesCache(
String resourcesLocation) {
Map<String, Class<? extends ReadableDataSource>> dataSourcesMap
= new HashMap<String, Class<? extends ReadableDataSource>>(
4);
ClassLoader classLoader = DataSourceLoader.class.getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = resolver.getResources(resourcesLocation);
for (Resource resource : resources) {
if (resource.exists()) {
Properties properties = PropertiesLoaderUtils
.loadProperties(resource);
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
String type = (String)entry.getKey();
String className = (String)entry.getValue();
if (!ClassUtils.isPresent(className, classLoader)) {
if (logger.isDebugEnabled()) {
logger.debug(
"Sentinel DataSource implementation [ type : "
+ type + ": , class : " + className
+ " , url : " + resource.getURL()
+ "] was not present in current classpath , "
+ "thus loading will be ignored , please add dependency if required !");
}
continue;
}
Assert.isTrue(!dataSourcesMap.containsKey(type),
"The duplicated type[" + type
+ "] of SentinelDataSource were found in "
+ "resource [" + resource.getURL() + "]");
Class<?> dataSourceClass = ClassUtils.resolveClassName(className,
classLoader);
Assert.isAssignable(ReadableDataSource.class, dataSourceClass);
dataSourcesMap.put(type,
(Class<? extends ReadableDataSource>)dataSourceClass);
if (logger.isDebugEnabled()) {
logger.debug("Sentinel DataSource implementation [ type : "
+ type + ": , class : " + className
+ "] was loaded.");
}
}
}
}
} catch (IOException e) {
if (logger.isErrorEnabled()) {
logger.error(e.getMessage(), e);
}
}
return dataSourcesMap;
}
public static Class<? extends ReadableDataSource> loadClass(String type)
throws IllegalArgumentException {
Class<? extends ReadableDataSource> dataSourceClass = dataSourceClassesCache.get(type);
if (dataSourceClass == null) {
if (dataSourceClassesCache.isEmpty()) {
loadAllDataSourceClassesCache();
dataSourceClass = dataSourceClassesCache.get(type);
}
}
if (dataSourceClass == null) {
throw new IllegalArgumentException(
"Sentinel DataSource implementation [ type : " + type
+ " ] can't be found!");
}
return dataSourceClass;
}
}

@ -0,0 +1,33 @@
/*
* 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.datasource;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public interface SentinelDataSourceConstants {
String PROPERTY_PREFIX = "spring.cloud.sentinel";
String PROPERTY_ITEM_SEPARATOR = ".";
String PROPERTY_DATASOURCE_NAME = "datasource";
String PROPERTY_DATASOURCE_PREFIX = PROPERTY_PREFIX + PROPERTY_ITEM_SEPARATOR
+ PROPERTY_DATASOURCE_NAME;
}

@ -0,0 +1,258 @@
/*
* 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.datasource;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.csp.sentinel.datasource.Converter;
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.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.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.alibaba.sentinel.datasource.annotation.SentinelDataSource;
import org.springframework.cloud.alibaba.sentinel.datasource.util.PropertySourcesUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
/**
* {@link SentinelDataSource @SentinelDataSource} Post Processor
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see ReadableDataSource
* @see SentinelDataSource
*/
public class SentinelDataSourcePostProcessor
extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor {
private static final Logger logger = LoggerFactory
.getLogger(SentinelDataSourcePostProcessor.class);
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ConfigurableEnvironment environment;
private final Map<String, List<SentinelDataSourceField>> dataSourceFieldCache = new ConcurrentHashMap<>(
64);
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// find all fields using by @SentinelDataSource annotation
ReflectionUtils.doWithFields(beanType, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field)
throws IllegalArgumentException, IllegalAccessException {
SentinelDataSource annotation = getAnnotation(field,
SentinelDataSource.class);
if (annotation != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn(
"@SentinelDataSource annotation is not supported on static fields: "
+ field);
}
return;
}
if (dataSourceFieldCache.containsKey(beanName)) {
dataSourceFieldCache.get(beanName)
.add(new SentinelDataSourceField(annotation, field));
} else {
List<SentinelDataSourceField> list = new ArrayList<>();
list.add(new SentinelDataSourceField(annotation, field));
dataSourceFieldCache.put(beanName, list);
}
}
}
});
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeanCreationException {
if (dataSourceFieldCache.containsKey(beanName)) {
List<SentinelDataSourceField> sentinelDataSourceFields = dataSourceFieldCache
.get(beanName);
sentinelDataSourceFields.forEach(sentinelDataSourceField -> {
try {
// construct DataSource field annotated by @SentinelDataSource
Field field = sentinelDataSourceField.getField();
ReflectionUtils.makeAccessible(field);
String dataSourceBeanName = constructDataSource(
sentinelDataSourceField.getSentinelDataSource());
field.set(bean, applicationContext.getBean(dataSourceBeanName));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
});
}
return pvs;
}
private String constructDataSource(SentinelDataSource annotation) {
String prefix = annotation.value();
if (StringUtils.isEmpty(prefix)) {
prefix = SentinelDataSourceConstants.PROPERTY_DATASOURCE_PREFIX;
}
Map<String, Object> propertyMap = PropertySourcesUtils
.getSubProperties(environment.getPropertySources(), prefix);
String alias = propertyMap.get("type").toString();
Class dataSourceClass = DataSourceLoader.loadClass(alias);
String beanName = StringUtils.isEmpty(annotation.name())
? StringUtils.uncapitalize(dataSourceClass.getSimpleName()) + "_" + prefix
: annotation.name();
if (applicationContext.containsBean(beanName)) {
return beanName;
}
Class targetClass = null;
// if alias exists in SentinelDataSourceRegistry, wired properties into
// FactoryBean
if (SentinelDataSourceRegistry.checkFactoryBean(alias)) {
targetClass = SentinelDataSourceRegistry.getFactoryBean(alias);
} else {
// if alias not exists in SentinelDataSourceRegistry, wired properties into
// raw class
targetClass = dataSourceClass;
}
registerDataSource(beanName, targetClass, propertyMap);
return beanName;
}
private void registerDataSource(String beanName, Class targetClass,
Map<String, Object> propertyMap) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(targetClass);
for (String propertyName : propertyMap.keySet()) {
Field field = ReflectionUtils.findField(targetClass, propertyName);
if (field != null) {
if (field.getType().isAssignableFrom(Converter.class)) {
// Converter get from ApplicationContext
builder.addPropertyReference(propertyName,
propertyMap.get(propertyName).toString());
} else {
// wired properties
builder.addPropertyValue(propertyName, propertyMap.get(propertyName));
}
}
}
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)applicationContext
.getAutowireCapableBeanFactory();
beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
@EventListener(classes = ApplicationStartedEvent.class)
public void appStartedListener(ApplicationStartedEvent event) throws Exception {
Map<String, ReadableDataSource> dataSourceMap = event.getApplicationContext().getBeansOfType(
ReadableDataSource.class);
if (dataSourceMap.size() == 1) {
ReadableDataSource dataSource = dataSourceMap.values().iterator().next();
Object ruleConfig = dataSource.loadConfig();
SentinelProperty sentinelProperty = dataSource.getProperty();
if (checkRuleType(ruleConfig, FlowRule.class)) {
FlowRuleManager.register2Property(sentinelProperty);
}
if (checkRuleType(ruleConfig, DegradeRule.class)) {
DegradeRuleManager.register2Property(sentinelProperty);
}
if (checkRuleType(ruleConfig, SystemRule.class)) {
SystemRuleManager.register2Property(sentinelProperty);
}
if (checkRuleType(ruleConfig, AuthorityRule.class)) {
AuthorityRuleManager.register2Property(sentinelProperty);
}
}
}
private boolean checkRuleType(Object ruleConfig, Class type) {
if (ruleConfig.getClass() == type) {
return true;
} else if (ruleConfig instanceof List) {
List ruleList = (List)ruleConfig;
if (ruleList.stream().filter(rule -> rule.getClass() == type).toArray().length == ruleList.size()) {
return true;
}
}
return false;
}
class SentinelDataSourceField {
private SentinelDataSource sentinelDataSource;
private Field field;
public SentinelDataSourceField(SentinelDataSource sentinelDataSource,
Field field) {
this.sentinelDataSource = sentinelDataSource;
this.field = field;
}
public SentinelDataSource getSentinelDataSource() {
return sentinelDataSource;
}
public void setSentinelDataSource(SentinelDataSource sentinelDataSource) {
this.sentinelDataSource = sentinelDataSource;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
}
}

@ -16,7 +16,7 @@
package org.springframework.cloud.alibaba.sentinel.datasource; package org.springframework.cloud.alibaba.sentinel.datasource;
import java.util.concurrent.ConcurrentHashMap; import java.util.HashMap;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
@ -29,7 +29,7 @@ import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.Zookeep
/** /**
* Registry to save DataSource FactoryBean * Registry to save DataSource FactoryBean
* *
* @author fangjian * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see ReadableDataSource * @see ReadableDataSource
* @see FileRefreshableDataSourceFactoryBean * @see FileRefreshableDataSourceFactoryBean
* @see ZookeeperDataSourceFactoryBean * @see ZookeeperDataSourceFactoryBean
@ -38,7 +38,7 @@ import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.Zookeep
*/ */
public class SentinelDataSourceRegistry { public class SentinelDataSourceRegistry {
private static ConcurrentHashMap<String, Class<? extends FactoryBean>> cache = new ConcurrentHashMap<>( private static HashMap<String, Class<? extends FactoryBean>> cache = new HashMap<>(
32); 32);
static { static {
@ -54,7 +54,6 @@ public class SentinelDataSourceRegistry {
public static synchronized void registerFactoryBean(String alias, public static synchronized void registerFactoryBean(String alias,
Class<? extends FactoryBean> clazz) { Class<? extends FactoryBean> clazz) {
cache.putIfAbsent(alias, clazz);
cache.put(alias, clazz); cache.put(alias, clazz);
} }

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.alibaba.sentinel.annotation; package org.springframework.cloud.alibaba.sentinel.datasource.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
@ -31,7 +31,7 @@ import org.springframework.core.annotation.AliasFor;
* into a Spring Bean. The Properties of DataSource bean get from config files with * into a Spring Bean. The Properties of DataSource bean get from config files with
* specific prefix. * specific prefix.
* *
* @author fangjian * <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see ReadableDataSource * @see ReadableDataSource
*/ */
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})

@ -0,0 +1,63 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource;
import org.springframework.beans.factory.FactoryBean;
/**
* A {@link FactoryBean} for creating {@link ApolloDataSource} instance.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see ApolloDataSource
*/
public class ApolloDataSourceFactoryBean implements FactoryBean<ApolloDataSource> {
private String namespaceName;
private String flowRulesKey;
private String defaultFlowRuleValue;
private Converter converter;
@Override
public ApolloDataSource getObject() throws Exception {
return new ApolloDataSource(namespaceName, flowRulesKey, defaultFlowRuleValue,
converter);
}
@Override
public Class<?> getObjectType() {
return ApolloDataSource.class;
}
public String getNamespaceName() {
return namespaceName;
}
public void setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
}
public String getFlowRulesKey() {
return flowRulesKey;
}
public void setFlowRulesKey(String flowRulesKey) {
this.flowRulesKey = flowRulesKey;
}
public String getDefaultFlowRuleValue() {
return defaultFlowRuleValue;
}
public void setDefaultFlowRuleValue(String defaultFlowRuleValue) {
this.defaultFlowRuleValue = defaultFlowRuleValue;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -0,0 +1,76 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import java.io.File;
import java.nio.charset.Charset;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import org.springframework.beans.factory.FactoryBean;
/**
* A {@link FactoryBean} for creating {@link FileRefreshableDataSource} instance.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see FileRefreshableDataSource
*/
public class FileRefreshableDataSourceFactoryBean
implements FactoryBean<FileRefreshableDataSource> {
private String file;
private String charset;
private long recommendRefreshMs;
private int bufSize;
private Converter converter;
@Override
public FileRefreshableDataSource getObject() throws Exception {
return new FileRefreshableDataSource(new File(file), converter,
recommendRefreshMs, bufSize, Charset.forName(charset));
}
@Override
public Class<?> getObjectType() {
return FileRefreshableDataSource.class;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public long getRecommendRefreshMs() {
return recommendRefreshMs;
}
public void setRecommendRefreshMs(long recommendRefreshMs) {
this.recommendRefreshMs = recommendRefreshMs;
}
public int getBufSize() {
return bufSize;
}
public void setBufSize(int bufSize) {
this.bufSize = bufSize;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -0,0 +1,62 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import org.springframework.beans.factory.FactoryBean;
/**
* A {@link FactoryBean} for creating {@link NacosDataSource} instance.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see NacosDataSource
*/
public class NacosDataSourceFactoryBean implements FactoryBean<NacosDataSource> {
private String serverAddr;
private String groupId;
private String dataId;
private Converter converter;
@Override
public NacosDataSource getObject() throws Exception {
return new NacosDataSource(serverAddr, groupId, dataId, converter);
}
@Override
public Class<?> getObjectType() {
return NacosDataSource.class;
}
public String getServerAddr() {
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -0,0 +1,81 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.FactoryBean;
/**
* A {@link FactoryBean} for creating {@link ZookeeperDataSource} instance.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see ZookeeperDataSource
*/
public class ZookeeperDataSourceFactoryBean implements FactoryBean<ZookeeperDataSource> {
private String serverAddr;
private String path;
private String groupId;
private String dataId;
private Converter converter;
@Override
public ZookeeperDataSource getObject() throws Exception {
if (StringUtils.isNotEmpty(groupId) && StringUtils.isNotEmpty(dataId)) {
// the path will be /{groupId}/{dataId}
return new ZookeeperDataSource(serverAddr, groupId, dataId, converter);
} else {
// using path directly
return new ZookeeperDataSource(serverAddr, path, converter);
}
}
@Override
public Class<?> getObjectType() {
return ZookeeperDataSource.class;
}
public String getServerAddr() {
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -14,16 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.alibaba.sentinel.util; package org.springframework.cloud.alibaba.sentinel.datasource.util;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
/** /**
* {@link PropertySources} Utilities * {@link PropertySources} Utilities
* *
@ -47,7 +47,7 @@ public abstract class PropertySourcesUtils {
for (PropertySource<?> source : propertySources) { for (PropertySource<?> source : propertySources) {
if (source instanceof EnumerablePropertySource) { if (source instanceof EnumerablePropertySource) {
for (String name : ((EnumerablePropertySource<?>) source).getPropertyNames()) { for (String name : ((EnumerablePropertySource<?>)source).getPropertyNames()) {
if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) { if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) {
String subName = name.substring(normalizedPrefix.length()); String subName = name.substring(normalizedPrefix.length());
if (!subProperties.containsKey(subName)) { // take first one if (!subProperties.containsKey(subName)) { // take first one

@ -27,35 +27,17 @@
<dependency> <dependency>
<groupId>com.alibaba.csp</groupId> <groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId> <artifactId>sentinel-annotation-aspectj</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba.csp</groupId> <groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId> <artifactId>sentinel-dubbo-adapter</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.alibaba.csp</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>sentinel-dubbo-adapter</artifactId> <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency> </dependency>
<!--spring boot--> <!--spring boot-->

@ -23,11 +23,4 @@ public interface SentinelConstants {
String PROPERTY_PREFIX = "spring.cloud.sentinel"; String PROPERTY_PREFIX = "spring.cloud.sentinel";
String PROPERTY_ITEM_SEPARATOR = ".";
String PROPERTY_DATASOURCE_NAME = "datasource";
String PROPERTY_DATASOURCE_PREFIX = PROPERTY_PREFIX + PROPERTY_ITEM_SEPARATOR
+ PROPERTY_DATASOURCE_NAME;
} }

@ -1,151 +0,0 @@
/*
* 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.datasource;
import static org.springframework.core.io.support.ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
/**
* {@link ReadableDataSource} Loader
*
* @author fangjian
*/
public class DataSourceLoader {
private static final Logger logger = LoggerFactory.getLogger(DataSourceLoader.class);
private final static String PROPERTIES_RESOURCE_LOCATION = "META-INF/sentinel-datasource.properties";
private final static String ALL_PROPERTIES_RESOURCES_LOCATION = CLASSPATH_ALL_URL_PREFIX
+ PROPERTIES_RESOURCE_LOCATION;
private final static ConcurrentMap<String, Class<? extends ReadableDataSource>> dataSourceClassesCache = new ConcurrentHashMap<String, Class<? extends ReadableDataSource>>(
4);
static void loadAllDataSourceClassesCache() {
Map<String, Class<? extends ReadableDataSource>> dataSourceClassesMap = loadAllDataSourceClassesCache(
ALL_PROPERTIES_RESOURCES_LOCATION);
dataSourceClassesCache.putAll(dataSourceClassesMap);
}
static Map<String, Class<? extends ReadableDataSource>> loadAllDataSourceClassesCache(
String resourcesLocation) {
Map<String, Class<? extends ReadableDataSource>> dataSourcesMap = new HashMap<String, Class<? extends ReadableDataSource>>(
4);
ClassLoader classLoader = DataSourceLoader.class.getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources = resolver.getResources(resourcesLocation);
for (Resource resource : resources) {
if (resource.exists()) {
Properties properties = PropertiesLoaderUtils
.loadProperties(resource);
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
String type = (String) entry.getKey();
String className = (String) entry.getValue();
if (!ClassUtils.isPresent(className, classLoader)) {
if (logger.isDebugEnabled()) {
logger.debug(
"Sentinel DataSource implementation [ type : "
+ type + ": , class : " + className
+ " , url : " + resource.getURL()
+ "] was not present in current classpath , "
+ "thus loading will be ignored , please add dependency if required !");
}
continue;
}
Assert.isTrue(!dataSourcesMap.containsKey(type),
"The duplicated type[" + type
+ "] of SentinelDataSource were found in "
+ "resource [" + resource.getURL() + "]");
Class<?> dataSourceClass = ClassUtils.resolveClassName(className,
classLoader);
Assert.isAssignable(ReadableDataSource.class, dataSourceClass);
dataSourcesMap.put(type,
(Class<? extends ReadableDataSource>) dataSourceClass);
if (logger.isDebugEnabled()) {
logger.debug("Sentinel DataSource implementation [ type : "
+ type + ": , class : " + className
+ "] was loaded.");
}
}
}
}
}
catch (IOException e) {
if (logger.isErrorEnabled()) {
logger.error(e.getMessage(), e);
}
}
return dataSourcesMap;
}
public static Class<? extends ReadableDataSource> loadClass(String type)
throws IllegalArgumentException {
Class<? extends ReadableDataSource> dataSourceClass = dataSourceClassesCache.get(type);
if (dataSourceClass == null) {
if (dataSourceClassesCache.isEmpty()) {
loadAllDataSourceClassesCache();
dataSourceClass = dataSourceClassesCache.get(type);
}
}
if (dataSourceClass == null) {
throw new IllegalArgumentException(
"Sentinel DataSource implementation [ type : " + type
+ " ] can't be found!");
}
return dataSourceClass;
}
}

@ -1,264 +0,0 @@
/*
* 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.datasource;
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.alibaba.sentinel.SentinelConstants;
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelDataSource;
import org.springframework.cloud.alibaba.sentinel.util.PropertySourcesUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import com.alibaba.csp.sentinel.datasource.Converter;
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.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.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
/**
* {@link SentinelDataSource @SentinelDataSource} Post Processor
*
* @author fangjian
* @see com.alibaba.csp.sentinel.datasource.ReadableDataSource
* @see SentinelDataSource
*/
public class SentinelDataSourcePostProcessor
extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor {
private static final Logger logger = LoggerFactory
.getLogger(SentinelDataSourcePostProcessor.class);
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ConfigurableEnvironment environment;
private final Map<String, List<SentinelDataSourceField>> dataSourceFieldCache = new ConcurrentHashMap<>(
64);
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// find all fields using by @SentinelDataSource annotation
ReflectionUtils.doWithFields(beanType, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field)
throws IllegalArgumentException, IllegalAccessException {
SentinelDataSource annotation = getAnnotation(field,
SentinelDataSource.class);
if (annotation != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn(
"@SentinelDataSource annotation is not supported on static fields: "
+ field);
}
return;
}
if (dataSourceFieldCache.containsKey(beanName)) {
dataSourceFieldCache.get(beanName)
.add(new SentinelDataSourceField(annotation, field));
}
else {
List<SentinelDataSourceField> list = new ArrayList<>();
list.add(new SentinelDataSourceField(annotation, field));
dataSourceFieldCache.put(beanName, list);
}
}
}
});
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeanCreationException {
if (dataSourceFieldCache.containsKey(beanName)) {
List<SentinelDataSourceField> sentinelDataSourceFields = dataSourceFieldCache
.get(beanName);
sentinelDataSourceFields.forEach(sentinelDataSourceField -> {
try {
// construct DataSource field annotated by @SentinelDataSource
Field field = sentinelDataSourceField.getField();
ReflectionUtils.makeAccessible(field);
String dataSourceBeanName = constructDataSource(
sentinelDataSourceField.getSentinelDataSource());
field.set(bean, applicationContext.getBean(dataSourceBeanName));
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
});
}
return pvs;
}
private String constructDataSource(SentinelDataSource annotation) {
String prefix = annotation.value();
if (StringUtils.isEmpty(prefix)) {
prefix = SentinelConstants.PROPERTY_DATASOURCE_PREFIX;
}
Map<String, Object> propertyMap = PropertySourcesUtils
.getSubProperties(environment.getPropertySources(), prefix);
String alias = propertyMap.get("type").toString();
Class dataSourceClass = DataSourceLoader.loadClass(alias);
String beanName = StringUtils.isEmpty(annotation.name())
? StringUtils.uncapitalize(dataSourceClass.getSimpleName()) + "_" + prefix
: annotation.name();
if (applicationContext.containsBean(beanName)) {
return beanName;
}
Class targetClass = null;
// if alias exists in SentinelDataSourceRegistry, wired properties into
// FactoryBean
if (SentinelDataSourceRegistry.checkFactoryBean(alias)) {
targetClass = SentinelDataSourceRegistry.getFactoryBean(alias);
}
else {
// if alias not exists in SentinelDataSourceRegistry, wired properties into
// raw class
targetClass = dataSourceClass;
}
registerDataSource(beanName, targetClass, propertyMap);
return beanName;
}
private void registerDataSource(String beanName, Class targetClass,
Map<String, Object> propertyMap) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(targetClass);
for (String propertyName : propertyMap.keySet()) {
Field field = ReflectionUtils.findField(targetClass, propertyName);
if (field != null) {
if (field.getType().isAssignableFrom(Converter.class)) {
// Converter get from ApplicationContext
builder.addPropertyReference(propertyName,
propertyMap.get(propertyName).toString());
}
else {
// wired properties
builder.addPropertyValue(propertyName, propertyMap.get(propertyName));
}
}
}
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
.getAutowireCapableBeanFactory();
beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
@EventListener(classes = ApplicationStartedEvent.class)
public void appStartedListener(ApplicationStartedEvent event) throws Exception {
Map<String, ReadableDataSource> dataSourceMap = event.getApplicationContext().getBeansOfType(ReadableDataSource.class);
if(dataSourceMap.size() == 1) {
ReadableDataSource dataSource = dataSourceMap.values().iterator().next();
Object ruleConfig = dataSource.loadConfig();
SentinelProperty sentinelProperty = dataSource.getProperty();
if(checkRuleType(ruleConfig, FlowRule.class)) {
FlowRuleManager.register2Property(sentinelProperty);
}
if(checkRuleType(ruleConfig, DegradeRule.class)) {
DegradeRuleManager.register2Property(sentinelProperty);
}
if(checkRuleType(ruleConfig, SystemRule.class)) {
SystemRuleManager.register2Property(sentinelProperty);
}
if(checkRuleType(ruleConfig, AuthorityRule.class)) {
AuthorityRuleManager.register2Property(sentinelProperty);
}
}
}
private boolean checkRuleType(Object ruleConfig, Class type) {
if(ruleConfig.getClass() == type) {
return true;
} else if(ruleConfig instanceof List) {
List ruleList = (List)ruleConfig;
if(ruleList.stream().filter(rule -> rule.getClass() == type).toArray().length == ruleList.size()) {
return true;
}
}
return false;
}
class SentinelDataSourceField {
private SentinelDataSource sentinelDataSource;
private Field field;
public SentinelDataSourceField(SentinelDataSource sentinelDataSource,
Field field) {
this.sentinelDataSource = sentinelDataSource;
this.field = field;
}
public SentinelDataSource getSentinelDataSource() {
return sentinelDataSource;
}
public void setSentinelDataSource(SentinelDataSource sentinelDataSource) {
this.sentinelDataSource = sentinelDataSource;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
}
}

@ -1,61 +0,0 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import org.springframework.beans.factory.FactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource;
/**
* @author fangjian
* @see ApolloDataSource
*/
public class ApolloDataSourceFactoryBean implements FactoryBean<ApolloDataSource> {
private String namespaceName;
private String flowRulesKey;
private String defaultFlowRuleValue;
private Converter converter;
@Override
public ApolloDataSource getObject() throws Exception {
return new ApolloDataSource(namespaceName, flowRulesKey, defaultFlowRuleValue,
converter);
}
@Override
public Class<?> getObjectType() {
return ApolloDataSource.class;
}
public String getNamespaceName() {
return namespaceName;
}
public void setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
}
public String getFlowRulesKey() {
return flowRulesKey;
}
public void setFlowRulesKey(String flowRulesKey) {
this.flowRulesKey = flowRulesKey;
}
public String getDefaultFlowRuleValue() {
return defaultFlowRuleValue;
}
public void setDefaultFlowRuleValue(String defaultFlowRuleValue) {
this.defaultFlowRuleValue = defaultFlowRuleValue;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -1,74 +0,0 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import java.io.File;
import java.nio.charset.Charset;
import org.springframework.beans.factory.FactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
/**
* @author fangjian
* @see FileRefreshableDataSource
*/
public class FileRefreshableDataSourceFactoryBean
implements FactoryBean<FileRefreshableDataSource> {
private String file;
private String charset;
private long recommendRefreshMs;
private int bufSize;
private Converter converter;
@Override
public FileRefreshableDataSource getObject() throws Exception {
return new FileRefreshableDataSource(new File(file), converter,
recommendRefreshMs, bufSize, Charset.forName(charset));
}
@Override
public Class<?> getObjectType() {
return FileRefreshableDataSource.class;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public long getRecommendRefreshMs() {
return recommendRefreshMs;
}
public void setRecommendRefreshMs(long recommendRefreshMs) {
this.recommendRefreshMs = recommendRefreshMs;
}
public int getBufSize() {
return bufSize;
}
public void setBufSize(int bufSize) {
this.bufSize = bufSize;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -1,60 +0,0 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import org.springframework.beans.factory.FactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
/**
* @author fangjian
* @see NacosDataSource
*/
public class NacosDataSourceFactoryBean implements FactoryBean<NacosDataSource> {
private String serverAddr;
private String groupId;
private String dataId;
private Converter converter;
@Override
public NacosDataSource getObject() throws Exception {
return new NacosDataSource(serverAddr, groupId, dataId, converter);
}
@Override
public Class<?> getObjectType() {
return NacosDataSource.class;
}
public String getServerAddr() {
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -1,80 +0,0 @@
package org.springframework.cloud.alibaba.sentinel.datasource.factorybean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.FactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource;
/**
* @author fangjian
* @see ZookeeperDataSource
*/
public class ZookeeperDataSourceFactoryBean implements FactoryBean<ZookeeperDataSource> {
private String serverAddr;
private String path;
private String groupId;
private String dataId;
private Converter converter;
@Override
public ZookeeperDataSource getObject() throws Exception {
if (StringUtils.isNotEmpty(groupId) && StringUtils.isNotEmpty(dataId)) {
// the path will be /{groupId}/{dataId}
return new ZookeeperDataSource(serverAddr, groupId, dataId, converter);
}
else {
// using path directly
return new ZookeeperDataSource(serverAddr, path, converter);
}
}
@Override
public Class<?> getObjectType() {
return ZookeeperDataSource.class;
}
public String getServerAddr() {
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter Converter) {
this.converter = Converter;
}
}

@ -15,18 +15,6 @@
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel</artifactId> <artifactId>spring-cloud-alibaba-sentinel</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

Loading…
Cancel
Save