1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00

以2.2.1.BUILD-SNAPSHOT 为基准,适配Greenwich版本的Spring Cloud

This commit is contained in:
theonefx
2020-04-03 14:14:47 +08:00
parent e963a39bd4
commit 9444117f59
654 changed files with 7971 additions and 17442 deletions

View File

@@ -0,0 +1,132 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-starters</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
<name>Spring Cloud Alibaba Sentinel DataSource</name>
<dependencies>
<!--spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-parameter-flow-control</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
<optional>true</optional>
</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>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<optional>true</optional>
</dependency>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,127 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import java.util.Arrays;
import java.util.Optional;
import com.alibaba.cloud.sentinel.datasource.config.AbstractDataSourceProperties;
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;
import org.springframework.util.StringUtils;
/**
* Enum for {@link AbstractRule} class, using in
* {@link AbstractDataSourceProperties#ruleType}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
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),
/**
* gateway flow.
*/
GW_FLOW("gw-flow",
"com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),
/**
* api.
*/
GW_API_GROUP("gw-api-group",
"com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");
/**
* alias for {@link AbstractRule}.
*/
private final String name;
/**
* concrete {@link AbstractRule} class.
*/
private Class clazz;
/**
* concrete {@link AbstractRule} class name.
*/
private String clazzName;
RuleType(String name, Class clazz) {
this.name = name;
this.clazz = clazz;
}
RuleType(String name, String clazzName) {
this.name = name;
this.clazzName = clazzName;
}
public String getName() {
return name;
}
public Class getClazz() {
if (clazz != null) {
return clazz;
}
else {
try {
return Class.forName(clazzName);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
public static Optional<RuleType> 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<RuleType> getByClass(Class clazz) {
return Arrays.stream(RuleType.values())
.filter(ruleType -> clazz == ruleType.getClazz()).findFirst();
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
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;
import org.springframework.core.env.Environment;
/**
* Abstract class Using by {@link DataSourcePropertiesConfiguration}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class AbstractDataSourceProperties {
@NotEmpty
private String dataType = "json";
@NotNull
private RuleType ruleType;
private String converterClass;
@JsonIgnore
private final String factoryBeanName;
@JsonIgnore
private Environment env;
public AbstractDataSourceProperties(String factoryBeanName) {
this.factoryBeanName = factoryBeanName;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public RuleType getRuleType() {
return ruleType;
}
public void setRuleType(RuleType ruleType) {
this.ruleType = ruleType;
}
public String getConverterClass() {
return converterClass;
}
public void setConverterClass(String converterClass) {
this.converterClass = converterClass;
}
public String getFactoryBeanName() {
return factoryBeanName;
}
protected Environment getEnv() {
return env;
}
public void setEnv(Environment env) {
this.env = env;
}
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;
case GW_FLOW:
GatewayRuleManager.register2Property(dataSource.getProperty());
break;
case GW_API_GROUP:
GatewayApiDefinitionManager.register2Property(dataSource.getProperty());
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import javax.validation.constraints.NotEmpty;
import com.alibaba.cloud.sentinel.datasource.factorybean.ApolloDataSourceFactoryBean;
/**
* Apollo Properties class Using by {@link DataSourcePropertiesConfiguration} and
* {@link ApolloDataSourceFactoryBean}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class ApolloDataSourceProperties extends AbstractDataSourceProperties {
@NotEmpty
private String namespaceName;
@NotEmpty
private String flowRulesKey;
private String defaultFlowRuleValue;
public ApolloDataSourceProperties() {
super(ApolloDataSourceFactoryBean.class.getName());
}
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;
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.ObjectUtils;
/**
* Using By ConfigurationProperties.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see NacosDataSourceProperties
* @see ApolloDataSourceProperties
* @see ZookeeperDataSourceProperties
* @see FileDataSourceProperties
* @see RedisDataSourceProperties
*/
public class DataSourcePropertiesConfiguration {
private FileDataSourceProperties file;
private NacosDataSourceProperties nacos;
private ZookeeperDataSourceProperties zk;
private ApolloDataSourceProperties apollo;
private RedisDataSourceProperties redis;
public DataSourcePropertiesConfiguration() {
}
public DataSourcePropertiesConfiguration(FileDataSourceProperties file) {
this.file = file;
}
public DataSourcePropertiesConfiguration(NacosDataSourceProperties nacos) {
this.nacos = nacos;
}
public DataSourcePropertiesConfiguration(ZookeeperDataSourceProperties zk) {
this.zk = zk;
}
public DataSourcePropertiesConfiguration(ApolloDataSourceProperties apollo) {
this.apollo = apollo;
}
public DataSourcePropertiesConfiguration(RedisDataSourceProperties redis) {
this.redis = redis;
}
public FileDataSourceProperties getFile() {
return file;
}
public void setFile(FileDataSourceProperties file) {
this.file = file;
}
public NacosDataSourceProperties getNacos() {
return nacos;
}
public void setNacos(NacosDataSourceProperties nacos) {
this.nacos = nacos;
}
public ZookeeperDataSourceProperties getZk() {
return zk;
}
public void setZk(ZookeeperDataSourceProperties zk) {
this.zk = zk;
}
public ApolloDataSourceProperties getApollo() {
return apollo;
}
public void setApollo(ApolloDataSourceProperties apollo) {
this.apollo = apollo;
}
public RedisDataSourceProperties getRedis() {
return redis;
}
public void setRedis(RedisDataSourceProperties redis) {
this.redis = redis;
}
@JsonIgnore
public List<String> getValidField() {
return Arrays.stream(this.getClass().getDeclaredFields()).map(field -> {
try {
if (!ObjectUtils.isEmpty(field.get(this))) {
return field.getName();
}
return null;
}
catch (IllegalAccessException e) {
// won't happen
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
}
@JsonIgnore
public AbstractDataSourceProperties getValidDataSourceProperties() {
List<String> invalidFields = getValidField();
if (invalidFields.size() == 1) {
try {
this.getClass().getDeclaredField(invalidFields.get(0))
.setAccessible(true);
return (AbstractDataSourceProperties) this.getClass()
.getDeclaredField(invalidFields.get(0)).get(this);
}
catch (IllegalAccessException e) {
// won't happen
}
catch (NoSuchFieldException e) {
// won't happen
}
}
return null;
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import java.io.IOException;
import javax.validation.constraints.NotEmpty;
import com.alibaba.cloud.sentinel.datasource.factorybean.FileRefreshableDataSourceFactoryBean;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
/**
* File Properties class Using by {@link DataSourcePropertiesConfiguration} and
* {@link FileRefreshableDataSourceFactoryBean}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class FileDataSourceProperties extends AbstractDataSourceProperties {
@NotEmpty
private String file;
private String charset = "utf-8";
private long recommendRefreshMs = 3000L;
private int bufSize = 1024 * 1024;
public FileDataSourceProperties() {
super(FileRefreshableDataSourceFactoryBean.class.getName());
}
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;
}
@Override
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] DataSource " + dataSourceName
+ " handle file [" + this.getFile() + "] error: " + e.getMessage(),
e);
}
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import javax.validation.constraints.NotEmpty;
import com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import org.springframework.util.StringUtils;
/**
* Nacos Properties class Using by {@link DataSourcePropertiesConfiguration} and
* {@link NacosDataSourceFactoryBean}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class NacosDataSourceProperties extends AbstractDataSourceProperties {
private String serverAddr;
@NotEmpty
private String groupId = "DEFAULT_GROUP";
@NotEmpty
private String dataId;
private String endpoint;
private String namespace;
private String accessKey;
private String secretKey;
public NacosDataSourceProperties() {
super(NacosDataSourceFactoryBean.class.getName());
}
@Override
public void preCheck(String dataSourceName) {
if (StringUtils.isEmpty(serverAddr)) {
serverAddr = this.getEnv().getProperty(
"spring.cloud.sentinel.datasource.nacos.server-addr",
"localhost:8848");
}
}
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 String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import java.time.Duration;
import java.util.List;
import com.alibaba.cloud.sentinel.datasource.factorybean.RedisDataSourceFactoryBean;
import org.springframework.util.StringUtils;
/**
* Zookeeper Properties class Using by {@link DataSourcePropertiesConfiguration} and
* {@link RedisDataSourceFactoryBean}.
*
* @author <a href="mailto:wangiegie@gmail.com">lengleng</a>
*/
public class RedisDataSourceProperties extends AbstractDataSourceProperties {
public RedisDataSourceProperties() {
super(RedisDataSourceFactoryBean.class.getName());
}
/**
* redis server host.
*/
private String host = "localhost";
/**
* redis server port.
*/
private int port = 6379;
/**
* redis server password.
*/
private String password;
/**
* redis server default select database.
*/
private int database;
/**
* redis server timeout.
*/
private Duration timeout;
/**
* Comma-separated list of "host:port" pairs.
*/
private List<String> nodes;
/**
* data key in Redis.
*/
private String ruleKey;
/**
* channel to subscribe in Redis.
*/
private String channel;
/**
* redis sentinel model.
*/
private String masterId;
@Override
public void preCheck(String dataSourceName) {
super.preCheck(dataSourceName);
if (StringUtils.isEmpty(ruleKey)) {
throw new IllegalArgumentException(
"RedisDataSource ruleKey can not be empty");
}
if (StringUtils.isEmpty(channel)) {
throw new IllegalArgumentException(
"RedisDataSource channel can not be empty");
}
if (!StringUtils.isEmpty(masterId) && StringUtils.isEmpty(masterId)) {
throw new IllegalArgumentException(
"RedisDataSource sentinel modelmasterId can not be empty");
}
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getRuleKey() {
return ruleKey;
}
public void setRuleKey(String ruleKey) {
this.ruleKey = ruleKey;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public Duration getTimeout() {
return timeout;
}
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
public String getMasterId() {
return masterId;
}
public void setMasterId(String masterId) {
this.masterId = masterId;
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.config;
import com.alibaba.cloud.sentinel.datasource.factorybean.ZookeeperDataSourceFactoryBean;
import org.springframework.util.StringUtils;
/**
* Zookeeper Properties class Using by {@link DataSourcePropertiesConfiguration} and
* {@link ZookeeperDataSourceFactoryBean}.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class ZookeeperDataSourceProperties extends AbstractDataSourceProperties {
public ZookeeperDataSourceProperties() {
super(ZookeeperDataSourceFactoryBean.class.getName());
}
private String serverAddr = "localhost:2181";
private String path;
private String groupId;
private String dataId;
@Override
public void preCheck(String dataSourceName) {
if (StringUtils.isEmpty(serverAddr)) {
serverAddr = this.getEnv()
.getProperty("spring.cloud.sentinel.datasource.zk.server-addr", "");
if (StringUtils.isEmpty(serverAddr)) {
throw new IllegalArgumentException(
"ZookeeperDataSource server-addr is empty");
}
}
}
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;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.converter;
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.fasterxml.jackson.databind.ObjectMapper;
/**
* Convert sentinel rules for json array Using strict mode to parse json.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see FlowRule
* @see DegradeRule
* @see SystemRule
* @see AuthorityRule
* @see ParamFlowRule
* @see ObjectMapper
*/
public class JsonConverter<T> extends SentinelConverter {
public JsonConverter(ObjectMapper objectMapper, Class<T> ruleClass) {
super(objectMapper, ruleClass);
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.converter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import com.alibaba.csp.sentinel.datasource.Converter;
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.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
/**
* Convert sentinel rules for json or xml array Using strict mode to parse json or xml.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see FlowRule
* @see DegradeRule
* @see SystemRule
* @see AuthorityRule
* @see ParamFlowRule
* @see ObjectMapper
*/
public abstract class SentinelConverter<T extends Object>
implements Converter<String, Collection<Object>> {
private static final Logger log = LoggerFactory.getLogger(SentinelConverter.class);
private final ObjectMapper objectMapper;
private final Class<T> ruleClass;
public SentinelConverter(ObjectMapper objectMapper, Class<T> ruleClass) {
this.objectMapper = objectMapper;
this.ruleClass = ruleClass;
}
@Override
public Collection<Object> convert(String source) {
Collection<Object> ruleCollection;
// hard code
if (ruleClass == FlowRule.class || ruleClass == DegradeRule.class
|| ruleClass == SystemRule.class || ruleClass == AuthorityRule.class
|| ruleClass == ParamFlowRule.class) {
ruleCollection = new ArrayList<>();
}
else {
ruleCollection = new HashSet<>();
}
if (StringUtils.isEmpty(source)) {
log.warn("converter can not convert rules because source is empty");
return ruleCollection;
}
try {
List sourceArray = objectMapper.readValue(source,
new TypeReference<List<HashMap>>() {
});
for (Object obj : sourceArray) {
String item = null;
try {
item = objectMapper.writeValueAsString(obj);
Optional.ofNullable(convertRule(item))
.ifPresent(convertRule -> ruleCollection.add(convertRule));
}
catch (IOException e) {
log.error("sentinel rule convert error: " + e.getMessage(), e);
throw new IllegalArgumentException(
"sentinel rule convert error: " + e.getMessage(), e);
}
}
}
catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
else {
throw new RuntimeException("convert error: " + e.getMessage(), e);
}
}
return ruleCollection;
}
private Object convertRule(String ruleStr) throws IOException {
return objectMapper.readValue(ruleStr, ruleClass);
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.converter;
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.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
/**
* Convert sentinel rules for xml array Using strict mode to parse xml.
*
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see FlowRule
* @see DegradeRule
* @see SystemRule
* @see AuthorityRule
* @see ParamFlowRule
* @see ObjectMapper
*/
public class XmlConverter<T> extends SentinelConverter {
public XmlConverter(XmlMapper xmlMapper, Class<T> ruleClass) {
super(xmlMapper, ruleClass);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.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;
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.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;
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.factorybean;
import java.util.Properties;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.nacos.api.PropertyKeyConst;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.StringUtils;
/**
* 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;
private String endpoint;
private String namespace;
private String accessKey;
private String secretKey;
@Override
public NacosDataSource getObject() throws Exception {
Properties properties = new Properties();
if (!StringUtils.isEmpty(this.serverAddr)) {
properties.setProperty(PropertyKeyConst.SERVER_ADDR, this.serverAddr);
}
else {
properties.setProperty(PropertyKeyConst.ACCESS_KEY, this.accessKey);
properties.setProperty(PropertyKeyConst.SECRET_KEY, this.secretKey);
properties.setProperty(PropertyKeyConst.ENDPOINT, this.endpoint);
}
if (!StringUtils.isEmpty(this.namespace)) {
properties.setProperty(PropertyKeyConst.NAMESPACE, this.namespace);
}
return new NacosDataSource(properties, 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;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource.factorybean;
import java.time.Duration;
import java.util.List;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.redis.RedisDataSource;
import com.alibaba.csp.sentinel.datasource.redis.config.RedisConnectionConfig;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* A {@link FactoryBean} for creating {@link RedisDataSource} instance.
*
* @author <a href="mailto:wangiegie@gmail.com">lengleng</a>
* @see RedisDataSource
*/
public class RedisDataSourceFactoryBean implements FactoryBean<RedisDataSource> {
private String host;
private int port;
private int database;
private Duration timeout;
/**
* Comma-separated list of "host:port" pairs.
*/
private List<String> nodes;
private Converter converter;
/**
* data key in Redis.
*/
private String ruleKey;
/**
* channel to subscribe in Redis.
*/
private String channel;
/**
* redis server password.
*/
private String password;
private String masterId;
@Override
public RedisDataSource getObject() {
RedisConnectionConfig.Builder builder = RedisConnectionConfig.builder();
if (nodes == null || nodes.isEmpty()) {
builder.withHost(host).withPort(port).withDatabase(database);
}
else {
nodes.forEach(node -> {
try {
String[] parts = StringUtils.split(node, ":");
Assert.state(parts.length == 2, "Must be defined as 'host:port'");
builder.withRedisSentinel(parts[0], Integer.parseInt(parts[1]));
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Invalid redis sentinel property " + node, ex);
}
});
builder.withSentinelMasterId(masterId);
}
if (timeout != null) {
builder.withTimeout(timeout.toMillis());
}
if (StringUtils.hasText(password)) {
builder.withPassword(password);
}
return new RedisDataSource<List<FlowRule>>(builder.build(), ruleKey, channel,
converter);
}
@Override
public Class<?> getObjectType() {
return RedisDataSource.class;
}
public Converter getConverter() {
return converter;
}
public void setConverter(Converter converter) {
this.converter = converter;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getRuleKey() {
return ruleKey;
}
public void setRuleKey(String ruleKey) {
this.ruleKey = ruleKey;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public Duration getTimeout() {
return timeout;
}
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
public String getMasterId() {
return masterId;
}
public void setMasterId(String masterId) {
this.masterId = masterId;
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.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;
}
}

View File

@@ -0,0 +1,5 @@
nacos = com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource
file =com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource
apollo = com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource
zk = com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource
redis = com.alibaba.csp.sentinel.datasource.redis.RedisDataSource

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import com.alibaba.cloud.sentinel.datasource.converter.JsonConverter;
import com.alibaba.cloud.sentinel.datasource.factorybean.ApolloDataSourceFactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class ApolloDataSourceFactoryBeanTests {
private String flowRuleKey = "sentinel";
private String namespace = "namespace";
private String defaultFlowValue = "{}";
@Test
public void testApolloFactoryBean() throws Exception {
ApolloDataSourceFactoryBean factoryBean = spy(new ApolloDataSourceFactoryBean());
Converter converter = mock(JsonConverter.class);
factoryBean.setDefaultFlowRuleValue(defaultFlowValue);
factoryBean.setFlowRulesKey(flowRuleKey);
factoryBean.setNamespaceName(namespace);
factoryBean.setConverter(converter);
ApolloDataSource apolloDataSource = mock(ApolloDataSource.class);
when(apolloDataSource.readSource()).thenReturn("{}");
doReturn(apolloDataSource).when(factoryBean).getObject();
assertThat(factoryBean.getObject()).isEqualTo(apolloDataSource);
assertThat(factoryBean.getObject().readSource()).isEqualTo("{}");
assertThat(factoryBean.getConverter()).isEqualTo(converter);
assertThat(factoryBean.getFlowRulesKey()).isEqualTo(flowRuleKey);
assertThat(factoryBean.getNamespaceName()).isEqualTo(namespace);
assertThat(factoryBean.getDefaultFlowRuleValue()).isEqualTo(defaultFlowValue);
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import java.io.IOException;
import java.util.List;
import com.alibaba.cloud.sentinel.datasource.config.ApolloDataSourceProperties;
import com.alibaba.cloud.sentinel.datasource.config.FileDataSourceProperties;
import com.alibaba.cloud.sentinel.datasource.config.ZookeeperDataSourceProperties;
import com.alibaba.cloud.sentinel.datasource.factorybean.ApolloDataSourceFactoryBean;
import com.alibaba.cloud.sentinel.datasource.factorybean.FileRefreshableDataSourceFactoryBean;
import com.alibaba.cloud.sentinel.datasource.factorybean.ZookeeperDataSourceFactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class DataSourcePropertiesTests {
@Test
public void testApollo() {
ApolloDataSourceProperties apolloDataSourceProperties = new ApolloDataSourceProperties();
apolloDataSourceProperties.setFlowRulesKey("test-key");
apolloDataSourceProperties.setDefaultFlowRuleValue("dft-val");
apolloDataSourceProperties.setNamespaceName("namespace");
apolloDataSourceProperties.setRuleType(RuleType.DEGRADE);
assertThat(apolloDataSourceProperties.getFlowRulesKey()).isEqualTo("test-key");
assertThat(apolloDataSourceProperties.getNamespaceName()).isEqualTo("namespace");
assertThat(apolloDataSourceProperties.getDataType()).isEqualTo("json");
assertThat(apolloDataSourceProperties.getRuleType()).isEqualTo(RuleType.DEGRADE);
assertThat(apolloDataSourceProperties.getDefaultFlowRuleValue())
.isEqualTo("dft-val");
assertThat(apolloDataSourceProperties.getFactoryBeanName())
.isEqualTo(ApolloDataSourceFactoryBean.class.getName());
assertThat(apolloDataSourceProperties.getConverterClass()).isNull();
}
@Test
public void testZK() {
ZookeeperDataSourceProperties zookeeperDataSourceProperties = new ZookeeperDataSourceProperties();
zookeeperDataSourceProperties.setServerAddr("localhost:2181");
zookeeperDataSourceProperties.setGroupId("groupId");
zookeeperDataSourceProperties.setDataId("dataId");
zookeeperDataSourceProperties.setPath("/path");
zookeeperDataSourceProperties.setConverterClass("test.ConverterClass");
zookeeperDataSourceProperties.setRuleType(RuleType.AUTHORITY);
assertThat(zookeeperDataSourceProperties.getServerAddr())
.isEqualTo("localhost:2181");
assertThat(zookeeperDataSourceProperties.getGroupId()).isEqualTo("groupId");
assertThat(zookeeperDataSourceProperties.getDataId()).isEqualTo("dataId");
assertThat(zookeeperDataSourceProperties.getPath()).isEqualTo("/path");
assertThat(zookeeperDataSourceProperties.getFactoryBeanName())
.isEqualTo(ZookeeperDataSourceFactoryBean.class.getName());
assertThat(zookeeperDataSourceProperties.getConverterClass())
.isEqualTo("test.ConverterClass");
assertThat(zookeeperDataSourceProperties.getRuleType())
.isEqualTo(RuleType.AUTHORITY);
}
@Test
public void testFileDefaultValue() {
FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
fileDataSourceProperties.setFile("/tmp/test.json");
fileDataSourceProperties.setRuleType(RuleType.PARAM_FLOW);
assertThat(fileDataSourceProperties.getFile()).isEqualTo("/tmp/test.json");
assertThat(fileDataSourceProperties.getCharset()).isEqualTo("utf-8");
assertThat(fileDataSourceProperties.getRecommendRefreshMs()).isEqualTo(3000L);
assertThat(fileDataSourceProperties.getBufSize()).isEqualTo(1024 * 1024);
assertThat(fileDataSourceProperties.getFactoryBeanName())
.isEqualTo(FileRefreshableDataSourceFactoryBean.class.getName());
assertThat(fileDataSourceProperties.getRuleType()).isEqualTo(RuleType.PARAM_FLOW);
}
@Test
public void testFileCustomValue() {
FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
fileDataSourceProperties.setFile("/tmp/test.json");
fileDataSourceProperties.setBufSize(1024);
fileDataSourceProperties.setRecommendRefreshMs(2000);
fileDataSourceProperties.setCharset("ISO8859-1");
assertThat(fileDataSourceProperties.getFile()).isEqualTo("/tmp/test.json");
assertThat(fileDataSourceProperties.getCharset()).isEqualTo("ISO8859-1");
assertThat(fileDataSourceProperties.getRecommendRefreshMs()).isEqualTo(2000L);
assertThat(fileDataSourceProperties.getBufSize()).isEqualTo(1024);
}
@Test(expected = RuntimeException.class)
public void testFileException() {
FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
fileDataSourceProperties.setFile("classpath: 1.json");
fileDataSourceProperties.preCheck("test-ds");
}
@Test
public void testPostRegister() throws Exception {
FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
fileDataSourceProperties.setFile("classpath: flowrule.json");
fileDataSourceProperties.setRuleType(RuleType.FLOW);
FileRefreshableDataSource fileRefreshableDataSource = new FileRefreshableDataSource(
ResourceUtils
.getFile(StringUtils
.trimAllWhitespace(fileDataSourceProperties.getFile()))
.getAbsolutePath(),
new Converter<String, List<FlowRule>>() {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public List<FlowRule> convert(String source) {
try {
return objectMapper.readValue(source,
new TypeReference<List<FlowRule>>() {
});
}
catch (IOException e) {
// ignore
}
return null;
}
});
fileDataSourceProperties.postRegister(fileRefreshableDataSource);
assertThat(FlowRuleManager.getRules())
.isEqualTo(fileRefreshableDataSource.loadConfig());
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import com.alibaba.cloud.sentinel.datasource.factorybean.FileRefreshableDataSourceFactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class FileRefreshableDataSourceFactoryBeanTests {
@Test
public void testFile() throws Exception {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
TestConfig.class);
assertThat(annotationConfigApplicationContext.getBean("fileBean")).isNotNull();
FileRefreshableDataSource fileRefreshableDataSource = annotationConfigApplicationContext
.getBean("fileBean", FileRefreshableDataSource.class);
assertThat(((List<FlowRule>) fileRefreshableDataSource.loadConfig()).size())
.isEqualTo(1);
FileRefreshableDataSourceFactoryBean factoryBean = annotationConfigApplicationContext
.getBean("&fileBean", FileRefreshableDataSourceFactoryBean.class);
assertThat(factoryBean.getBufSize()).isEqualTo(1024);
assertThat(factoryBean.getCharset()).isEqualTo("utf-8");
assertThat(factoryBean.getRecommendRefreshMs()).isEqualTo(2000);
assertThat(factoryBean.getFile()).isNotNull();
assertThat(factoryBean.getConverter()).isNotNull();
}
@Configuration
public static class TestConfig {
@Bean
public FileRefreshableDataSourceFactoryBean fileBean() {
FileRefreshableDataSourceFactoryBean factoryBean = new FileRefreshableDataSourceFactoryBean();
factoryBean.setBufSize(1024);
factoryBean.setCharset("utf-8");
factoryBean.setRecommendRefreshMs(2000);
try {
factoryBean.setFile(ResourceUtils.getFile("classpath:flowrule.json")
.getAbsolutePath());
}
catch (FileNotFoundException e) {
// ignore
}
factoryBean.setConverter(buildConverter());
return factoryBean;
}
private Converter buildConverter() {
return new Converter<String, List<FlowRule>>() {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public List<FlowRule> convert(String source) {
try {
return objectMapper.readValue(source,
new TypeReference<List<FlowRule>>() {
});
}
catch (IOException e) {
// ignore
}
return null;
}
};
}
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import com.alibaba.cloud.sentinel.datasource.converter.SentinelConverter;
import com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class NacosDataSourceFactoryBeanTests {
private String dataId = "sentinel";
private String groupId = "DEFAULT_GROUP";
private String serverAddr = "localhost:8848";
private String accessKey = "ak";
private String secretKey = "sk";
private String endpoint = "endpoint";
private String namespace = "namespace";
@Test
public void testNacosFactoryBeanServerAddr() throws Exception {
NacosDataSourceFactoryBean factoryBean = spy(new NacosDataSourceFactoryBean());
Converter converter = mock(SentinelConverter.class);
factoryBean.setDataId(dataId);
factoryBean.setGroupId(groupId);
factoryBean.setServerAddr(serverAddr);
factoryBean.setConverter(converter);
NacosDataSource nacosDataSource = mock(NacosDataSource.class);
doReturn(nacosDataSource).when(factoryBean).getObject();
when(nacosDataSource.readSource()).thenReturn("{}");
assertThat(factoryBean.getObject()).isEqualTo(nacosDataSource);
assertThat(factoryBean.getObject().readSource()).isEqualTo("{}");
assertThat(factoryBean.getConverter()).isEqualTo(converter);
assertThat(factoryBean.getDataId()).isEqualTo(dataId);
assertThat(factoryBean.getGroupId()).isEqualTo(groupId);
assertThat(factoryBean.getServerAddr()).isEqualTo(serverAddr);
}
@Test
public void testNacosFactoryBeanProperties() throws Exception {
NacosDataSourceFactoryBean factoryBean = spy(new NacosDataSourceFactoryBean());
Converter converter = mock(SentinelConverter.class);
factoryBean.setDataId(dataId);
factoryBean.setGroupId(groupId);
factoryBean.setAccessKey(accessKey);
factoryBean.setSecretKey(secretKey);
factoryBean.setEndpoint(endpoint);
factoryBean.setNamespace(namespace);
factoryBean.setConverter(converter);
NacosDataSource nacosDataSource = mock(NacosDataSource.class);
doReturn(nacosDataSource).when(factoryBean).getObject();
when(nacosDataSource.readSource()).thenReturn("{}");
assertThat(factoryBean.getObject()).isEqualTo(nacosDataSource);
assertThat(factoryBean.getObject().readSource()).isEqualTo("{}");
assertThat(factoryBean.getConverter()).isEqualTo(converter);
assertThat(factoryBean.getDataId()).isEqualTo(dataId);
assertThat(factoryBean.getGroupId()).isEqualTo(groupId);
assertThat(factoryBean.getNamespace()).isEqualTo(namespace);
assertThat(factoryBean.getEndpoint()).isEqualTo(endpoint);
assertThat(factoryBean.getAccessKey()).isEqualTo(accessKey);
assertThat(factoryBean.getSecretKey()).isEqualTo(secretKey);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties;
import com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class NacosDataSourcePropertiesTests {
@Test
public void testNacosWithAddr() {
NacosDataSourceProperties nacosDataSourceProperties = new NacosDataSourceProperties();
nacosDataSourceProperties.setServerAddr("127.0.0.1:8848");
nacosDataSourceProperties.setRuleType(RuleType.FLOW);
nacosDataSourceProperties.setDataId("sentinel");
nacosDataSourceProperties.setGroupId("custom-group");
nacosDataSourceProperties.setDataType("xml");
assertThat(nacosDataSourceProperties.getGroupId()).isEqualTo("custom-group");
assertThat(nacosDataSourceProperties.getDataId()).isEqualTo("sentinel");
assertThat(nacosDataSourceProperties.getDataType()).isEqualTo("xml");
assertThat(nacosDataSourceProperties.getRuleType()).isEqualTo(RuleType.FLOW);
assertThat(nacosDataSourceProperties.getFactoryBeanName())
.isEqualTo(NacosDataSourceFactoryBean.class.getName());
}
@Test
public void testNacosWithProperties() {
NacosDataSourceProperties nacosDataSourceProperties = new NacosDataSourceProperties();
nacosDataSourceProperties.setAccessKey("ak");
nacosDataSourceProperties.setSecretKey("sk");
nacosDataSourceProperties.setEndpoint("endpoint");
nacosDataSourceProperties.setNamespace("namespace");
nacosDataSourceProperties.setRuleType(RuleType.SYSTEM);
assertThat(nacosDataSourceProperties.getAccessKey()).isEqualTo("ak");
assertThat(nacosDataSourceProperties.getSecretKey()).isEqualTo("sk");
assertThat(nacosDataSourceProperties.getEndpoint()).isEqualTo("endpoint");
assertThat(nacosDataSourceProperties.getNamespace()).isEqualTo("namespace");
assertThat(nacosDataSourceProperties.getRuleType()).isEqualTo(RuleType.SYSTEM);
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
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;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class RuleTypeTests {
@Test
public void testGetByName() {
assertThat(RuleType.getByName("").isPresent()).isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByName("test").isPresent()).isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByName("param_flow").isPresent()).isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByName("param").isPresent()).isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByName("FLOW").isPresent()).isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByName("flow").isPresent()).isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByName("degrade").isPresent()).isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByName("param-flow").isPresent()).isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByName("system").isPresent()).isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByName("authority").isPresent()).isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByName("flow").get()).isEqualTo(RuleType.FLOW);
assertThat(RuleType.getByName("degrade").get()).isEqualTo(RuleType.DEGRADE);
assertThat(RuleType.getByName("param-flow").get()).isEqualTo(RuleType.PARAM_FLOW);
assertThat(RuleType.getByName("system").get()).isEqualTo(RuleType.SYSTEM);
assertThat(RuleType.getByName("authority").get()).isEqualTo(RuleType.AUTHORITY);
}
@Test
public void testGetByClass() {
assertThat(RuleType.getByClass(Object.class).isPresent())
.isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByClass(AbstractRule.class).isPresent())
.isEqualTo(Boolean.FALSE);
assertThat(RuleType.getByClass(FlowRule.class).isPresent())
.isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByClass(DegradeRule.class).isPresent())
.isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByClass(ParamFlowRule.class).isPresent())
.isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByClass(SystemRule.class).isPresent())
.isEqualTo(Boolean.TRUE);
assertThat(RuleType.getByClass(AuthorityRule.class).isPresent())
.isEqualTo(Boolean.TRUE);
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import java.io.IOException;
import java.util.List;
import com.alibaba.cloud.sentinel.datasource.converter.JsonConverter;
import com.alibaba.cloud.sentinel.datasource.converter.XmlConverter;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class SentinelConverterTests {
private ObjectMapper objectMapper = new ObjectMapper();
private XmlMapper xmlMapper = new XmlMapper();
@Test
public void testJsonConverter() {
JsonConverter jsonConverter = new JsonConverter(objectMapper, FlowRule.class);
List<FlowRule> flowRules = (List<FlowRule>) jsonConverter
.convert(readFileContent("classpath: flowrule.json"));
assertThat(flowRules.size()).isEqualTo(1);
assertThat(flowRules.get(0).getResource()).isEqualTo("resource");
assertThat(flowRules.get(0).getLimitApp()).isEqualTo("default");
assertThat(String.valueOf(flowRules.get(0).getCount())).isEqualTo("1.0");
assertThat(flowRules.get(0).getControlBehavior())
.isEqualTo(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
assertThat(flowRules.get(0).getStrategy())
.isEqualTo(RuleConstant.STRATEGY_DIRECT);
assertThat(flowRules.get(0).getGrade()).isEqualTo(RuleConstant.FLOW_GRADE_QPS);
}
@Test
public void testConverterEmptyContent() {
JsonConverter jsonConverter = new JsonConverter(objectMapper, FlowRule.class);
List<FlowRule> flowRules = (List<FlowRule>) jsonConverter.convert("");
assertThat(flowRules.size()).isEqualTo(0);
}
@Test(expected = RuntimeException.class)
public void testConverterErrorFormat() {
JsonConverter jsonConverter = new JsonConverter(objectMapper, FlowRule.class);
jsonConverter.convert(readFileContent("classpath: flowrule-errorformat.json"));
}
@Test(expected = RuntimeException.class)
public void testConverterErrorContent() {
JsonConverter jsonConverter = new JsonConverter(objectMapper, FlowRule.class);
jsonConverter.convert(readFileContent("classpath: flowrule-errorcontent.json"));
}
@Test
public void testXmlConverter() {
XmlConverter jsonConverter = new XmlConverter(xmlMapper, FlowRule.class);
List<FlowRule> flowRules = (List<FlowRule>) jsonConverter
.convert(readFileContent("classpath: flowrule.xml"));
assertThat(flowRules.size()).isEqualTo(2);
assertThat(flowRules.get(0).getResource()).isEqualTo("resource");
assertThat(flowRules.get(0).getLimitApp()).isEqualTo("default");
assertThat(String.valueOf(flowRules.get(0).getCount())).isEqualTo("1.0");
assertThat(flowRules.get(0).getControlBehavior())
.isEqualTo(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
assertThat(flowRules.get(0).getStrategy())
.isEqualTo(RuleConstant.STRATEGY_DIRECT);
assertThat(flowRules.get(0).getGrade()).isEqualTo(RuleConstant.FLOW_GRADE_QPS);
assertThat(flowRules.get(1).getResource()).isEqualTo("test");
assertThat(flowRules.get(1).getLimitApp()).isEqualTo("default");
assertThat(String.valueOf(flowRules.get(1).getCount())).isEqualTo("1.0");
assertThat(flowRules.get(1).getControlBehavior())
.isEqualTo(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
assertThat(flowRules.get(1).getStrategy())
.isEqualTo(RuleConstant.STRATEGY_DIRECT);
assertThat(flowRules.get(1).getGrade()).isEqualTo(RuleConstant.FLOW_GRADE_QPS);
}
private String readFileContent(String file) {
try {
return FileUtils.readFileToString(
ResourceUtils.getFile(StringUtils.trimAllWhitespace(file)));
}
catch (IOException e) {
return "";
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2013-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
*
* https://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 com.alibaba.cloud.sentinel.datasource;
import com.alibaba.cloud.sentinel.datasource.converter.XmlConverter;
import com.alibaba.cloud.sentinel.datasource.factorybean.ZookeeperDataSourceFactoryBean;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
*/
public class ZookeeperDataSourceFactoryBeanTests {
private String dataId = "dataId";
private String groupId = "groupId";
private String serverAddr = "localhost:2181";
private String path = "/sentinel";
@Test
public void testZKWithoutPathFactoryBean() throws Exception {
ZookeeperDataSourceFactoryBean factoryBean = spy(
ZookeeperDataSourceFactoryBean.class);
Converter converter = mock(XmlConverter.class);
ZookeeperDataSource zookeeperDataSource = mock(ZookeeperDataSource.class);
factoryBean.setConverter(converter);
factoryBean.setDataId(dataId);
factoryBean.setGroupId(groupId);
factoryBean.setServerAddr(serverAddr);
when(zookeeperDataSource.readSource()).thenReturn("{}");
doReturn(zookeeperDataSource).when(factoryBean).getObject();
assertThat(factoryBean.getObject()).isEqualTo(zookeeperDataSource);
assertThat(factoryBean.getObject().readSource()).isEqualTo("{}");
assertThat(factoryBean.getDataId()).isEqualTo(dataId);
assertThat(factoryBean.getConverter()).isEqualTo(converter);
assertThat(factoryBean.getGroupId()).isEqualTo(groupId);
assertThat(factoryBean.getServerAddr()).isEqualTo(serverAddr);
}
@Test
public void testZKWithPathFactoryBean() throws Exception {
ZookeeperDataSourceFactoryBean factoryBean = spy(
ZookeeperDataSourceFactoryBean.class);
Converter converter = mock(XmlConverter.class);
ZookeeperDataSource zookeeperDataSource = mock(ZookeeperDataSource.class);
factoryBean.setConverter(converter);
factoryBean.setPath(path);
factoryBean.setServerAddr(serverAddr);
when(zookeeperDataSource.readSource()).thenReturn("{}");
doReturn(zookeeperDataSource).when(factoryBean).getObject();
assertThat(factoryBean.getObject()).isEqualTo(zookeeperDataSource);
assertThat(factoryBean.getObject().readSource()).isEqualTo("{}");
assertThat(factoryBean.getConverter()).isEqualTo(converter);
assertThat(factoryBean.getPath()).isEqualTo(path);
assertThat(factoryBean.getServerAddr()).isEqualTo(serverAddr);
}
}

View File

@@ -0,0 +1,11 @@
[
{
"test": 1,
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]

View File

@@ -0,0 +1,10 @@
[
{
"resource": "resource",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}==
]

View File

@@ -0,0 +1,10 @@
[
{
"resource": "resource",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Rules>
<FlowRule>
<resource>resource</resource>
<controlBehavior>0</controlBehavior>
<count>1</count>
<grade>1</grade>
<limitApp>default</limitApp>
<strategy>0</strategy>
</FlowRule>
<FlowRule>
<resource>test</resource>
<controlBehavior>0</controlBehavior>
<count>1</count>
<grade>1</grade>
<limitApp>default</limitApp>
<strategy>0</strategy>
</FlowRule>
</Rules>