mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge remote-tracking branch 'upstream/master'
# Conflicts: # spring-cloud-alibaba-docs/src/main/asciidoc-zh/sentinel.adoc # spring-cloud-alibaba-docs/src/main/asciidoc/sentinel.adoc
This commit is contained in:
commit
2fdeeec3ff
@ -24,7 +24,7 @@ jobs:
|
||||
- ~/.m2
|
||||
- run:
|
||||
name: "Running build"
|
||||
command: ./mvnw -Pspring -Pdocs clean install cobertura:cobertura -U -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
command: ./mvnw -Pspring -Pdocs clean install -U -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
- run:
|
||||
name: "Aggregate test results"
|
||||
when: always
|
||||
|
61
pom.xml
61
pom.xml
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.0.4.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
@ -66,10 +66,10 @@
|
||||
|
||||
<properties>
|
||||
<!-- Dependency Versions -->
|
||||
<spring-cloud-commons.version>2.0.2.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.2.RELEASE</spring-cloud-netflix.version>
|
||||
<spring-cloud-openfeign.version>2.0.2.RELEASE</spring-cloud-openfeign.version>
|
||||
<spring-cloud-bus.version>2.0.0.RELEASE</spring-cloud-bus.version>
|
||||
<spring-cloud-commons.version>2.1.0.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.1.0.RELEASE</spring-cloud-netflix.version>
|
||||
<spring-cloud-openfeign.version>2.1.0.RELEASE</spring-cloud-openfeign.version>
|
||||
<spring-cloud-bus.version>2.1.0.RELEASE</spring-cloud-bus.version>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<javax-servlet-api>3.0</javax-servlet-api>
|
||||
@ -81,8 +81,7 @@
|
||||
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<cobertura.version>2.1.1</cobertura.version>
|
||||
<cobertura-maven-plugin.version>2.7</cobertura-maven-plugin.version>
|
||||
<jacoco.version>0.7.9</jacoco.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
@ -166,25 +165,10 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.cobertura</groupId>
|
||||
<artifactId>cobertura-runtime</artifactId>
|
||||
<version>${cobertura.version}</version>
|
||||
<scope>provided</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@ -208,30 +192,25 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>${cobertura-maven-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>5.0.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
<configuration>
|
||||
<quiet>true</quiet>
|
||||
<formats>
|
||||
<format>html</format>
|
||||
<format>xml</format>
|
||||
</formats>
|
||||
<check/>
|
||||
<check />
|
||||
<destFile>target/coverage-reports/jacoco-unit.exec</destFile>
|
||||
<dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>jacoco-initialize</id>
|
||||
<goals>
|
||||
<goal>cobertura</goal>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jacoco-site</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-dependencies-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.0.4.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
@ -17,10 +17,10 @@
|
||||
<description>Spring Cloud Alibaba Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<sentinel.version>1.4.1</sentinel.version>
|
||||
<sentinel.version>1.4.2</sentinel.version>
|
||||
<oss.version>3.1.0</oss.version>
|
||||
<fescar.version>0.1.3</fescar.version>
|
||||
<nacos.client.version>0.8.0</nacos.client.version>
|
||||
<nacos.client.version>0.8.1</nacos.client.version>
|
||||
<nacos.config.version>0.8.0</nacos.config.version>
|
||||
<acm.version>1.0.8</acm.version>
|
||||
<ans.version>1.0.1</ans.version>
|
||||
@ -453,26 +453,4 @@
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -49,28 +49,5 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!-- put here your original plugin configuration for the children -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
|
@ -100,7 +100,7 @@ spring:
|
||||
|
||||
### Feign 支持
|
||||
|
||||
Sentinel 适配了 https://github.com/OpenFeign/feign[Feign] 组件。如果想使用,除了引入 `sentinel-starter` 的依赖外还需要 3 个步骤:
|
||||
Sentinel 适配了 https://github.com/OpenFeign/feign[Feign] 组件。如果想使用,除了引入 `sentinel-starter` 的依赖外还需要 2 个步骤:
|
||||
|
||||
* 配置文件打开 sentinel 对 feign 的支持:`feign.sentinel.enabled=true`
|
||||
* 加入 `feign starter` 依赖触发 `sentinel starter` 的配置类生效:
|
||||
@ -110,15 +110,8 @@ Sentinel 适配了 https://github.com/OpenFeign/feign[Feign] 组件。如果想
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
* `feign` 内部的 `loadbalance` 功能依赖 Netflix 的 `ribbon` 模块(如果不使用 `loadbalance` 功能可不引入):
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
这是一个 `FeignClient` 对应的接口:
|
||||
这是一个 `FeignClient` 的简单使用示例:
|
||||
|
||||
```java
|
||||
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
|
||||
@ -142,12 +135,10 @@ class EchoServiceFallback implements EchoService {
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl
|
||||
NOTE: Feign 对应的接口中的资源名策略定义:httpmethod:protocol://requesturl。`@FeignClient` 注解中的所有属性,Sentinel 都做了兼容。
|
||||
|
||||
`EchoService` 接口中方法 `echo` 对应的资源名为 `GET:http://service-provider/echo/{str}`。
|
||||
|
||||
请注意:`@FeignClient` 注解中的所有属性,Sentinel 都做了兼容。
|
||||
|
||||
### RestTemplate 支持
|
||||
|
||||
Spring Cloud Alibaba Sentinel 支持对 `RestTemplate` 的服务调用使用 Sentinel 进行保护,在构造 `RestTemplate` bean的时候需要加上 `@SentinelRestTemplate` 注解。
|
||||
@ -160,14 +151,13 @@ public RestTemplate restTemplate() {
|
||||
}
|
||||
```
|
||||
|
||||
`@SentinelRestTemplate` 注解的参数支持限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)的处理。
|
||||
`@SentinelRestTemplate` 注解的属性支持限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)的处理。
|
||||
|
||||
其中 `blockHandler` 或 `fallback` 对应的方法必须是对应 `blockHandlerClass` 或 `fallbackClass` 中的静态方法。
|
||||
其中 `blockHandler` 或 `fallback` 属性对应的方法必须是对应 `blockHandlerClass` 或 `fallbackClass` 属性中的静态方法。
|
||||
|
||||
该注解对应的方法参数跟 `ClientHttpRequestInterceptor` 接口中的参数一致,并多出了一个 `BlockException` 参数,且返回值是 `ClientHttpResponse`。
|
||||
被限流后如果不继续执行后面的 Http 请求拦截器,则可以通过 `SentinelClientHttpResponse` 的一个实例来自定义被限流后的返回值结果。
|
||||
该方法的参数跟返回值跟 `org.springframework.http.client.ClientHttpRequestInterceptor#interceptor` 方法一致,其中参数多出了一个 `BlockException` 参数用于获取 Sentinel 捕获的异常。
|
||||
|
||||
比如上述 `ExceptionUtil` 的 `handleException` 方法对应的声明如下:
|
||||
比如上述 `@SentinelRestTemplate` 注解中 `ExceptionUtil` 的 `handleException` 属性对应的方法声明如下:
|
||||
|
||||
```java
|
||||
public class ExceptionUtil {
|
||||
@ -177,7 +167,11 @@ public class ExceptionUtil {
|
||||
}
|
||||
```
|
||||
|
||||
`@SentinelRestTemplate` 注解的限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)不强制填写,当被 Sentinel 熔断后,会返回 `RestTemplate request block by sentinel` 信息,或者也可以填写对应的方法自行处理。
|
||||
NOTE: 应用启动的时候会检查 `@SentinelRestTemplate` 注解对应的限流或降级方法是否存在,如不存在会抛出异常
|
||||
|
||||
`@SentinelRestTemplate` 注解的限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)属性不强制填写。
|
||||
|
||||
当使用 `RestTemplate` 调用被 Sentinel 熔断后,会返回 `RestTemplate request block by sentinel` 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 `SentinelClientHttpResponse` 用于构造返回信息。
|
||||
|
||||
Sentinel RestTemplate 限流的资源规则提供两种粒度:
|
||||
|
||||
@ -185,102 +179,49 @@ Sentinel RestTemplate 限流的资源规则提供两种粒度:
|
||||
|
||||
* `schema://host:port`:协议、主机和端口
|
||||
|
||||
NOTE: 以 `https://www.taobao.com/test` 这个 path 为例。对应的资源名有两种粒度,分别是 `https://www.taobao.com` 以及 `https://www.taobao.com/test`
|
||||
NOTE: 以 `https://www.taobao.com/test` 这个 url 为例。对应的资源名有两种粒度,分别是 `https://www.taobao.com` 以及 `https://www.taobao.com/test`
|
||||
|
||||
### 动态数据源支持
|
||||
|
||||
#### 在我们的第一个版本 0.2.0.RELEASE 或 0.1.0.RELEASE 中的使用方式
|
||||
`SentinelProperties` 内部提供了 `TreeMap` 类型的 `datasource` 属性用于配置数据源信息。
|
||||
|
||||
需要3个步骤才可完成数据源的配置:
|
||||
|
||||
* 配置文件中定义数据源信息。比如使用文件:
|
||||
|
||||
.application.properties
|
||||
----
|
||||
spring.cloud.sentinel.datasource.type=file
|
||||
spring.cloud.sentinel.datasource.recommendRefreshMs=3000
|
||||
spring.cloud.sentinel.datasource.bufSize=4056196
|
||||
spring.cloud.sentinel.datasource.charset=utf-8
|
||||
spring.cloud.sentinel.datasource.converter=flowConverter
|
||||
spring.cloud.sentinel.datasource.file=/Users/you/yourrule.json
|
||||
----
|
||||
|
||||
* 创建一个 Converter 类实现 `com.alibaba.csp.sentinel.datasource.Converter` 接口,并且需要在 `ApplicationContext` 中有该类的一个 Bean
|
||||
|
||||
```java
|
||||
@Component("flowConverter")
|
||||
public class JsonFlowRuleListParser implements Converter<String, List<FlowRule>> {
|
||||
@Override
|
||||
public List<FlowRule> convert(String source) {
|
||||
return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这个 Converter 的 bean name 需要跟 `application.properties` 配置文件中的 converter 配置一致
|
||||
|
||||
* 在任意一个 Spring Bean 中定义一个被 `@SentinelDataSource` 注解修饰的 `ReadableDataSource` 属性
|
||||
|
||||
```java
|
||||
@SentinelDataSource("spring.cloud.sentinel.datasource")
|
||||
private ReadableDataSource dataSource;
|
||||
```
|
||||
|
||||
`@SentinelDataSource` 注解的 value 属性表示数据源在 `application.properties` 配置文件中前缀。 该在例子中,前缀为 `spring.cloud.sentinel.datasource` 。
|
||||
|
||||
如果 `ApplicationContext` 中存在超过1个 `ReadableDataSource` bean,那么不会加载这些 `ReadableDataSource` 中的任意一个。 只有在 `ApplicationContext` 存在一个 `ReadableDataSource` 的情况下才会生效。
|
||||
|
||||
如果数据源生效并且规则成功加载,控制台会打印类似如下信息:
|
||||
|
||||
```
|
||||
[Sentinel Starter] load 3 flow rules
|
||||
```
|
||||
|
||||
#### 后续版本的使用方式
|
||||
|
||||
只需要1个步骤就可完成数据源的配置:
|
||||
|
||||
* 直接在 `application.properties` 配置文件中配置数据源信息即可
|
||||
|
||||
比如配置了4个数据源:
|
||||
比如配置 4 个数据源:
|
||||
|
||||
```
|
||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
|
||||
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
|
||||
#spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter
|
||||
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
|
||||
|
||||
spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
|
||||
spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
|
||||
spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
|
||||
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
|
||||
spring.cloud.sentinel.datasource.ds5.apollo.rule-type=param-flow
|
||||
|
||||
```
|
||||
|
||||
这样配置方式参考了 Spring Cloud Stream Binder 的配置,内部使用了 `TreeMap` 进行存储,comparator 为 `String.CASE_INSENSITIVE_ORDER` 。
|
||||
这种配置方式参考了 Spring Cloud Stream Binder 的配置,内部使用了 `TreeMap` 进行存储,comparator 为 `String.CASE_INSENSITIVE_ORDER` 。
|
||||
|
||||
NOTE: d1, ds2, ds3, ds4 是 `ReadableDataSource` 的名字,可随意编写。后面的 `file` ,`zk` ,`nacos` , `apollo` 就是对应具体的数据源。 它们后面的配置就是这些数据源各自的配置。
|
||||
NOTE: d1, ds2, ds3, ds4 是 `ReadableDataSource` 的名字,可随意编写。后面的 `file` ,`zk` ,`nacos` , `apollo` 就是对应具体的数据源。 它们后面的配置就是这些具体数据源各自的配置。
|
||||
|
||||
每种数据源都有两个共同的配置项: `data-type` 和 `converter-class` 。
|
||||
每种数据源都有两个共同的配置项: `data-type`、 `converter-class` 以及 `rule-type`。
|
||||
|
||||
`data-type` 配置项表示 `Converter`,Spring Cloud Alibaba Sentinel 默认提供两种内置的值,分别是 `json` 和 `xml` (不填默认是json)。 如果不想使用内置的 `json` 或 `xml` 这两种 `Converter`,可以填写 `custom` 表示自定义 `Converter`,然后再配置 `converter-class` 配置项,该配置项需要写类的全路径名。
|
||||
`data-type` 配置项表示 `Converter` 类型,Spring Cloud Alibaba Sentinel 默认提供两种内置的值,分别是 `json` 和 `xml` (不填默认是json)。 如果不想使用内置的 `json` 或 `xml` 这两种 `Converter`,可以填写 `custom` 表示自定义 `Converter`,然后再配置 `converter-class` 配置项,该配置项需要写类的全路径名(比如 `spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter`)。
|
||||
|
||||
这两种内置的 `Converter` 只支持解析 json 数组 或 xml 数组。内部解析的时候会自动判断每个 json 对象或xml对象属于哪4种 Sentinel 规则(`FlowRule`,`DegradeRule`,`SystemRule`,`AuthorityRule`, `ParamFlowRule`)。
|
||||
|
||||
比如10个规则数组里解析出5个限流规则和5个降级规则。 这种情况下该数据源不会注册,日志里页会进行警告。
|
||||
|
||||
如果10个规则里有9个限流规则,1个解析报错了。这种情况下日志会警告有个规则格式错误,另外9个限流规则会注册上去。
|
||||
|
||||
这里 json 或 xml 解析用的是 `jackson`。`ObjectMapper` 或 `XmlMapper` 使用默认的配置,遇到不认识的字段会解析报错。 因为不这样做的话限流 json 也会解析成 系统规则(系统规则所有的配置都有默认值),所以需要这样严格解析。
|
||||
|
||||
当然还有一种情况是 json 对象或 xml 对象可能会匹配上所有4种规则(比如json对象里只配了 `resource` 字段,那么会匹配上4种规则),这种情况下日志里会警告,并且过滤掉这个对象。
|
||||
|
||||
用户使用这种配置的时候只需要填写正确的json或xml就行,有任何不合理的信息都会在日志里打印出来。
|
||||
`rule-type` 配置表示该数据源中的规则属于哪种类型的规则(`flow`,`degrade`,`authority`,`system`, `param-flow`)。
|
||||
|
||||
如果数据源生效并且规则成功加载,控制台会打印类似如下信息:
|
||||
|
||||
@ -289,6 +230,8 @@ NOTE: d1, ds2, ds3, ds4 是 `ReadableDataSource` 的名字,可随意编写。
|
||||
[Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule
|
||||
```
|
||||
|
||||
NOTE: 当某个数据源规则信息加载失败的情况下,不会影响应用的启动,会在日志中打印出错误信息。
|
||||
|
||||
NOTE: 默认情况下,xml 格式是不支持的。需要添加 `jackson-dataformat-xml` 依赖后才会自动生效。
|
||||
|
||||
关于 Sentinel 动态数据源的实现原理,参考: https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95[动态规则扩展]
|
||||
@ -300,6 +243,8 @@ NOTE: 默认情况下,xml 格式是不支持的。需要添加 `jackson-datafo
|
||||
* Spring Boot 1.x 中添加配置 `management.security.enabled=false`。暴露的 endpoint 路径为 `/sentinel`
|
||||
* Spring Boot 2.x 中添加配置 `management.endpoints.web.exposure.include=*`。暴露的 endpoint 路径为 `/actuator/sentinel`
|
||||
|
||||
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
|
||||
|
||||
### More
|
||||
|
||||
下表显示当应用的 `ApplicationContext` 中存在对应的Bean的类型时,会进行的一些操作:
|
||||
@ -310,6 +255,7 @@ NOTE: 默认情况下,xml 格式是不支持的。需要添加 `jackson-datafo
|
||||
^|存在Bean的类型 ^|操作 ^|作用
|
||||
|`UrlCleaner`|`WebCallbackManager.setUrlCleaner(urlCleaner)`|资源清理(资源(比如将满足 /foo/:id 的 URL 都归到 /foo/* 资源下))
|
||||
|`UrlBlockHandler`|`WebCallbackManager.setUrlBlockHandler(urlBlockHandler)`|自定义限流处理逻辑
|
||||
|`RequestOriginParser`|`WebCallbackManager.setRequestOriginParser(requestOriginParser)`|设置来源信息
|
||||
|====
|
||||
|
||||
下表显示 Spring Cloud Alibaba Sentinel 的所有配置信息:
|
||||
@ -322,14 +268,17 @@ NOTE: 默认情况下,xml 格式是不支持的。需要添加 `jackson-datafo
|
||||
|`spring.cloud.sentinel.eager`|取消Sentinel控制台懒加载|false
|
||||
|`spring.cloud.sentinel.transport.port`|应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer|8721
|
||||
|`spring.cloud.sentinel.transport.dashboard`|Sentinel 控制台地址|
|
||||
|`spring.cloud.sentinel.transport.heartbeatIntervalMs`|应用与Sentinel控制台的心跳间隔时间|
|
||||
|`spring.cloud.sentinel.transport.heartbeat-interval-ms`|应用与Sentinel控制台的心跳间隔时间|
|
||||
|`spring.cloud.sentinel.transport.client-ip`|客户端IP|
|
||||
|`spring.cloud.sentinel.filter.order`|Servlet Filter的加载顺序。Starter内部会构造这个filter|Integer.MIN_VALUE
|
||||
|`spring.cloud.sentinel.filter.spring.path-patterns`|数据类型是数组。表示Servlet Filter的url pattern集合|/*
|
||||
|`spring.cloud.sentinel.filter.url-patterns`|数据类型是数组。表示Servlet Filter的url pattern集合|/*
|
||||
|`spring.cloud.sentinel.metric.charset`|metric文件字符集|UTF-8
|
||||
|`spring.cloud.sentinel.metric.fileSingleSize`|Sentinel metric 单个文件的大小|
|
||||
|`spring.cloud.sentinel.metric.fileTotalCount`|Sentinel metric 总文件数量|
|
||||
|`spring.cloud.sentinel.metric.file-single-size`|Sentinel metric 单个文件的大小|
|
||||
|`spring.cloud.sentinel.metric.file-total-count`|Sentinel metric 总文件数量|
|
||||
|`spring.cloud.sentinel.log.dir`|Sentinel 日志文件所在的目录|
|
||||
|`spring.cloud.sentinel.log.switch-pid`|Sentinel 日志文件名是否需要带上pid|false
|
||||
|`spring.cloud.sentinel.servlet.blockPage`| 自定义的跳转 URL,当请求被限流时会自动跳转至设定好的 URL |
|
||||
|`spring.cloud.sentinel.flow.coldFactor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8[冷启动因子] |3
|
||||
|`spring.cloud.sentinel.servlet.block-page`| 自定义的跳转 URL,当请求被限流时会自动跳转至设定好的 URL |
|
||||
|`spring.cloud.sentinel.flow.cold-factor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8[冷启动因子] |3
|
||||
|====
|
||||
|
||||
NOTE: 请注意。这些配置只有在 Servlet 环境下才会生效,RestTemplate 和 Feign 针对这些配置都无法生效
|
@ -100,7 +100,7 @@ For more information about Sentinel dashboard, please refer to https://github.co
|
||||
|
||||
### Feign Support
|
||||
|
||||
Sentinel is compatible with the https://github.com/OpenFeign/feign[Feign] component. To use it, in addition to introducing the `sentinel-starter` dependency, complete the following 3 steps:
|
||||
Sentinel is compatible with the https://github.com/OpenFeign/feign[Feign] component. To use it, in addition to introducing the `sentinel-starter` dependency, complete the following 2 steps:
|
||||
|
||||
* Enable the Sentinel support for feign in the properties file. `feign.sentinel.enabled=true`
|
||||
* Add the `feign starter` dependency to trigger and enable `sentinel starter`:
|
||||
@ -110,15 +110,8 @@ Sentinel is compatible with the https://github.com/OpenFeign/feign[Feign] compon
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
* The `loadbalance` in `feign` is dependent on the `ribbon` module of Netflix (You do not need to introduce it if `loadbalance` is not used):
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
This is an interface for `FeignClient`:
|
||||
This is a simple usage of `FeignClient`:
|
||||
|
||||
```java
|
||||
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
|
||||
@ -142,12 +135,10 @@ class EchoServiceFallback implements EchoService {
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: The resource name policy in the corresponding interface of Feign is:httpmethod:protocol://requesturl
|
||||
NOTE: The resource name policy in the corresponding interface of Feign is:httpmethod:protocol://requesturl. All the attributes in the `@FeignClient` annotation is supported by Sentinel.
|
||||
|
||||
The corresponding resource name of the `echo` method in the `EchoService` interface is `GET:http://service-provider/echo/{str}`.
|
||||
|
||||
Note: All the attributes in the `@FeignClient` annotation is supported by Sentinel.
|
||||
|
||||
### RestTemplate Support
|
||||
|
||||
Spring Cloud Alibaba Sentinel supports the protection of `RestTemplate` service calls using Sentinel. To do this, you need to add the `@SentinelRestTemplate` annotation when constructing the `RestTemplate` bean.
|
||||
@ -160,14 +151,13 @@ public RestTemplate restTemplate() {
|
||||
}
|
||||
```
|
||||
|
||||
The parameter of the `@SentinelRestTemplate` annotation support flow control(`blockHandler`, `blockHandlerClass`) and circuit breaking(`fallback`, `fallbackClass`).
|
||||
The attribute of the `@SentinelRestTemplate` annotation support flow control(`blockHandler`, `blockHandlerClass`) and circuit breaking(`fallback`, `fallbackClass`).
|
||||
|
||||
==
|
||||
|
||||
The `blockHandler` or `fallback` is the static method of `blockHandlerClass` or `fallbackClass`.
|
||||
|
||||
The parameter of method in `@SentinelRestTemplate` is same as `ClientHttpRequestInterceptor`, but it has one more parameter `BlockException` and its value of return type should be `ClientHttpResponse`.
|
||||
If you do not continue to execute the following Http request interceptor after being restricted, you can use the instance of `SentinelClientHttpResponse` to customize the return value result after the current limit.
|
||||
The parameter and return value of method in `@SentinelRestTemplate` is same as `org.springframework.http.client.ClientHttpRequestInterceptor#interceptor`, but it has one more parameter `BlockException` to catch the exception by Sentinel.
|
||||
|
||||
The method signature of `handleException` in `ExceptionUtil` above should be like this:
|
||||
|
||||
@ -179,7 +169,11 @@ public class ExceptionUtil {
|
||||
}
|
||||
```
|
||||
|
||||
It will return `RestTemplate request block by sentinel` when you do not write any flow control(`blockHandler`, `blockHandlerClass`) configuration or circuit breaking configuration(`fallback`, `fallbackClass`), you can override it by using your own method.
|
||||
NOTE: When the application starts, it will check if the `@SentinelRestTemplate` annotation corresponding to the flow control or circuit breaking method exists, if it does not exist, it will throw an exception.
|
||||
|
||||
The attribute of the `@SentinelRestTemplate` annotation is optional.
|
||||
|
||||
It will return `RestTemplate request block by sentinel` when you using `RestTemplate` blocked by Sentinel. You can override it by your own logic. We provide `SentinelClientHttpResponse` to handle the response.
|
||||
|
||||
Sentinel RestTemplate provides two granularities for resource rate limiting:
|
||||
|
||||
@ -191,98 +185,44 @@ NOTE: Take `https://www.taobao.com/test` as an example. The corresponding resour
|
||||
|
||||
### Dynamic Data Source Support
|
||||
|
||||
#### The usage of our first version 0.2.0.RELEASE or 0.1.0.RELEASE
|
||||
|
||||
you need to complete the following 3 steps to configure your data source.
|
||||
|
||||
* Define the data source information in your properties file. For example, you can use:
|
||||
|
||||
.application.properties
|
||||
----
|
||||
spring.cloud.sentinel.datasource.type=file
|
||||
spring.cloud.sentinel.datasource.recommendRefreshMs=3000
|
||||
spring.cloud.sentinel.datasource.bufSize=4056196
|
||||
spring.cloud.sentinel.datasource.charset=utf-8
|
||||
spring.cloud.sentinel.datasource.converter=flowConverter
|
||||
spring.cloud.sentinel.datasource.file=/Users/you/yourrule.json
|
||||
----
|
||||
|
||||
* Create a Converter class to implement the `com.alibaba.csp.sentinel.datasource.Converter` interface, and you need to have a bean of this class in `ApplicationContext`.
|
||||
|
||||
```java
|
||||
@Component("flowConverter")
|
||||
public class JsonFlowRuleListParser implements Converter<String, List<FlowRule>> {
|
||||
@Override
|
||||
public List<FlowRule> convert(String source) {
|
||||
return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The bean name of this Converter needs to be the same with the converter in the `application.properties` file.
|
||||
|
||||
* Define a `ReadableDataSource` attribute that is modified by the `@SentinelDataSource` annotation in any Spring Bean `@SentinelDataSource`.
|
||||
|
||||
```java
|
||||
@SentinelDataSource("spring.cloud.sentinel.datasource")
|
||||
private ReadableDataSource dataSource;
|
||||
```
|
||||
|
||||
The value attribute of `@SentinelDataSource` means that the data source is in the prefix of the `application.properties` file. In this example, the prefix is `spring.cloud.sentinel.datasource`.
|
||||
|
||||
If there are over 1 `ReadableDataSource` beans in `ApplicationContext`, then none of the data sources in `ReadableDataSource` will be loaded. It takes effect only when there is only 1 `ReadableDataSource` in `ApplicationContext`.
|
||||
|
||||
If the data source takes effect and is loaded successfully, the dashboard will print information as shown below:
|
||||
|
||||
```
|
||||
[Sentinel Starter] load 3 flow rules
|
||||
```
|
||||
|
||||
#### The usage after first version
|
||||
|
||||
You only need to complete 1 step to configure your data source:
|
||||
|
||||
* Configure your data source in the `application.properties` file directly.
|
||||
`SentinelProperties` provide `datasource` attribute to configure datasource.
|
||||
|
||||
For example, 4 data sources are configures:
|
||||
|
||||
```
|
||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
|
||||
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
|
||||
#spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter
|
||||
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
|
||||
|
||||
spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
|
||||
spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
|
||||
spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
|
||||
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
|
||||
spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
|
||||
|
||||
spring.cloud.sentinel.datasource.ds5.apollo.rule-type=param-flow
|
||||
```
|
||||
|
||||
This method follows the configuration of Spring Cloud Stream Binder. `TreeMap` is used for storage internally, and comparator is `String.CASE_INSENSITIVE_ORDER`.
|
||||
|
||||
NOTE: d1, ds2, ds3, ds4 are the names of `ReadableDataSource`, and can be coded as you like. The `file`, `zk`, `nacos` , `apollo` refer to the specific data sources. The configurations following them are the specific configurations of these data sources respecitively.
|
||||
|
||||
Every data source has two common configuration items: `data-type` and `converter-class`.
|
||||
Every data source has 3 common configuration items: `data-type`, `converter-class` and `rule-type`.
|
||||
|
||||
`data-type` refers to `Converter`. Spring Cloud Alibaba Sentinel provides two embedded values by defaul: `json` and `xml` (the default is json if not specified). If you do not want to use the embedded `json` or `xml` `Converter`, you can also fill in `custom` to indicate that you will define your own `Converter`, and then configure the `converter-class`. You need to specify the full path of the class for this configuration.
|
||||
`data-type` refers to `Converter`. Spring Cloud Alibaba Sentinel provides two embedded values by default: `json` and `xml` (the default is json if not specified). If you do not want to use the embedded `json` or `xml` `Converter`, you can also fill in `custom` to indicate that you will define your own `Converter`, and then configure the `converter-class`. You need to specify the full path of the class for this configuration.
|
||||
|
||||
The two embedded `Converter` only supports parsing the Json array or XML array. Sentinel will determine automatically which of the 4 Sentinel rules that the Json or XML objext belongs to(`FlowRule`, `DegradeRule`, `SystemRule`, `AuthorityRule`, `ParamFlowRule`).
|
||||
|
||||
For example, if 5 rate limiting rules and 5 degradation rules in the 10 rule arrays, then the data source will not be registered, and there will be warnings in the logs.
|
||||
|
||||
If there are 9 rate limiting rules among the 10 arrays, and 1 error parsing the 10th array, then there will be warning in the log indicating that there is error in one of the rules, while the other 9 rules will be registered.
|
||||
|
||||
Here `jackson` is used to parse the Json or XML arrays. `ObjectMapper` or `XmlMapper` uses the default configuration and will report error if there are unrecognized fields. The reason behind this logic is that without this strict parsing, Json will also be parsed as system rules(all system rules have default values).
|
||||
|
||||
In another case, the Json or XML object might match all of the 4 rules(for example, if only the `resource` field is configured in the Json object, then it will match all 4 rules). In this case, there will be warnings in the log, and this object will be filtered.
|
||||
|
||||
When you use this configuration, you only need to fill in the Json or XML correctly, and any of the unreasonable information will be printed in the log.
|
||||
`rule-type` refers to the rule type in datasource(`flow`, `degrade`, `authority`, `system`, `param-flow`).
|
||||
|
||||
If the data source takes effect and is loaded successfully, the dashboard will print information as shown below:
|
||||
|
||||
@ -302,6 +242,8 @@ Before you use the Endpoint feature, please add the `spring-boot-starter-actuat
|
||||
* Add `management.security.enabled=false` in Spring Boot 1.x. The exposed endpoint path is `/sentinel`.
|
||||
* Add `management.endpoints.web.exposure.include=*` in Spring Boot 2.x. The exposed endpoint path is `/actuator/sentinel`.
|
||||
|
||||
The information exposed in Sentinel Endpoint is very useful. It includes all the rules of the current application, the log directory, the IP of the current instance, the Sentinel Dashboard address, the Block Page, the heartbeat frequency of the application and the Sentinel Dashboard, and so on.
|
||||
|
||||
### More
|
||||
|
||||
The following table shows that when there are corresponding bean types in `ApplicationContext`, some actions will be taken:
|
||||
@ -312,6 +254,7 @@ The following table shows that when there are corresponding bean types in `Appli
|
||||
^|Existing Bean Type ^|Action ^|Function
|
||||
|`UrlCleaner`|`WebCallbackManager.setUrlCleaner(urlCleaner)`|Resource cleaning(resource(for example, classify all URLs of /foo/:id to the /foo/* resource))
|
||||
|`UrlBlockHandler`|`WebCallbackManager.setUrlBlockHandler(urlBlockHandler)`|Customize rate limiting logic
|
||||
|`RequestOriginParser`|`WebCallbackManager.setRequestOriginParser(requestOriginParser)`|Setting the origin
|
||||
|====
|
||||
|
||||
The following table shows all the configurations of Spring Cloud Alibaba Sentinel:
|
||||
@ -325,13 +268,16 @@ The following table shows all the configurations of Spring Cloud Alibaba Sentine
|
||||
|`spring.cloud.sentinel.transport.port`|Port for the application to interact with Sentinel dashboard. An HTTP Server which uses this port will be started in the application|8721
|
||||
|`spring.cloud.sentinel.transport.dashboard`|Sentinel dashboard address|
|
||||
|`spring.cloud.sentinel.transport.heartbeatIntervalMs`|Hearbeat interval between the application and Sentinel dashboard|
|
||||
|`spring.cloud.sentinel.transport.client-ip`|Client IP|
|
||||
|`spring.cloud.sentinel.filter.order`|Loading order of Servlet Filter. The filter will be constructed in the Starter|Integer.MIN_VALUE
|
||||
|`spring.cloud.sentinel.filter.spring.path-patterns`|Data type is array. Refers to the collection of Servlet Filter ULR patterns|/*
|
||||
|`spring.cloud.sentinel.filter.url-patterns`|Data type is array. Refers to the collection of Servlet Filter ULR patterns|/*
|
||||
|`spring.cloud.sentinel.metric.charset`|metric file character set|UTF-8
|
||||
|`spring.cloud.sentinel.metric.fileSingleSize`|Sentinel metric single file size|
|
||||
|`spring.cloud.sentinel.metric.fileTotalCount`|Sentinel metric total file number|
|
||||
|`spring.cloud.sentinel.log.dir`|Directory of Sentinel log files|
|
||||
|`spring.cloud.sentinel.log.switch-pid`|If PID is required for Sentinel log file names|false
|
||||
|`spring.cloud.sentinel.servlet.blockPage`| Customized redirection URL. When rate limited, the request will be redirected to the pre-defined URL |
|
||||
|`spring.cloud.sentinel.flow.coldFactor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8[冷启动因子] |3
|
||||
|`spring.cloud.sentinel.flow.coldFactor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8[ColdFactor] |3
|
||||
|====
|
||||
|
||||
NOTE: These configurations will only take effect in servlet environment. RestTemplate and Feign will not take effect for these configurations.
|
@ -23,28 +23,11 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -29,25 +29,4 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -25,25 +25,4 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -27,28 +27,11 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -34,14 +34,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -55,15 +47,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -1,2 +1,4 @@
|
||||
spring.application.name=nacos-config-example
|
||||
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
|
||||
spring.application.name=sca-nacos-config
|
||||
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
|
||||
spring.cloud.nacos.config.shared-data-ids=base-common.properties,common.properties
|
||||
spring.cloud.nacos.config.refreshable-dataids=common.properties
|
@ -44,18 +44,9 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -69,15 +60,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -29,18 +29,9 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -54,15 +45,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -20,26 +20,4 @@
|
||||
<module>nacos-discovery-consumer-example</module>
|
||||
<module>nacos-discovery-provider-example</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -35,14 +35,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -56,15 +48,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -33,14 +33,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -54,15 +46,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -20,26 +20,4 @@
|
||||
<module>nacos-gateway-discovery-example</module>
|
||||
<module>nacos-gateway-provider-example</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -33,14 +33,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -54,15 +46,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -40,14 +40,6 @@
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@ -57,16 +49,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -40,14 +40,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -61,15 +53,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -27,28 +27,11 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -51,14 +51,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -72,15 +64,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -16,14 +16,6 @@
|
||||
<description>api for sentinel dubbo example</description>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@ -33,15 +25,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -40,14 +40,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -61,15 +53,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -39,14 +39,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -60,15 +52,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -35,14 +35,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -56,15 +48,6 @@
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -65,6 +65,11 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@ -75,6 +80,19 @@
|
||||
<artifactId>spring-cloud-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.powermock.modules.test.powermockito/powermock-modules-test-powermockito -->
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.alibaba.nacos;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceLocator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -34,6 +35,7 @@ public class NacosConfigBootstrapConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
|
||||
public NacosPropertySourceLocator nacosPropertySourceLocator(
|
||||
NacosConfigProperties nacosConfigProperties) {
|
||||
return new NacosPropertySourceLocator(nacosConfigProperties);
|
||||
|
@ -18,8 +18,9 @@ package org.springframework.cloud.alibaba.nacos;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -49,9 +50,15 @@ import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
|
||||
@ConfigurationProperties(NacosConfigProperties.PREFIX)
|
||||
public class NacosConfigProperties {
|
||||
|
||||
static final String PREFIX = "spring.cloud.nacos.config";
|
||||
public static final String PREFIX = "spring.cloud.nacos.config";
|
||||
|
||||
private static final Log log = LogFactory.getLog(NacosConfigProperties.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosConfigProperties.class);
|
||||
|
||||
/**
|
||||
* whether to enable nacos config.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* nacos config server address
|
||||
@ -145,6 +152,14 @@ public class NacosConfigProperties {
|
||||
|
||||
// todo sts support
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getServerAddr() {
|
||||
return serverAddr;
|
||||
}
|
||||
@ -322,16 +337,17 @@ public class NacosConfigProperties {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NacosConfigProperties{" + "serverAddr='" + serverAddr + '\''
|
||||
+ ", encode='" + encode + '\'' + ", group='" + group + '\''
|
||||
+ ", sharedDataids='" + this.sharedDataids + '\''
|
||||
+ ", refreshableDataids='" + this.refreshableDataids + '\'' + ", prefix='"
|
||||
+ prefix + '\'' + ", fileExtension='" + fileExtension + '\''
|
||||
+ ", timeout=" + timeout + ", endpoint='" + endpoint + '\''
|
||||
+ ", namespace='" + namespace + '\'' + ", accessKey='" + accessKey + '\''
|
||||
+ ", secretKey='" + secretKey + '\'' + ", contextPath='" + contextPath
|
||||
+ '\'' + ", clusterName='" + clusterName + '\'' + ", name='" + name + '\''
|
||||
+ ", activeProfiles=" + Arrays.toString(activeProfiles) + '}';
|
||||
return "NacosConfigProperties{" + "enabled=" + enabled + ", serverAddr='"
|
||||
+ serverAddr + '\'' + ", encode='" + encode + '\'' + ", group='" + group
|
||||
+ '\'' + ", prefix='" + prefix + '\'' + ", fileExtension='"
|
||||
+ fileExtension + '\'' + ", timeout=" + timeout + ", endpoint='"
|
||||
+ endpoint + '\'' + ", namespace='" + namespace + '\'' + ", accessKey='"
|
||||
+ accessKey + '\'' + ", secretKey='" + secretKey + '\''
|
||||
+ ", contextPath='" + contextPath + '\'' + ", clusterName='" + clusterName
|
||||
+ '\'' + ", name='" + name + '\'' + ", activeProfiles="
|
||||
+ Arrays.toString(activeProfiles) + ", sharedDataids='" + sharedDataids
|
||||
+ '\'' + ", refreshableDataids='" + refreshableDataids + '\''
|
||||
+ ", extConfig=" + extConfig + '}';
|
||||
}
|
||||
|
||||
public ConfigService configServiceInstance() {
|
||||
@ -354,11 +370,8 @@ public class NacosConfigProperties {
|
||||
return configService;
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error(
|
||||
"create config service error!properties=" + this.toString() + ",e=,",
|
||||
e);
|
||||
log.error("create config service error!properties={},e=,", this, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosPropertySourceRepository {
|
||||
|
||||
@ -45,6 +46,7 @@ public class NacosPropertySourceRepository {
|
||||
}
|
||||
|
||||
public static NacosPropertySource getNacosPropertySource(String dataId) {
|
||||
|
||||
return nacosPropertySourceRepository.get(dataId);
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ package org.springframework.cloud.alibaba.nacos.client;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosPropertySourceRepository;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
@ -37,7 +38,8 @@ import java.util.Properties;
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosPropertySourceBuilder {
|
||||
private static final Log log = LogFactory.getLog(NacosPropertySourceBuilder.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosPropertySourceBuilder.class);
|
||||
private static final Properties EMPTY_PROPERTIES = new Properties();
|
||||
|
||||
private ConfigService configService;
|
||||
@ -101,11 +103,10 @@ public class NacosPropertySourceBuilder {
|
||||
}
|
||||
}
|
||||
catch (NacosException e) {
|
||||
log.error("get data from Nacos error,dataId:" + dataId + ", ", e);
|
||||
log.error("get data from Nacos error,dataId:{}, ", dataId, e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("parse data from Nacos error,dataId:" + dataId + ",data:" + data
|
||||
+ ",", e);
|
||||
log.error("parse data from Nacos error,dataId:{},data:{},", dataId, data, e);
|
||||
}
|
||||
return EMPTY_PROPERTIES;
|
||||
}
|
||||
|
@ -17,8 +17,9 @@
|
||||
package org.springframework.cloud.alibaba.nacos.client;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosConfigProperties;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosPropertySourceRepository;
|
||||
import org.springframework.cloud.alibaba.nacos.refresh.NacosContextRefresher;
|
||||
@ -39,7 +40,8 @@ import java.util.List;
|
||||
@Order(0)
|
||||
public class NacosPropertySourceLocator implements PropertySourceLocator {
|
||||
|
||||
private static final Log log = LogFactory.getLog(NacosPropertySourceLocator.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosPropertySourceLocator.class);
|
||||
private static final String NACOS_PROPERTY_SOURCE_NAME = "NACOS";
|
||||
private static final String SEP1 = "-";
|
||||
private static final String DOT = ".";
|
||||
@ -182,19 +184,19 @@ public class NacosPropertySourceLocator implements PropertySourceLocator {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkDataIdFileExtension(String[] sharedDataIdArry) {
|
||||
private static void checkDataIdFileExtension(String[] dataIdArray) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < sharedDataIdArry.length; i++) {
|
||||
for (int i = 0; i < dataIdArray.length; i++) {
|
||||
boolean isLegal = false;
|
||||
for (String fileExtension : SUPPORT_FILE_EXTENSION) {
|
||||
if (sharedDataIdArry[i].indexOf(fileExtension) > 0) {
|
||||
if (dataIdArray[i].indexOf(fileExtension) > 0) {
|
||||
isLegal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add tips
|
||||
if (!isLegal) {
|
||||
stringBuilder.append(sharedDataIdArry[i] + ",");
|
||||
stringBuilder.append(dataIdArray[i] + ",");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,9 @@ package org.springframework.cloud.alibaba.nacos.refresh;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosPropertySourceRepository;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySource;
|
||||
@ -51,7 +52,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
public class NacosContextRefresher
|
||||
implements ApplicationListener<ApplicationReadyEvent>, ApplicationContextAware {
|
||||
|
||||
private final static Log log = LogFactory.getLog(NacosContextRefresher.class);
|
||||
private final static Logger log = LoggerFactory
|
||||
.getLogger(NacosContextRefresher.class);
|
||||
|
||||
private static final AtomicLong REFRESH_COUNT = new AtomicLong(0);
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.nacos;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigEndpoint;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-01-17 2:25 PM
|
||||
*/
|
||||
public class EndpointTests extends NacosPowerMockitBaseTests {
|
||||
|
||||
@Test
|
||||
public void nacosConfigEndpoint() {
|
||||
|
||||
NacosConfigEndpoint nacosConfigEndpoint = super.context
|
||||
.getBean(NacosConfigEndpoint.class);
|
||||
assertThat(nacosConfigEndpoint != null).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointInvoke() {
|
||||
NacosConfigEndpoint nacosConfigEndpoint = this.context
|
||||
.getBean(NacosConfigEndpoint.class);
|
||||
assertThat(nacosConfigEndpoint.invoke() != null).isEqualTo(true);
|
||||
}
|
||||
}
|
@ -16,59 +16,52 @@
|
||||
|
||||
package org.springframework.cloud.alibaba.nacos;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceLocator;
|
||||
import org.springframework.cloud.alibaba.nacos.refresh.NacosRefreshProperties;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScope;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosConfigAutoConfigurationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.context = new SpringApplicationBuilder(
|
||||
NacosConfigBootstrapConfiguration.class,
|
||||
NacosConfigAutoConfiguration.class, TestConfiguration.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.run("--spring.cloud.nacos.config.name=myapp",
|
||||
"--spring.cloud.config.enabled=true",
|
||||
"--spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
||||
"--spring.cloud.nacos.config.prefix=test");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
public class NacosConfigAutoConfigurationTests extends NacosPowerMockitBaseTests {
|
||||
@Test
|
||||
public void testNacosConfigProperties() {
|
||||
|
||||
NacosConfigProperties nacosConfigProperties = this.context.getParent()
|
||||
NacosConfigProperties nacosConfigProperties = context.getParent()
|
||||
.getBean(NacosConfigProperties.class);
|
||||
assertThat(nacosConfigProperties.getFileExtension()).isEqualTo("properties");
|
||||
assertThat(nacosConfigProperties.getPrefix()).isEqualTo("test");
|
||||
assertThat(nacosConfigProperties.getName()).isEqualTo("myapp");
|
||||
assertThat(nacosConfigProperties.getPrefix() == null).isEqualTo(true);
|
||||
assertThat(nacosConfigProperties.getNamespace() == null).isEqualTo(true);
|
||||
assertThat(nacosConfigProperties.getName()).isEqualTo("sca-nacos-config");
|
||||
assertThat(nacosConfigProperties.getServerAddr()).isEqualTo("127.0.0.1:8848");
|
||||
assertThat(nacosConfigProperties.getEncode()).isEqualTo("utf-8");
|
||||
assertThat(nacosConfigProperties.getActiveProfiles())
|
||||
.isEqualTo(new String[] { "develop" });
|
||||
assertThat(nacosConfigProperties.getSharedDataids())
|
||||
.isEqualTo("base-common.properties,common.properties");
|
||||
assertThat(nacosConfigProperties.getRefreshableDataids())
|
||||
.isEqualTo("common.properties");
|
||||
assertThat(nacosConfigProperties.getExtConfig().size()).isEqualTo(3);
|
||||
assertThat(nacosConfigProperties.getExtConfig().get(0).getDataId())
|
||||
.isEqualTo("ext00.yaml");
|
||||
assertThat(nacosConfigProperties.getExtConfig().get(1).getGroup())
|
||||
.isEqualTo("EXT01_GROUP");
|
||||
assertThat(nacosConfigProperties.getExtConfig().get(1).isRefresh())
|
||||
.isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nacosPropertySourceLocator() {
|
||||
NacosPropertySourceLocator nacosPropertySourceLocator = this.context
|
||||
.getBean(NacosPropertySourceLocator.class);
|
||||
PropertySource propertySource = nacosPropertySourceLocator
|
||||
.locate(this.context.getEnvironment());
|
||||
assertThat(propertySource instanceof CompositePropertySource).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -80,18 +73,4 @@ public class NacosConfigAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureBefore(NacosConfigAutoConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Bean
|
||||
ContextRefresher contextRefresher() {
|
||||
return new ContextRefresher(context, new RefreshScope());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,82 +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.nacos;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
public class NacosConfigBootstrapConfigurationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.context = new SpringApplicationBuilder(
|
||||
NacosConfigBootstrapConfiguration.class).web(WebApplicationType.NONE).run(
|
||||
"--spring.cloud.nacos.config.name=myapp",
|
||||
"--spring.cloud.config.enabled=true",
|
||||
"--spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
||||
"--spring.cloud.nacos.config.prefix=test");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNacosPropertySourceLocator() {
|
||||
|
||||
NacosPropertySourceLocator locator = this.context
|
||||
.getBean(NacosPropertySourceLocator.class);
|
||||
Environment environment = this.context.getEnvironment();
|
||||
try {
|
||||
locator.locate(environment);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
Field nacosConfigPropertiesField = ReflectionUtils
|
||||
.findField(NacosPropertySourceLocator.class, "nacosConfigProperties");
|
||||
nacosConfigPropertiesField.setAccessible(true);
|
||||
|
||||
NacosConfigProperties configService = (NacosConfigProperties) ReflectionUtils
|
||||
.getField(nacosConfigPropertiesField, locator);
|
||||
|
||||
assertThat(configService).isNotNull();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.nacos;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigHealthIndicator;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-01-17 2:58 PM
|
||||
*/
|
||||
public class NacosConfigHealthIndicatorTests extends NacosPowerMockitBaseTests {
|
||||
|
||||
@Test
|
||||
public void nacosConfigHealthIndicatorInstance() {
|
||||
NacosConfigHealthIndicator nacosConfigHealthIndicator = this.context
|
||||
.getBean(NacosConfigHealthIndicator.class);
|
||||
|
||||
assertThat(nacosConfigHealthIndicator != null).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHealthCheck() {
|
||||
|
||||
NacosConfigHealthIndicator nacosConfigHealthIndicator = this.context
|
||||
.getBean(NacosConfigHealthIndicator.class);
|
||||
|
||||
Health.Builder builder = Health.up();
|
||||
|
||||
Method method = ReflectionUtils.findMethod(NacosConfigHealthIndicator.class,
|
||||
"doHealthCheck", Health.Builder.class);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
assertThat(method != null).isEqualTo(true);
|
||||
|
||||
try {
|
||||
method.invoke(nacosConfigHealthIndicator, builder);
|
||||
assertThat(builder != null).isEqualTo(true);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.nacos;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.api.support.MethodProxy;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySource;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceBuilder;
|
||||
import org.springframework.cloud.alibaba.nacos.endpoint.NacosConfigEndpointAutoConfiguration;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScope;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-01-17 8:54 PM
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(SpringRunner.class)
|
||||
@PowerMockIgnore({ "javax.management.*", "javax.net.ssl.*" })
|
||||
@PrepareForTest({ NacosPropertySourceBuilder.class })
|
||||
@SpringBootTest(classes = { NacosConfigBootstrapConfiguration.class,
|
||||
NacosConfigEndpointAutoConfiguration.class, NacosConfigAutoConfiguration.class,
|
||||
NacosPowerMockitBaseTests.TestConfiguration.class }, properties = {
|
||||
"spring.application.name=sca-nacos-config",
|
||||
"spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
||||
"spring.cloud.nacos.config.name=sca-nacos-config",
|
||||
// "spring.cloud.nacos.config.refresh.enabled=false",
|
||||
"spring.cloud.nacos.config.encode=utf-8",
|
||||
"spring.cloud.nacos.config.shared-data-ids=base-common.properties,common.properties",
|
||||
"spring.cloud.nacos.config.refreshable-dataids=common.properties",
|
||||
"spring.cloud.nacos.config.ext-config[0].data-id=ext00.yaml",
|
||||
"spring.cloud.nacos.config.ext-config[1].data-id=ext01.yml",
|
||||
"spring.cloud.nacos.config.ext-config[1].group=EXT01_GROUP",
|
||||
"spring.cloud.nacos.config.ext-config[1].refresh=true",
|
||||
"spring.cloud.nacos.config.ext-config[2].data-id=ext02.yaml",
|
||||
"spring.profiles.active=develop", "server.port=19090" })
|
||||
public class NacosPowerMockitBaseTests {
|
||||
|
||||
private final static List<String> DATAIDS = Arrays.asList("common.properties",
|
||||
"base-common.properties", "ext00.yaml", "ext01.yml", "ext02.yaml",
|
||||
"sca-nacos-config.properties", "sca-nacos-config-develop.properties");
|
||||
|
||||
private final static HashMap<String, Properties> VALUES = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
protected ApplicationContext context;
|
||||
|
||||
static {
|
||||
initDataIds();
|
||||
try {
|
||||
final Constructor constructor = ReflectionUtils.accessibleConstructor(
|
||||
NacosPropertySource.class, String.class, String.class, Map.class,
|
||||
Date.class, boolean.class);
|
||||
Method method = PowerMockito.method(NacosPropertySourceBuilder.class, "build",
|
||||
String.class, String.class, String.class, boolean.class);
|
||||
MethodProxy.proxy(method, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
Properties properties = VALUES.get(args[0].toString());
|
||||
if (properties == null) {
|
||||
properties = new Properties();
|
||||
properties.put("user.name", args[0].toString());
|
||||
}
|
||||
Object instance = constructor.newInstance(args[1].toString(),
|
||||
args[0].toString(), properties, new Date(), args[3]);
|
||||
return instance;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void initDataIds() {
|
||||
DATAIDS.forEach(dataId -> {
|
||||
String realpath = "/" + dataId;
|
||||
ClassPathResource classPathResource = new ClassPathResource(realpath);
|
||||
if (realpath.endsWith("properties")) {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(classPathResource.getInputStream());
|
||||
VALUES.put(dataId, properties);
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (realpath.endsWith("yaml") || realpath.endsWith("yml")) {
|
||||
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
|
||||
yamlFactory.setResources(classPathResource);
|
||||
try {
|
||||
VALUES.put(dataId, yamlFactory.getObject());
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public NacosPropertySourceBuilder nacosPropertySourceBuilderInstance() {
|
||||
NacosConfigProperties nacosConfigProperties = this.context
|
||||
.getBean(NacosConfigProperties.class);
|
||||
|
||||
ConfigService configService = nacosConfigProperties.configServiceInstance();
|
||||
long timeout = nacosConfigProperties.getTimeout();
|
||||
NacosPropertySourceBuilder nacosPropertySourceBuilder = new NacosPropertySourceBuilder(
|
||||
configService, timeout);
|
||||
return nacosPropertySourceBuilder;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureBefore(NacosConfigAutoConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Bean
|
||||
ContextRefresher contextRefresher() {
|
||||
RefreshScope refreshScope = new RefreshScope();
|
||||
refreshScope.setApplicationContext(context);
|
||||
return new ContextRefresher(context, refreshScope);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppContext() {
|
||||
System.err.println(this.context);
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.nacos;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.powermock.api.support.MethodProxy;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySource;
|
||||
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceBuilder;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-01-17 11:49 AM
|
||||
*/
|
||||
public class NacosPropertySourceBuilderTests extends NacosPowerMockitBaseTests {
|
||||
|
||||
@Test
|
||||
public void nacosPropertySourceBuilder() {
|
||||
|
||||
assertThat(nacosPropertySourceBuilderInstance() != null).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfigByProperties() {
|
||||
try {
|
||||
final HashMap<String, String> value = new HashMap<>();
|
||||
value.put("dev.mode", "local-mock");
|
||||
|
||||
final Constructor constructor = ReflectionUtils.accessibleConstructor(
|
||||
NacosPropertySource.class, String.class, String.class, Map.class,
|
||||
Date.class, boolean.class);
|
||||
|
||||
NacosPropertySourceBuilder nacosPropertySourceBuilder = nacosPropertySourceBuilderInstance();
|
||||
|
||||
Method method = ReflectionUtils.findMethod(NacosPropertySourceBuilder.class,
|
||||
"build", String.class, String.class, String.class, boolean.class);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
assertThat(method != null).isEqualTo(true);
|
||||
MethodProxy.proxy(method, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
Object instance = constructor.newInstance(args[1].toString(),
|
||||
args[0].toString(), value, new Date(), args[3]);
|
||||
return instance;
|
||||
}
|
||||
});
|
||||
|
||||
Object result = method.invoke(nacosPropertySourceBuilder,
|
||||
"mock-nacos-config.properties", "DEFAULT_GROUP", "properties", true);
|
||||
assertThat(result != null).isEqualTo(true);
|
||||
assertThat(result instanceof NacosPropertySource).isEqualTo(true);
|
||||
NacosPropertySource nacosPropertySource = (NacosPropertySource) result;
|
||||
assertThat(nacosPropertySource.getProperty("dev.mode"))
|
||||
.isEqualTo("local-mock");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfigByYaml() {
|
||||
|
||||
try {
|
||||
//
|
||||
final HashMap<String, String> value = new HashMap<>();
|
||||
value.put("mock-ext-config", "mock-ext-config-value");
|
||||
|
||||
final Constructor constructor = ReflectionUtils.accessibleConstructor(
|
||||
NacosPropertySource.class, String.class, String.class, Map.class,
|
||||
Date.class, boolean.class);
|
||||
|
||||
Method method = ReflectionUtils.findMethod(NacosPropertySourceBuilder.class,
|
||||
"build", String.class, String.class, String.class, boolean.class);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
assertThat(method != null).isEqualTo(true);
|
||||
|
||||
MethodProxy.proxy(method, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
Object instance = constructor.newInstance(args[1].toString(),
|
||||
args[0].toString(), value, new Date(), args[3]);
|
||||
return instance;
|
||||
}
|
||||
});
|
||||
|
||||
NacosPropertySourceBuilder nacosPropertySourceBuilder = nacosPropertySourceBuilderInstance();
|
||||
Object result = method.invoke(nacosPropertySourceBuilder, "ext-config.yaml",
|
||||
"DEFAULT_GROUP", "yaml", true);
|
||||
assertThat(result != null).isEqualTo(true);
|
||||
assertThat(result instanceof NacosPropertySource).isEqualTo(true);
|
||||
NacosPropertySource nacosPropertySource = (NacosPropertySource) result;
|
||||
assertThat(nacosPropertySource.getProperty("mock-ext-config"))
|
||||
.isEqualTo("mock-ext-config-value");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfigByYml() {
|
||||
try {
|
||||
//
|
||||
final HashMap<String, String> value = new HashMap<>();
|
||||
value.put("mock-ext-config-yml", "mock-ext-config-yml-value");
|
||||
|
||||
final Constructor constructor = ReflectionUtils.accessibleConstructor(
|
||||
NacosPropertySource.class, String.class, String.class, Map.class,
|
||||
Date.class, boolean.class);
|
||||
|
||||
Method method = ReflectionUtils.findMethod(NacosPropertySourceBuilder.class,
|
||||
"build", String.class, String.class, String.class, boolean.class);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
assertThat(method != null).isEqualTo(true);
|
||||
|
||||
MethodProxy.proxy(method, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
Object instance = constructor.newInstance(args[1].toString(),
|
||||
args[0].toString(), value, new Date(), args[3]);
|
||||
return instance;
|
||||
}
|
||||
});
|
||||
|
||||
NacosPropertySourceBuilder nacosPropertySourceBuilder = nacosPropertySourceBuilderInstance();
|
||||
Object result = method.invoke(nacosPropertySourceBuilder, "ext-config.yml",
|
||||
"DEFAULT_GROUP", "yml", true);
|
||||
assertThat(result != null).isEqualTo(true);
|
||||
assertThat(result instanceof NacosPropertySource).isEqualTo(true);
|
||||
NacosPropertySource nacosPropertySource = (NacosPropertySource) result;
|
||||
assertThat(nacosPropertySource.getProperty("mock-ext-config-yml"))
|
||||
.isEqualTo("mock-ext-config-yml-value");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEmpty() {
|
||||
NacosPropertySourceBuilder nacosPropertySourceBuilder = nacosPropertySourceBuilderInstance();
|
||||
|
||||
Method method = ReflectionUtils.findMethod(NacosPropertySourceBuilder.class,
|
||||
"build", String.class, String.class, String.class, boolean.class);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
assertThat(method != null).isEqualTo(true);
|
||||
|
||||
try {
|
||||
Object result = method.invoke(nacosPropertySourceBuilder, "nacos-empty.yml",
|
||||
"DEFAULT_GROUP", "yml", true);
|
||||
assertThat(result != null).isEqualTo(true);
|
||||
assertThat(result instanceof NacosPropertySource).isEqualTo(true);
|
||||
NacosPropertySource nacosPropertySource = (NacosPropertySource) result;
|
||||
assertThat(nacosPropertySource.getProperty("address")).isEqualTo(null);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.nacos;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-01-17 11:46 AM
|
||||
*/
|
||||
public class NacosSharedAndExtConfigTests extends NacosPowerMockitBaseTests {
|
||||
private final static Logger log = LoggerFactory
|
||||
.getLogger(NacosSharedAndExtConfigTests.class);
|
||||
|
||||
@Test
|
||||
public void testSharedConfigPriority() {
|
||||
String userName = this.context.getEnvironment().getProperty("user.address");
|
||||
assertThat(userName).isEqualTo("zhejiang-ningbo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSharedConfigRefresh() {
|
||||
|
||||
while (true) {
|
||||
// ContextRefresher contextRefresher = this.context
|
||||
// .getBean(ContextRefresher.class);
|
||||
// contextRefresher.refresh();
|
||||
String userName = this.context.getEnvironment().getProperty("user.address");
|
||||
try {
|
||||
assertThat(userName).isEqualTo("zhejiang-ningbo");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
log.info("user name is {}", userName);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 真实测试时将这里 注释掉
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtConfigPriority() {
|
||||
String extKey = this.context.getEnvironment().getProperty("ext.key");
|
||||
assertThat(extKey).isEqualTo("ext.value02");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtOtherGroup() {
|
||||
String userExt = this.context.getEnvironment().getProperty("user.ext");
|
||||
assertThat(userExt).isEqualTo("EXT01_GROUP-value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtRefresh() {
|
||||
while (true) {
|
||||
// ContextRefresher contextRefresher = this.context
|
||||
// .getBean(ContextRefresher.class);
|
||||
// contextRefresher.refresh();
|
||||
String userExt = this.context.getEnvironment().getProperty("user.ext");
|
||||
try {
|
||||
assertThat(userExt).isEqualTo("EXT01_GROUP-value");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
log.info("user name is {}", userExt);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
user.name=base-common-value
|
||||
user.address=zhejiang-hangzhou
|
@ -0,0 +1,2 @@
|
||||
user.name=common-value
|
||||
user.address=zhejiang-ningbo
|
@ -0,0 +1,4 @@
|
||||
user:
|
||||
name: ext-00-value
|
||||
ext:
|
||||
key: ext.value00
|
@ -0,0 +1,5 @@
|
||||
user:
|
||||
name: ext-01-value
|
||||
ext: EXT01_GROUP-value
|
||||
ext:
|
||||
key: ext.value01
|
@ -0,0 +1,5 @@
|
||||
user:
|
||||
name: ext-02-value
|
||||
ext:
|
||||
key: ext.value02
|
||||
app-local-common: update app local shared cguration for Nacos
|
@ -0,0 +1 @@
|
||||
user.name=sca-nacos-config-value-develop
|
@ -0,0 +1,2 @@
|
||||
user.name=sca-nacos-config-value
|
||||
dev.mode=local
|
@ -82,28 +82,4 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<excludes>
|
||||
<exclude>org/springframework/cloud/alibaba/nacos/**.*class</exclude>
|
||||
</excludes>
|
||||
</instrumentation>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -28,7 +28,7 @@ import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClientAut
|
||||
import org.springframework.cloud.alibaba.nacos.registry.NacosAutoServiceRegistration;
|
||||
import org.springframework.cloud.alibaba.nacos.registry.NacosRegistration;
|
||||
import org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistry;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -43,7 +43,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConditionalOnNacosDiscoveryEnabled
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
@AutoConfigureBefore(NacosDiscoveryClientAutoConfiguration.class)
|
||||
@AutoConfigureAfter(AutoServiceRegistrationAutoConfiguration.class)
|
||||
@AutoConfigureAfter(AutoServiceRegistrationConfiguration.class)
|
||||
public class NacosDiscoveryAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.cloud.alibaba.nacos;
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -27,14 +28,25 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.*;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
|
||||
|
||||
/**
|
||||
* @author dungu.zpf
|
||||
@ -154,8 +166,8 @@ public class NacosDiscoveryProperties {
|
||||
}
|
||||
|
||||
serverAddr = Objects.toString(serverAddr, "");
|
||||
if(serverAddr.lastIndexOf("/") != -1) {
|
||||
serverAddr.substring(0,serverAddr.length()-1);
|
||||
if (serverAddr.lastIndexOf("/") != -1) {
|
||||
serverAddr.substring(0, serverAddr.length() - 1);
|
||||
}
|
||||
endpoint = Objects.toString(endpoint, "");
|
||||
namespace = Objects.toString(namespace, "");
|
||||
@ -397,13 +409,14 @@ public class NacosDiscoveryProperties {
|
||||
properties.put(CLUSTER_NAME, clusterName);
|
||||
properties.put(NAMING_LOAD_CACHE_AT_START, namingLoadCacheAtStart);
|
||||
|
||||
try {
|
||||
namingService = NacosFactory.createNamingService(properties);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
namingService = NacosFactory.createNamingService(properties);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("create naming service error!properties={},e=,", this, e);
|
||||
return null;
|
||||
}
|
||||
return namingService;
|
||||
return namingService;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.alibaba.nacos.ConditionalOnNacosDiscoveryEnabled;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
|
||||
import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClient;
|
||||
import org.springframework.cloud.alibaba.nacos.discovery.NacosWatch;
|
||||
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
|
||||
|
@ -30,75 +30,74 @@ import org.springframework.util.StringUtils;
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class NacosAutoServiceRegistration
|
||||
extends AbstractAutoServiceRegistration<Registration> {
|
||||
private static final Logger LOGGER = LoggerFactory
|
||||
.getLogger(NacosAutoServiceRegistration.class);
|
||||
extends AbstractAutoServiceRegistration<Registration> {
|
||||
private static final Logger LOGGER = LoggerFactory
|
||||
.getLogger(NacosAutoServiceRegistration.class);
|
||||
|
||||
private NacosRegistration registration;
|
||||
private NacosRegistration registration;
|
||||
|
||||
public NacosAutoServiceRegistration(
|
||||
ServiceRegistry<Registration> serviceRegistry,
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
NacosRegistration registration) {
|
||||
super(serviceRegistry, autoServiceRegistrationProperties);
|
||||
this.registration = registration;
|
||||
}
|
||||
public NacosAutoServiceRegistration(ServiceRegistry<Registration> serviceRegistry,
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
NacosRegistration registration) {
|
||||
super(serviceRegistry, autoServiceRegistrationProperties);
|
||||
this.registration = registration;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setPort(int port) {
|
||||
getPort().set(port);
|
||||
}
|
||||
@Deprecated
|
||||
public void setPort(int port) {
|
||||
getPort().set(port);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NacosRegistration getRegistration() {
|
||||
if (this.registration.getPort() < 0 && this.getPort().get() > 0) {
|
||||
this.registration.setPort(this.getPort().get());
|
||||
}
|
||||
Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set");
|
||||
return this.registration;
|
||||
}
|
||||
@Override
|
||||
protected NacosRegistration getRegistration() {
|
||||
if (this.registration.getPort() < 0 && this.getPort().get() > 0) {
|
||||
this.registration.setPort(this.getPort().get());
|
||||
}
|
||||
Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set");
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NacosRegistration getManagementRegistration() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected NacosRegistration getManagementRegistration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void register() {
|
||||
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
|
||||
LOGGER.debug("Registration disabled.");
|
||||
return;
|
||||
}
|
||||
if (this.registration.getPort() < 0) {
|
||||
this.registration.setPort(getPort().get());
|
||||
}
|
||||
super.register();
|
||||
}
|
||||
@Override
|
||||
protected void register() {
|
||||
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
|
||||
LOGGER.debug("Registration disabled.");
|
||||
return;
|
||||
}
|
||||
if (this.registration.getPort() < 0) {
|
||||
this.registration.setPort(getPort().get());
|
||||
}
|
||||
super.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerManagement() {
|
||||
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
|
||||
return;
|
||||
}
|
||||
super.registerManagement();
|
||||
@Override
|
||||
protected void registerManagement() {
|
||||
if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
|
||||
return;
|
||||
}
|
||||
super.registerManagement();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getConfiguration() {
|
||||
return this.registration.getNacosDiscoveryProperties();
|
||||
}
|
||||
@Override
|
||||
protected Object getConfiguration() {
|
||||
return this.registration.getNacosDiscoveryProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabled() {
|
||||
return this.registration.getNacosDiscoveryProperties().isRegisterEnabled();
|
||||
}
|
||||
@Override
|
||||
protected boolean isEnabled() {
|
||||
return this.registration.getNacosDiscoveryProperties().isRegisterEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected String getAppName() {
|
||||
String appName = registration.getNacosDiscoveryProperties().getService();
|
||||
return StringUtils.isEmpty(appName) ? super.getAppName() : appName;
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected String getAppName() {
|
||||
String appName = registration.getNacosDiscoveryProperties().getService();
|
||||
return StringUtils.isEmpty(appName) ? super.getAppName() : appName;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,83 +32,84 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class NacosServiceRegistry implements ServiceRegistry<Registration> {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class);
|
||||
private static Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class);
|
||||
|
||||
private final NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
private final NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
|
||||
private final NamingService namingService;
|
||||
private final NamingService namingService;
|
||||
|
||||
public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {
|
||||
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
|
||||
this.namingService = nacosDiscoveryProperties.namingServiceInstance();
|
||||
}
|
||||
public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {
|
||||
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
|
||||
this.namingService = nacosDiscoveryProperties.namingServiceInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Registration registration) {
|
||||
|
||||
@Override
|
||||
public void register(Registration registration) {
|
||||
if (StringUtils.isEmpty(registration.getServiceId())) {
|
||||
logger.info("No service to register for nacos client...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(registration.getServiceId())) {
|
||||
logger.info("No service to register for nacos client...");
|
||||
return;
|
||||
}
|
||||
String serviceId = registration.getServiceId();
|
||||
|
||||
String serviceId = registration.getServiceId();
|
||||
Instance instance = new Instance();
|
||||
instance.setIp(registration.getHost());
|
||||
instance.setPort(registration.getPort());
|
||||
instance.setWeight(nacosDiscoveryProperties.getWeight());
|
||||
instance.setClusterName(nacosDiscoveryProperties.getClusterName());
|
||||
instance.setMetadata(registration.getMetadata());
|
||||
|
||||
Instance instance = new Instance();
|
||||
instance.setIp(registration.getHost());
|
||||
instance.setPort(registration.getPort());
|
||||
instance.setWeight(nacosDiscoveryProperties.getWeight());
|
||||
instance.setClusterName(nacosDiscoveryProperties.getClusterName());
|
||||
instance.setMetadata(registration.getMetadata());
|
||||
try {
|
||||
namingService.registerInstance(serviceId, instance);
|
||||
logger.info("nacos registry, {} {}:{} register finished", serviceId,
|
||||
instance.getIp(), instance.getPort());
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("nacos registry, {} register failed...{},", serviceId,
|
||||
registration.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
namingService.registerInstance(serviceId, instance);
|
||||
logger.info("nacos registry, {} {}:{} register finished", serviceId,
|
||||
instance.getIp(), instance.getPort());
|
||||
} catch (Exception e) {
|
||||
logger.error("nacos registry, {} register failed...{},", serviceId,
|
||||
registration.toString(), e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void deregister(Registration registration) {
|
||||
|
||||
@Override
|
||||
public void deregister(Registration registration) {
|
||||
logger.info("De-registering from Nacos Server now...");
|
||||
|
||||
logger.info("De-registering from Nacos Server now...");
|
||||
if (StringUtils.isEmpty(registration.getServiceId())) {
|
||||
logger.info("No dom to de-register for nacos client...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(registration.getServiceId())) {
|
||||
logger.info("No dom to de-register for nacos client...");
|
||||
return;
|
||||
}
|
||||
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
|
||||
String serviceId = registration.getServiceId();
|
||||
|
||||
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
|
||||
String serviceId = registration.getServiceId();
|
||||
try {
|
||||
namingService.deregisterInstance(serviceId, registration.getHost(),
|
||||
registration.getPort(), nacosDiscoveryProperties.getClusterName());
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("ERR_NACOS_DEREGISTER, de-register failed...{},",
|
||||
registration.toString(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
namingService.deregisterInstance(serviceId, registration.getHost(),
|
||||
registration.getPort(), nacosDiscoveryProperties.getClusterName());
|
||||
} catch (Exception e) {
|
||||
logger.error("ERR_NACOS_DEREGISTER, de-register failed...{},",
|
||||
registration.toString(), e);
|
||||
}
|
||||
logger.info("De-registration finished.");
|
||||
}
|
||||
|
||||
logger.info("De-registration finished.");
|
||||
}
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void setStatus(Registration registration, String status) {
|
||||
// nacos doesn't support set status of a particular registration.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(Registration registration, String status) {
|
||||
// nacos doesn't support set status of a particular registration.
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getStatus(Registration registration) {
|
||||
// nacos doesn't support query status of a particular registration.
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public <T> T getStatus(Registration registration) {
|
||||
// nacos doesn't support query status of a particular registration.
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,14 @@
|
||||
package org.springframework.cloud.alibaba.nacos.ribbon;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosServer extends Server {
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.alibaba.nacos.ribbon;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
|
||||
@ -62,7 +63,10 @@ public class NacosServerList extends AbstractServerList<NacosServer> {
|
||||
}
|
||||
|
||||
private List<NacosServer> instancesToServerList(List<Instance> instances) {
|
||||
List<NacosServer> result = new ArrayList<>(instances.size());
|
||||
List<NacosServer> result = new ArrayList<>();
|
||||
if (null == instances) {
|
||||
return result;
|
||||
}
|
||||
for (Instance instance : instances) {
|
||||
result.add(new NacosServer(instance));
|
||||
}
|
||||
|
@ -16,11 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.alibaba.nacos.registry;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -28,12 +23,16 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryAutoConfiguration;
|
||||
import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
|
||||
import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
@ -42,7 +41,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
@SpringBootTest(classes = NacosAutoServiceRegistrationIpTests.TestConfig.class, properties = {
|
||||
"spring.application.name=myTestService1",
|
||||
"spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848",
|
||||
"spring.cloud.nacos.discovery.ip=123.123.123.123" }, webEnvironment = RANDOM_PORT)
|
||||
"spring.cloud.nacos.discovery.ip=123.123.123.123" }, webEnvironment = RANDOM_PORT)
|
||||
public class NacosAutoServiceRegistrationIpTests {
|
||||
|
||||
@Autowired
|
||||
|
@ -1,15 +1,5 @@
|
||||
package org.springframework.cloud.alibaba.sentinel.datasource.converter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.RuleType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
import com.alibaba.csp.sentinel.slots.block.AbstractRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
|
||||
@ -23,6 +13,15 @@ import com.alibaba.csp.sentinel.slots.system.SystemRule;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.RuleType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Convert sentinel rules for json or xml array Using strict mode to parse json or xml
|
||||
@ -38,7 +37,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
public abstract class SentinelConverter<T extends AbstractRule>
|
||||
implements Converter<String, List<AbstractRule>> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SentinelConverter.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(SentinelConverter.class);
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@ -53,7 +52,7 @@ public abstract class SentinelConverter<T extends AbstractRule>
|
||||
public List<AbstractRule> convert(String source) {
|
||||
List<AbstractRule> ruleList = new ArrayList<>();
|
||||
if (StringUtils.isEmpty(source)) {
|
||||
logger.warn("converter can not convert rules because source is empty");
|
||||
log.warn("converter can not convert rules because source is empty");
|
||||
return ruleList;
|
||||
}
|
||||
try {
|
||||
|
@ -1,230 +1,230 @@
|
||||
/*
|
||||
* 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.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.config.ApolloDataSourceProperties;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.config.FileDataSourceProperties;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.config.NacosDataSourceProperties;
|
||||
import org.springframework.cloud.alibaba.sentinel.datasource.config.ZookeeperDataSourceProperties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
public class DataSourcePropertiesConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void testFileAttr() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
|
||||
FileDataSourceProperties fileDataSourceProperties = buildFileProperties();
|
||||
|
||||
dataSourcePropertiesConfiguration.setFile(fileDataSourceProperties);
|
||||
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration valid field size was wrong after set file attribute",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration file properties was null after set file attribute",
|
||||
dataSourcePropertiesConfiguration.getFile());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration valid properties was null after set file attribute",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNacosAttr() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
|
||||
NacosDataSourceProperties nacosDataSourceProperties = buildNacosProperties();
|
||||
|
||||
dataSourcePropertiesConfiguration.setNacos(nacosDataSourceProperties);
|
||||
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration valid field size was wrong after set nacos attribute",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration nacos properties was null after set nacos attribute",
|
||||
dataSourcePropertiesConfiguration.getNacos());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration valid properties was null after set nacos attribute",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZKAttr() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
|
||||
ZookeeperDataSourceProperties zookeeperDataSourceProperties = buildZKProperties();
|
||||
|
||||
dataSourcePropertiesConfiguration.setZk(zookeeperDataSourceProperties);
|
||||
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration valid field size was wrong after set zk attribute",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration zk properties was null after set zk attribute",
|
||||
dataSourcePropertiesConfiguration.getZk());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration valid properties was null after set zk attribute",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApolloAttr() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
|
||||
ApolloDataSourceProperties apolloDataSourceProperties = buildApolloProperties();
|
||||
|
||||
dataSourcePropertiesConfiguration.setApollo(apolloDataSourceProperties);
|
||||
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration valid field size was wrong after set apollo attribute",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration apollo properties was null after set apollo attribute",
|
||||
dataSourcePropertiesConfiguration.getApollo());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration valid properties was null after set apollo attribute",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiAttr() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
|
||||
FileDataSourceProperties fileDataSourceProperties = buildFileProperties();
|
||||
NacosDataSourceProperties nacosDataSourceProperties = buildNacosProperties();
|
||||
|
||||
dataSourcePropertiesConfiguration.setFile(fileDataSourceProperties);
|
||||
dataSourcePropertiesConfiguration.setNacos(nacosDataSourceProperties);
|
||||
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration valid field size was wrong after set file and nacos attribute",
|
||||
2, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNull(
|
||||
"DataSourcePropertiesConfiguration valid properties was not null after set file and nacos attribute",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileConstructor() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
buildFileProperties());
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration file constructor valid field size was wrong",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration file constructor valid properties was null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNacosConstructor() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
buildNacosProperties());
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration nacos constructor valid field size was wrong",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration nacos constructor valid properties was null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApolloConstructor() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
buildApolloProperties());
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration apollo constructor valid field size was wrong",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration apollo constructor valid properties was null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZKConstructor() {
|
||||
DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
buildZKProperties());
|
||||
assertEquals(
|
||||
"DataSourcePropertiesConfiguration zk constructor valid field size was wrong",
|
||||
1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
assertNotNull(
|
||||
"DataSourcePropertiesConfiguration zk constructor valid properties was null",
|
||||
dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
}
|
||||
|
||||
private FileDataSourceProperties buildFileProperties() {
|
||||
FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
|
||||
|
||||
fileDataSourceProperties.setFile("/tmp/test.json");
|
||||
fileDataSourceProperties.setBufSize(1024);
|
||||
fileDataSourceProperties.setRecommendRefreshMs(2000);
|
||||
return fileDataSourceProperties;
|
||||
}
|
||||
|
||||
private NacosDataSourceProperties buildNacosProperties() {
|
||||
NacosDataSourceProperties nacosDataSourceProperties = new NacosDataSourceProperties();
|
||||
nacosDataSourceProperties.setServerAddr("127.0.0.1:8848");
|
||||
nacosDataSourceProperties.setDataId("sentinel");
|
||||
nacosDataSourceProperties.setGroupId("custom-group");
|
||||
return nacosDataSourceProperties;
|
||||
}
|
||||
|
||||
private ApolloDataSourceProperties buildApolloProperties() {
|
||||
ApolloDataSourceProperties apolloDataSourceProperties = new ApolloDataSourceProperties();
|
||||
apolloDataSourceProperties.setFlowRulesKey("test-key");
|
||||
apolloDataSourceProperties.setDefaultFlowRuleValue("dft-val");
|
||||
apolloDataSourceProperties.setNamespaceName("namespace");
|
||||
return apolloDataSourceProperties;
|
||||
}
|
||||
|
||||
private ZookeeperDataSourceProperties buildZKProperties() {
|
||||
ZookeeperDataSourceProperties zookeeperDataSourceProperties = new ZookeeperDataSourceProperties();
|
||||
|
||||
zookeeperDataSourceProperties.setServerAddr("localhost:2181");
|
||||
zookeeperDataSourceProperties.setPath("/path");
|
||||
return zookeeperDataSourceProperties;
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.junit.Assert.assertEquals;
|
||||
//import static org.junit.Assert.assertNotNull;
|
||||
//import static org.junit.Assert.assertNull;
|
||||
//
|
||||
//import org.junit.Test;
|
||||
//import org.springframework.cloud.alibaba.sentinel.datasource.config.ApolloDataSourceProperties;
|
||||
//import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration;
|
||||
//import org.springframework.cloud.alibaba.sentinel.datasource.config.FileDataSourceProperties;
|
||||
//import org.springframework.cloud.alibaba.sentinel.datasource.config.NacosDataSourceProperties;
|
||||
//import org.springframework.cloud.alibaba.sentinel.datasource.config.ZookeeperDataSourceProperties;
|
||||
//
|
||||
///**
|
||||
// * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
// */
|
||||
//public class DataSourcePropertiesConfigurationTests {
|
||||
//
|
||||
// @Test
|
||||
// public void testFileAttr() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
// assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
// dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
//
|
||||
// FileDataSourceProperties fileDataSourceProperties = buildFileProperties();
|
||||
//
|
||||
// dataSourcePropertiesConfiguration.setFile(fileDataSourceProperties);
|
||||
//
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration valid field size was wrong after set file attribute",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration file properties was null after set file attribute",
|
||||
// dataSourcePropertiesConfiguration.getFile());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration valid properties was null after set file attribute",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testNacosAttr() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
// assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
// dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
//
|
||||
// NacosDataSourceProperties nacosDataSourceProperties = buildNacosProperties();
|
||||
//
|
||||
// dataSourcePropertiesConfiguration.setNacos(nacosDataSourceProperties);
|
||||
//
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration valid field size was wrong after set nacos attribute",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration nacos properties was null after set nacos attribute",
|
||||
// dataSourcePropertiesConfiguration.getNacos());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration valid properties was null after set nacos attribute",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testZKAttr() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
// assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
// dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
//
|
||||
// ZookeeperDataSourceProperties zookeeperDataSourceProperties = buildZKProperties();
|
||||
//
|
||||
// dataSourcePropertiesConfiguration.setZk(zookeeperDataSourceProperties);
|
||||
//
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration valid field size was wrong after set zk attribute",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration zk properties was null after set zk attribute",
|
||||
// dataSourcePropertiesConfiguration.getZk());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration valid properties was null after set zk attribute",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testApolloAttr() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
// assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
// dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
//
|
||||
// ApolloDataSourceProperties apolloDataSourceProperties = buildApolloProperties();
|
||||
//
|
||||
// dataSourcePropertiesConfiguration.setApollo(apolloDataSourceProperties);
|
||||
//
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration valid field size was wrong after set apollo attribute",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration apollo properties was null after set apollo attribute",
|
||||
// dataSourcePropertiesConfiguration.getApollo());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration valid properties was null after set apollo attribute",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testMultiAttr() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration();
|
||||
// assertEquals("DataSourcePropertiesConfiguration valid field size was wrong", 0,
|
||||
// dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull("DataSourcePropertiesConfiguration valid properties was not null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
//
|
||||
// FileDataSourceProperties fileDataSourceProperties = buildFileProperties();
|
||||
// NacosDataSourceProperties nacosDataSourceProperties = buildNacosProperties();
|
||||
//
|
||||
// dataSourcePropertiesConfiguration.setFile(fileDataSourceProperties);
|
||||
// dataSourcePropertiesConfiguration.setNacos(nacosDataSourceProperties);
|
||||
//
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration valid field size was wrong after set file and nacos attribute",
|
||||
// 2, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNull(
|
||||
// "DataSourcePropertiesConfiguration valid properties was not null after set file and nacos attribute",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testFileConstructor() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
// buildFileProperties());
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration file constructor valid field size was wrong",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration file constructor valid properties was null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testNacosConstructor() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
// buildNacosProperties());
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration nacos constructor valid field size was wrong",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration nacos constructor valid properties was null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testApolloConstructor() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
// buildApolloProperties());
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration apollo constructor valid field size was wrong",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration apollo constructor valid properties was null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testZKConstructor() {
|
||||
// DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration = new DataSourcePropertiesConfiguration(
|
||||
// buildZKProperties());
|
||||
// assertEquals(
|
||||
// "DataSourcePropertiesConfiguration zk constructor valid field size was wrong",
|
||||
// 1, dataSourcePropertiesConfiguration.getValidField().size());
|
||||
// assertNotNull(
|
||||
// "DataSourcePropertiesConfiguration zk constructor valid properties was null",
|
||||
// dataSourcePropertiesConfiguration.getValidDataSourceProperties());
|
||||
// }
|
||||
//
|
||||
// private FileDataSourceProperties buildFileProperties() {
|
||||
// FileDataSourceProperties fileDataSourceProperties = new FileDataSourceProperties();
|
||||
//
|
||||
// fileDataSourceProperties.setFile("/tmp/test.json");
|
||||
// fileDataSourceProperties.setBufSize(1024);
|
||||
// fileDataSourceProperties.setRecommendRefreshMs(2000);
|
||||
// return fileDataSourceProperties;
|
||||
// }
|
||||
//
|
||||
// private NacosDataSourceProperties buildNacosProperties() {
|
||||
// NacosDataSourceProperties nacosDataSourceProperties = new NacosDataSourceProperties();
|
||||
// nacosDataSourceProperties.setServerAddr("127.0.0.1:8848");
|
||||
// nacosDataSourceProperties.setDataId("sentinel");
|
||||
// nacosDataSourceProperties.setGroupId("custom-group");
|
||||
// return nacosDataSourceProperties;
|
||||
// }
|
||||
//
|
||||
// private ApolloDataSourceProperties buildApolloProperties() {
|
||||
// ApolloDataSourceProperties apolloDataSourceProperties = new ApolloDataSourceProperties();
|
||||
// apolloDataSourceProperties.setFlowRulesKey("test-key");
|
||||
// apolloDataSourceProperties.setDefaultFlowRuleValue("dft-val");
|
||||
// apolloDataSourceProperties.setNamespaceName("namespace");
|
||||
// return apolloDataSourceProperties;
|
||||
// }
|
||||
//
|
||||
// private ZookeeperDataSourceProperties buildZKProperties() {
|
||||
// ZookeeperDataSourceProperties zookeeperDataSourceProperties = new ZookeeperDataSourceProperties();
|
||||
//
|
||||
// zookeeperDataSourceProperties.setServerAddr("localhost:2181");
|
||||
// zookeeperDataSourceProperties.setPath("/path");
|
||||
// return zookeeperDataSourceProperties;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.alibaba.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -40,7 +41,7 @@ import java.util.List;
|
||||
@EnableConfigurationProperties(SentinelProperties.class)
|
||||
public class SentinelWebAutoConfiguration {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SentinelWebAutoConfiguration.class);
|
||||
|
||||
@Autowired
|
||||
@ -63,7 +64,7 @@ public class SentinelWebAutoConfiguration {
|
||||
Filter filter = new CommonFilter();
|
||||
registration.setFilter(filter);
|
||||
registration.setOrder(filterConfig.getOrder());
|
||||
logger.info("[Sentinel Starter] register Sentinel with urlPatterns: {}.",
|
||||
log.info("[Sentinel Starter] register Sentinel with urlPatterns: {}.",
|
||||
filterConfig.getUrlPatterns());
|
||||
return registration;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.alibaba.sentinel.custom;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@ -50,7 +51,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SentinelBeanPostProcessor.class);
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
@ -97,14 +98,14 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
return;
|
||||
}
|
||||
if (blockClass != void.class && StringUtils.isEmpty(blockMethod)) {
|
||||
logger.error(
|
||||
log.error(
|
||||
"{} class attribute exists but {} method attribute is not exists in bean[{}]",
|
||||
type, type, beanName);
|
||||
throw new IllegalArgumentException(type + " class attribute exists but "
|
||||
+ type + " method attribute is not exists in bean[" + beanName + "]");
|
||||
}
|
||||
else if (blockClass == void.class && !StringUtils.isEmpty(blockMethod)) {
|
||||
logger.error(
|
||||
log.error(
|
||||
"{} method attribute exists but {} class attribute is not exists in bean[{}]",
|
||||
type, type, beanName);
|
||||
throw new IllegalArgumentException(type + " method attribute exists but "
|
||||
@ -116,7 +117,7 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
Arrays.stream(args).map(clazz -> clazz.getSimpleName()).toArray());
|
||||
Method foundMethod = ClassUtils.getStaticMethod(blockClass, blockMethod, args);
|
||||
if (foundMethod == null) {
|
||||
logger.error(
|
||||
log.error(
|
||||
"{} static method can not be found in bean[{}]. The right method signature is {}#{}{}, please check your class name, method name and arguments",
|
||||
type, beanName, blockClass.getName(), blockMethod, argsStr);
|
||||
throw new IllegalArgumentException(type
|
||||
@ -127,7 +128,7 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
}
|
||||
|
||||
if (!ClientHttpResponse.class.isAssignableFrom(foundMethod.getReturnType())) {
|
||||
logger.error(
|
||||
log.error(
|
||||
"{} method return value in bean[{}] is not ClientHttpResponse: {}#{}{}",
|
||||
type, beanName, blockClass.getName(), blockMethod, argsStr);
|
||||
throw new IllegalArgumentException(type + " method return value in bean["
|
||||
|
@ -1,11 +1,8 @@
|
||||
package org.springframework.cloud.alibaba.sentinel.custom;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
|
||||
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
|
||||
import com.alibaba.csp.sentinel.slots.block.AbstractRule;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -21,9 +18,12 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
|
||||
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
|
||||
import com.alibaba.csp.sentinel.slots.block.AbstractRule;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Sentinel {@link ReadableDataSource} Handler Handle the configurations of
|
||||
@ -36,7 +36,7 @@ import com.alibaba.csp.sentinel.slots.block.AbstractRule;
|
||||
*/
|
||||
public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SentinelDataSourceHandler.class);
|
||||
|
||||
private List<String> dataTypeList = Arrays.asList("json", "xml");
|
||||
@ -61,7 +61,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
try {
|
||||
List<String> validFields = dataSourceProperties.getValidField();
|
||||
if (validFields.size() != 1) {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " multi datasource active and won't loaded: "
|
||||
+ dataSourceProperties.getValidField());
|
||||
return;
|
||||
@ -73,7 +73,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
+ "-sentinel-" + validFields.get(0) + "-datasource");
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " build error: " + e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
@ -90,7 +90,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
m.put(v.getName(), v.get(dataSourceProperties));
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " field: " + v.getName() + " invoke error");
|
||||
throw new RuntimeException(
|
||||
"[Sentinel Starter] DataSource " + dataSourceName
|
||||
@ -136,7 +136,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
builder.addPropertyReference("converter", customConvertBeanName);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " handle "
|
||||
+ dataSourceProperties.getClass().getSimpleName()
|
||||
+ " error, class name: "
|
||||
@ -195,20 +195,20 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
ruleConfig = dataSource.loadConfig();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " loadConfig error: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
if (ruleConfig instanceof List) {
|
||||
List convertedRuleList = (List) ruleConfig;
|
||||
if (CollectionUtils.isEmpty(convertedRuleList)) {
|
||||
logger.warn("[Sentinel Starter] DataSource {} rule list is empty.",
|
||||
log.warn("[Sentinel Starter] DataSource {} rule list is empty.",
|
||||
dataSourceName);
|
||||
return;
|
||||
}
|
||||
if (convertedRuleList.stream()
|
||||
.noneMatch(rule -> rule.getClass() == ruleClass)) {
|
||||
logger.error("[Sentinel Starter] DataSource {} none rules are {} type.",
|
||||
log.error("[Sentinel Starter] DataSource {} none rules are {} type.",
|
||||
dataSourceName, ruleClass.getSimpleName());
|
||||
throw new IllegalArgumentException("[Sentinel Starter] DataSource "
|
||||
+ dataSourceName + " none rules are " + ruleClass.getSimpleName()
|
||||
@ -216,16 +216,16 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
}
|
||||
else if (!convertedRuleList.stream()
|
||||
.allMatch(rule -> rule.getClass() == ruleClass)) {
|
||||
logger.warn("[Sentinel Starter] DataSource {} all rules are not {} type.",
|
||||
log.warn("[Sentinel Starter] DataSource {} all rules are not {} type.",
|
||||
dataSourceName, ruleClass.getSimpleName());
|
||||
}
|
||||
else {
|
||||
logger.info("[Sentinel Starter] DataSource {} load {} {}", dataSourceName,
|
||||
log.info("[Sentinel Starter] DataSource {} load {} {}", dataSourceName,
|
||||
convertedRuleList.size(), ruleClass.getSimpleName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
log.error("[Sentinel Starter] DataSource " + dataSourceName
|
||||
+ " rule class is not List<" + ruleClass.getSimpleName()
|
||||
+ ">. Class: " + ruleConfig.getClass());
|
||||
throw new IllegalArgumentException("[Sentinel Starter] DataSource "
|
||||
|
@ -22,8 +22,7 @@ import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.springframework.cloud.alibaba.sentinel.rest.SentinelClientHttpResponse;
|
||||
import org.springframework.http.HttpRequest;
|
||||
@ -43,9 +42,6 @@ import java.net.URI;
|
||||
*/
|
||||
public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(SentinelProtectInterceptor.class);
|
||||
|
||||
private final SentinelRestTemplate sentinelRestTemplate;
|
||||
|
||||
public SentinelProtectInterceptor(SentinelRestTemplate sentinelRestTemplate) {
|
||||
|
@ -27,29 +27,29 @@ import java.util.Map;
|
||||
*/
|
||||
public class AcmPropertySource extends MapPropertySource {
|
||||
|
||||
private final String dataId;
|
||||
private final String dataId;
|
||||
|
||||
private final Date timestamp;
|
||||
private final Date timestamp;
|
||||
|
||||
private final boolean groupLevel;
|
||||
private final boolean groupLevel;
|
||||
|
||||
AcmPropertySource(String dataId, Map<String, Object> source, Date timestamp,
|
||||
boolean groupLevel) {
|
||||
super(dataId, source);
|
||||
this.dataId = dataId;
|
||||
this.timestamp = timestamp;
|
||||
this.groupLevel = groupLevel;
|
||||
}
|
||||
AcmPropertySource(String dataId, Map<String, Object> source, Date timestamp,
|
||||
boolean groupLevel) {
|
||||
super(dataId, source);
|
||||
this.dataId = dataId;
|
||||
this.timestamp = timestamp;
|
||||
this.groupLevel = groupLevel;
|
||||
}
|
||||
|
||||
public String getDataId() {
|
||||
return dataId;
|
||||
}
|
||||
public String getDataId() {
|
||||
return dataId;
|
||||
}
|
||||
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public boolean isGroupLevel() {
|
||||
return groupLevel;
|
||||
}
|
||||
public boolean isGroupLevel() {
|
||||
return groupLevel;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.cloud.alicloud.acm.bootstrap;
|
||||
|
||||
import com.alibaba.edas.acm.ConfigService;
|
||||
import com.alibaba.edas.acm.exception.ConfigException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
@ -25,7 +26,11 @@ import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author juven.xuxb
|
||||
@ -33,64 +38,68 @@ import java.util.*;
|
||||
*/
|
||||
class AcmPropertySourceBuilder {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AcmPropertySourceBuilder.class);
|
||||
private Logger log = LoggerFactory.getLogger(AcmPropertySourceBuilder.class);
|
||||
|
||||
/**
|
||||
* 传入 ACM 的 DataId 和 groupID,获取到解析后的 AcmProperty 对象
|
||||
*
|
||||
* @param dataId
|
||||
* @param diamondGroup
|
||||
* @param groupLevel
|
||||
* @return
|
||||
*/
|
||||
AcmPropertySource build(String dataId, String diamondGroup, boolean groupLevel) {
|
||||
Properties properties = loadDiamondData(dataId, diamondGroup);
|
||||
if (properties == null) {
|
||||
return null;
|
||||
}
|
||||
return new AcmPropertySource(dataId, toMap(properties), new Date(), groupLevel);
|
||||
}
|
||||
/**
|
||||
* 传入 ACM 的 DataId 和 groupID,获取到解析后的 AcmProperty 对象
|
||||
*
|
||||
* @param dataId
|
||||
* @param diamondGroup
|
||||
* @param groupLevel
|
||||
* @return
|
||||
*/
|
||||
AcmPropertySource build(String dataId, String diamondGroup, boolean groupLevel) {
|
||||
Properties properties = loadDiamondData(dataId, diamondGroup);
|
||||
if (properties == null) {
|
||||
return null;
|
||||
}
|
||||
return new AcmPropertySource(dataId, toMap(properties), new Date(), groupLevel);
|
||||
}
|
||||
|
||||
private Properties loadDiamondData(String dataId, String diamondGroup) {
|
||||
try {
|
||||
String data = ConfigService.getConfig(dataId, diamondGroup, 3000L);
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
if (dataId.endsWith(".properties")) {
|
||||
Properties properties = new Properties();
|
||||
logger.info(String.format("Loading acm data, dataId: '%s', group: '%s'",
|
||||
dataId, diamondGroup));
|
||||
properties.load(new StringReader(data));
|
||||
return properties;
|
||||
} else if (dataId.endsWith(".yaml") || dataId.endsWith(".yml")) {
|
||||
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
|
||||
yamlFactory.setResources(new ByteArrayResource(data.getBytes()));
|
||||
return yamlFactory.getObject();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ConfigException) {
|
||||
logger.error("DIAMOND-100500:" + dataId + ", " + e.toString(), e);
|
||||
} else {
|
||||
logger.error("DIAMOND-100500:" + dataId, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private Properties loadDiamondData(String dataId, String diamondGroup) {
|
||||
try {
|
||||
String data = ConfigService.getConfig(dataId, diamondGroup, 3000L);
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
if (dataId.endsWith(".properties")) {
|
||||
Properties properties = new Properties();
|
||||
log.info(String.format("Loading acm data, dataId: '%s', group: '%s'",
|
||||
dataId, diamondGroup));
|
||||
properties.load(new StringReader(data));
|
||||
return properties;
|
||||
}
|
||||
else if (dataId.endsWith(".yaml") || dataId.endsWith(".yml")) {
|
||||
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
|
||||
yamlFactory.setResources(new ByteArrayResource(data.getBytes()));
|
||||
return yamlFactory.getObject();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof ConfigException) {
|
||||
log.error("DIAMOND-100500:" + dataId + ", " + e.toString(), e);
|
||||
}
|
||||
else {
|
||||
log.error("DIAMOND-100500:" + dataId, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> toMap(Properties properties) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
Enumeration<String> keys = (Enumeration<String>)properties.propertyNames();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = keys.nextElement();
|
||||
Object value = properties.getProperty(key);
|
||||
if (value != null) {
|
||||
result.put(key, ((String)value).trim());
|
||||
} else {
|
||||
result.put(key, null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> toMap(Properties properties) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = keys.nextElement();
|
||||
Object value = properties.getProperty(key);
|
||||
if (value != null) {
|
||||
result.put(key, ((String) value).trim());
|
||||
}
|
||||
else {
|
||||
result.put(key, null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -38,40 +38,40 @@ import java.util.Map;
|
||||
@Endpoint(id = "acm")
|
||||
public class AcmEndpoint {
|
||||
|
||||
private final AcmProperties properties;
|
||||
private final AcmProperties properties;
|
||||
|
||||
private final AcmRefreshHistory refreshHistory;
|
||||
private final AcmRefreshHistory refreshHistory;
|
||||
|
||||
private final AcmPropertySourceRepository propertySourceRepository;
|
||||
private final AcmPropertySourceRepository propertySourceRepository;
|
||||
|
||||
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public AcmEndpoint(AcmProperties properties, AcmRefreshHistory refreshHistory,
|
||||
AcmPropertySourceRepository propertySourceRepository) {
|
||||
this.properties = properties;
|
||||
this.refreshHistory = refreshHistory;
|
||||
this.propertySourceRepository = propertySourceRepository;
|
||||
}
|
||||
public AcmEndpoint(AcmProperties properties, AcmRefreshHistory refreshHistory,
|
||||
AcmPropertySourceRepository propertySourceRepository) {
|
||||
this.properties = properties;
|
||||
this.refreshHistory = refreshHistory;
|
||||
this.propertySourceRepository = propertySourceRepository;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("config", properties);
|
||||
@ReadOperation
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("config", properties);
|
||||
|
||||
Map<String, Object> runtime = new HashMap<>();
|
||||
List<AcmPropertySource> all = propertySourceRepository.getAll();
|
||||
Map<String, Object> runtime = new HashMap<>();
|
||||
List<AcmPropertySource> all = propertySourceRepository.getAll();
|
||||
|
||||
List<Map<String, Object>> sources = new ArrayList<>();
|
||||
for (AcmPropertySource ps : all) {
|
||||
Map<String, Object> source = new HashMap<>();
|
||||
source.put("dataId", ps.getDataId());
|
||||
source.put("lastSynced", dateFormat.format(ps.getTimestamp()));
|
||||
sources.add(source);
|
||||
}
|
||||
runtime.put("sources", sources);
|
||||
runtime.put("refreshHistory", refreshHistory.getRecords());
|
||||
List<Map<String, Object>> sources = new ArrayList<>();
|
||||
for (AcmPropertySource ps : all) {
|
||||
Map<String, Object> source = new HashMap<>();
|
||||
source.put("dataId", ps.getDataId());
|
||||
source.put("lastSynced", dateFormat.format(ps.getTimestamp()));
|
||||
sources.add(source);
|
||||
}
|
||||
runtime.put("sources", sources);
|
||||
runtime.put("refreshHistory", refreshHistory.getRecords());
|
||||
|
||||
result.put("runtime", runtime);
|
||||
return result;
|
||||
}
|
||||
result.put("runtime", runtime);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.alicloud.acm.endpoint;
|
||||
|
||||
import com.alibaba.edas.acm.ConfigService;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.cloud.alicloud.acm.AcmPropertySourceRepository;
|
||||
@ -33,39 +34,40 @@ import java.util.List;
|
||||
*/
|
||||
public class AcmHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private final AcmProperties acmProperties;
|
||||
private final AcmProperties acmProperties;
|
||||
|
||||
private final AcmPropertySourceRepository acmPropertySourceRepository;
|
||||
private final AcmPropertySourceRepository acmPropertySourceRepository;
|
||||
|
||||
private final List<String> dataIds;
|
||||
private final List<String> dataIds;
|
||||
|
||||
public AcmHealthIndicator(AcmProperties acmProperties,
|
||||
AcmPropertySourceRepository acmPropertySourceRepository) {
|
||||
this.acmProperties = acmProperties;
|
||||
this.acmPropertySourceRepository = acmPropertySourceRepository;
|
||||
public AcmHealthIndicator(AcmProperties acmProperties,
|
||||
AcmPropertySourceRepository acmPropertySourceRepository) {
|
||||
this.acmProperties = acmProperties;
|
||||
this.acmPropertySourceRepository = acmPropertySourceRepository;
|
||||
|
||||
this.dataIds = new ArrayList<>();
|
||||
for (AcmPropertySource acmPropertySource : this.acmPropertySourceRepository
|
||||
.getAll()) {
|
||||
this.dataIds.add(acmPropertySource.getDataId());
|
||||
}
|
||||
}
|
||||
this.dataIds = new ArrayList<>();
|
||||
for (AcmPropertySource acmPropertySource : this.acmPropertySourceRepository
|
||||
.getAll()) {
|
||||
this.dataIds.add(acmPropertySource.getDataId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
for (String dataId : dataIds) {
|
||||
try {
|
||||
String config = ConfigService.getConfig(dataId, acmProperties.getGroup(),
|
||||
acmProperties.getTimeout());
|
||||
if (StringUtils.isEmpty(config)) {
|
||||
builder.down().withDetail(String.format("dataId: '%s', group: '%s'",
|
||||
dataId, acmProperties.getGroup()), "config is empty");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
builder.down().withDetail(String.format("dataId: '%s', group: '%s'",
|
||||
dataId, acmProperties.getGroup()), e.getMessage());
|
||||
}
|
||||
}
|
||||
builder.up().withDetail("dataIds", dataIds);
|
||||
}
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
for (String dataId : dataIds) {
|
||||
try {
|
||||
String config = ConfigService.getConfig(dataId, acmProperties.getGroup(),
|
||||
acmProperties.getTimeout());
|
||||
if (StringUtils.isEmpty(config)) {
|
||||
builder.down().withDetail(String.format("dataId: '%s', group: '%s'",
|
||||
dataId, acmProperties.getGroup()), "config is empty");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
builder.down().withDetail(String.format("dataId: '%s', group: '%s'",
|
||||
dataId, acmProperties.getGroup()), e.getMessage());
|
||||
}
|
||||
}
|
||||
builder.up().withDetail("dataIds", dataIds);
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.alicloud.acm.refresh;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.alibaba.edas.acm.ConfigService;
|
||||
import com.alibaba.edas.acm.listener.ConfigChangeListener;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -36,8 +32,12 @@ import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.edas.acm.ConfigService;
|
||||
import com.alibaba.edas.acm.listener.ConfigChangeListener;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* On application start up, AcmContextRefresher add diamond listeners to all application
|
||||
@ -49,7 +49,7 @@ import com.alibaba.edas.acm.listener.ConfigChangeListener;
|
||||
public class AcmContextRefresher
|
||||
implements ApplicationListener<ApplicationReadyEvent>, ApplicationContextAware {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AcmContextRefresher.class);
|
||||
private Logger log = LoggerFactory.getLogger(AcmContextRefresher.class);
|
||||
|
||||
private final ContextRefresher contextRefresher;
|
||||
|
||||
@ -103,7 +103,7 @@ public class AcmContextRefresher
|
||||
}
|
||||
catch (NoSuchAlgorithmException
|
||||
| UnsupportedEncodingException e) {
|
||||
logger.warn("unable to get md5 for dataId: " + dataId, e);
|
||||
log.warn("unable to get md5 for dataId: " + dataId, e);
|
||||
}
|
||||
}
|
||||
refreshHistory.add(dataId, md5);
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.cloud.alicloud.ans;
|
||||
|
||||
import com.alibaba.ans.core.NamingService;
|
||||
import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
@ -30,6 +31,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
public class AnsDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
|
@ -28,6 +28,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
@Configuration
|
||||
@Conditional(MigrateOnConditionMissingClass.class)
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.cloud.alicloud.ans.endpoint;
|
||||
|
||||
import com.alibaba.ans.core.NamingService;
|
||||
import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
@ -31,6 +32,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
@Endpoint(id = "ans")
|
||||
public class AnsEndpoint {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.springframework.cloud.alicloud.ans.migrate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
|
||||
@ -11,7 +11,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
@Endpoint(id = "migrate")
|
||||
public class MigrateEndpoint {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MigrateEndpoint.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(MigrateEndpoint.class);
|
||||
|
||||
public MigrateEndpoint() {
|
||||
}
|
||||
|
@ -6,6 +6,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
*/
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass(value = Endpoint.class)
|
||||
@Conditional(MigrateOnConditionClass.class)
|
||||
|
@ -35,7 +35,7 @@ public abstract class MigrateOnCondition implements Condition, BeanClassLoaderAw
|
||||
forName(className, classLoader);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable var3) {
|
||||
catch (Throwable throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -45,5 +45,4 @@ public abstract class MigrateOnCondition implements Condition, BeanClassLoaderAw
|
||||
return classLoader != null ? classLoader.loadClass(className)
|
||||
: Class.forName(className);
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package org.springframework.cloud.alicloud.ans.migrate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
@ -10,13 +10,14 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
*/
|
||||
public class MigrateOnConditionClass extends MigrateOnCondition {
|
||||
|
||||
protected static final Log log = LogFactory.getLog(MigrateOnConditionClass.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MigrateOnConditionClass.class);
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
boolean result = isPresent(conditionOnClass[0], classLoader)
|
||||
|| isPresent(conditionOnClass[1], classLoader);
|
||||
log.info("the result of match is :" + result);
|
||||
log.info("the result of matcher is " + result);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package org.springframework.cloud.alicloud.ans.migrate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
@ -9,14 +9,13 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
* @author pbting
|
||||
*/
|
||||
public class MigrateOnConditionMissingClass extends MigrateOnConditionClass {
|
||||
|
||||
protected static final Log log = LogFactory
|
||||
.getLog(MigrateOnConditionMissingClass.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MigrateOnConditionMissingClass.class);
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
boolean result = !super.matches(context, metadata);
|
||||
log.info("the result of match is :" + result);
|
||||
log.info(" the result of matcher is " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.AfterReturningAdvice;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
|
||||
@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
*/
|
||||
final class MigrateProxyManager {
|
||||
|
||||
private final static Log log = LogFactory.getLog(MigrateProxyManager.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(MigrateProxyManager.class);
|
||||
private final static AtomicBoolean IS_PROXY = new AtomicBoolean(true);
|
||||
|
||||
private final static Set<String> SERVICES_ID = new ConcurrentSkipListSet<>();
|
||||
|
@ -3,8 +3,8 @@ package org.springframework.cloud.alicloud.ans.migrate;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
@ -12,7 +12,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
public class MigrateRibbonBeanPostProcessor
|
||||
implements BeanPostProcessor, BeanClassLoaderAware {
|
||||
|
||||
protected static final Log log = LogFactory.getLog(MigrateOnCondition.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(MigrateOnCondition.class);
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private IClientConfig clientConfig;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.springframework.cloud.alicloud.ans.migrate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||
import org.springframework.cloud.alicloud.ans.registry.AnsRegistration;
|
||||
import org.springframework.cloud.alicloud.ans.registry.AnsServiceRegistry;
|
||||
@ -19,7 +19,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@Component
|
||||
public class MigrateServiceRegistry {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MigrateServiceRegistry.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(MigrateServiceRegistry.class);
|
||||
|
||||
private AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
|
@ -12,6 +12,9 @@ import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@Conditional(MigrateOnConditionClass.class)
|
||||
|
@ -4,8 +4,8 @@ import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.alicloud.ans.ribbon.AnsServer;
|
||||
import org.springframework.cloud.alicloud.ans.ribbon.AnsServerList;
|
||||
|
||||
@ -22,11 +22,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author pbting
|
||||
*/
|
||||
class ServerListInvocationHandler implements MethodInterceptor {
|
||||
|
||||
private final static Log log = LogFactory.getLog(ServerListInvocationHandler.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ServerListInvocationHandler.class);
|
||||
|
||||
private final static ConcurrentMap<String, AnsServerList> SERVER_LIST_CONCURRENT_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -4,6 +4,9 @@ import com.netflix.loadbalancer.Server;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
*/
|
||||
public class ServerWrapper {
|
||||
|
||||
private Server server;
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.alicloud.ans.registry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
@ -27,10 +27,12 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
public class AnsAutoServiceRegistration
|
||||
extends AbstractAutoServiceRegistration<AnsRegistration> {
|
||||
private static final Log log = LogFactory.getLog(AnsAutoServiceRegistration.class);
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(AnsAutoServiceRegistration.class);
|
||||
|
||||
@Autowired
|
||||
private AnsRegistration registration;
|
||||
|
@ -18,9 +18,10 @@ package org.springframework.cloud.alicloud.ans.registry;
|
||||
|
||||
import com.alibaba.ans.core.NamingService;
|
||||
import com.alibaba.ans.shaded.com.taobao.vipserver.client.ipms.NodeReactor;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -32,7 +33,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class AnsServiceRegistry implements ServiceRegistry<AnsRegistration> {
|
||||
|
||||
private static Log log = LogFactory.getLog(AnsServiceRegistry.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(AnsServiceRegistry.class);
|
||||
|
||||
private static final String SEPARATOR = ",";
|
||||
|
||||
|
@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
@Configuration
|
||||
@Conditional(MigrateOnConditionMissingClass.class)
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.cloud.alicloud.ans.ribbon;
|
||||
|
||||
import com.alibaba.ans.core.NamingService;
|
||||
import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
|
||||
@ -26,6 +27,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
* @author pbting
|
||||
*/
|
||||
public class AnsServerList extends AbstractServerList<AnsServer> {
|
||||
|
||||
|
@ -1,20 +1,20 @@
|
||||
package org.springframework.cloud.alicloud.context.nacos;
|
||||
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfiguration;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.cloud.alicloud.context.listener.AbstractOnceApplicationListener;
|
||||
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfiguration;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosParameterInitListener
|
||||
public class NacosConfigParameterInitListener
|
||||
extends AbstractOnceApplicationListener<ApplicationEnvironmentPreparedEvent> {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosParameterInitListener.class);
|
||||
.getLogger(NacosConfigParameterInitListener.class);
|
||||
|
||||
@Override
|
||||
protected String conditionalOnClass() {
|
||||
@ -30,12 +30,15 @@ public class NacosParameterInitListener
|
||||
EdasChangeOrderConfiguration edasChangeOrderConfiguration = EdasChangeOrderConfigurationFactory
|
||||
.getEdasChangeOrderConfiguration();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Initialize Nacos Config Parameter ,is managed {}.",
|
||||
edasChangeOrderConfiguration.isEdasManaged());
|
||||
}
|
||||
|
||||
if (!edasChangeOrderConfiguration.isEdasManaged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Initialize Nacos Parameter from edas change order,is edas managed {}.",
|
||||
edasChangeOrderConfiguration.isEdasManaged());
|
||||
System.getProperties().setProperty("spring.cloud.nacos.config.server-mode",
|
||||
"EDAS");
|
||||
// initialize nacos configuration
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.alicloud.context.nacos;
|
||||
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfiguration;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.cloud.alicloud.context.listener.AbstractOnceApplicationListener;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author pbting
|
||||
* @date 2019-02-14 11:12 AM
|
||||
*/
|
||||
public class NacosDiscoveryParameterInitListener
|
||||
extends AbstractOnceApplicationListener<ApplicationEnvironmentPreparedEvent> {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosDiscoveryParameterInitListener.class);
|
||||
|
||||
@Override
|
||||
protected String conditionalOnClass() {
|
||||
return "org.springframework.cloud.alibaba.nacos.NacosDiscoveryAutoConfiguration";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
EdasChangeOrderConfiguration edasChangeOrderConfiguration = EdasChangeOrderConfigurationFactory
|
||||
.getEdasChangeOrderConfiguration();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Initialize Nacos Discovery Parameter ,is managed {}.",
|
||||
edasChangeOrderConfiguration.isEdasManaged());
|
||||
}
|
||||
|
||||
if (!edasChangeOrderConfiguration.isEdasManaged()) {
|
||||
return;
|
||||
}
|
||||
// initialize nacos configuration
|
||||
Properties properties = System.getProperties();
|
||||
|
||||
// step 1: set some properties for spring cloud alibaba nacos discovery
|
||||
properties.setProperty("spring.cloud.nacos.discovery.server-addr", "");
|
||||
properties.setProperty("spring.cloud.nacos.discovery.endpoint",
|
||||
edasChangeOrderConfiguration.getAddressServerDomain());
|
||||
properties.setProperty("spring.cloud.nacos.discovery.namespace",
|
||||
edasChangeOrderConfiguration.getTenantId());
|
||||
properties.setProperty("spring.cloud.nacos.discovery.access-key",
|
||||
edasChangeOrderConfiguration.getDauthAccessKey());
|
||||
properties.setProperty("spring.cloud.nacos.discovery.secret-key",
|
||||
edasChangeOrderConfiguration.getDauthSecretKey());
|
||||
|
||||
// step 2: set these properties for nacos client
|
||||
properties.setProperty("webContext", "/vipserver");
|
||||
properties.setProperty("serverPort", "80");
|
||||
}
|
||||
}
|
@ -10,5 +10,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.alicloud.context.sms.SmsContextAutoConfiguration
|
||||
org.springframework.context.ApplicationListener=\
|
||||
org.springframework.cloud.alicloud.context.ans.AnsContextApplicationListener,\
|
||||
org.springframework.cloud.alicloud.context.nacos.NacosParameterInitListener,\
|
||||
org.springframework.cloud.alicloud.context.nacos.NacosConfigParameterInitListener,\
|
||||
org.springframework.cloud.alicloud.context.nacos.NacosDiscoveryParameterInitListener,\
|
||||
org.springframework.cloud.alicloud.context.sentinel.SentinelAliCloudListener
|
@ -16,7 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.alicloud.context.nacos;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import com.alibaba.cloud.context.ans.AliCloudAnsInitializer;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@ -24,15 +25,14 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.springframework.cloud.alicloud.context.BaseAliCloudSpringApplication;
|
||||
import org.springframework.cloud.alicloud.utils.ChangeOrderUtils;
|
||||
|
||||
import com.alibaba.cloud.context.ans.AliCloudAnsInitializer;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
*/
|
||||
@PrepareForTest({ EdasChangeOrderConfigurationFactory.class,
|
||||
NacosParameterInitListener.class, AliCloudAnsInitializer.class })
|
||||
public class NacosParameterInitListenerTests extends BaseAliCloudSpringApplication {
|
||||
NacosConfigParameterInitListener.class, AliCloudAnsInitializer.class })
|
||||
public class NacosConfigParameterInitListenerTests extends BaseAliCloudSpringApplication {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.alicloud.context.nacos;
|
||||
|
||||
import com.alibaba.cloud.context.ans.AliCloudAnsInitializer;
|
||||
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.springframework.cloud.alicloud.context.BaseAliCloudSpringApplication;
|
||||
import org.springframework.cloud.alicloud.utils.ChangeOrderUtils;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
/**
|
||||
* @author xiaolongzuo
|
||||
*/
|
||||
@PrepareForTest({EdasChangeOrderConfigurationFactory.class,
|
||||
NacosConfigParameterInitListener.class, AliCloudAnsInitializer.class})
|
||||
public class NacosDiscoveryParameterInitListenerTests extends BaseAliCloudSpringApplication {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
ChangeOrderUtils.mockChangeOrder();
|
||||
System.getProperties().setProperty("webContext", "/vipserver");
|
||||
System.getProperties().setProperty("serverPort", "80");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNacosParameterInitListener() {
|
||||
assertThat(System.getProperty("spring.cloud.nacos.config.server-addr"))
|
||||
.isEqualTo("");
|
||||
assertThat(System.getProperty("spring.cloud.nacos.config.endpoint"))
|
||||
.isEqualTo("testDomain");
|
||||
assertThat(System.getProperty("spring.cloud.nacos.config.namespace"))
|
||||
.isEqualTo("testTenantId");
|
||||
assertThat(System.getProperty("spring.cloud.nacos.config.access-key"))
|
||||
.isEqualTo("testAK");
|
||||
assertThat(System.getProperty("spring.cloud.nacos.config.secret-key"))
|
||||
.isEqualTo("testSK");
|
||||
assertThat(System.getProperties().getProperty("webContext")).isEqualTo("/vipserver");
|
||||
assertThat(System.getProperties().getProperty("serverPort")).isEqualTo("80");
|
||||
}
|
||||
}
|
@ -20,26 +20,4 @@
|
||||
<module>spring-cloud-starter-stream-rocketmq</module>
|
||||
<module>spring-cloud-starter-bus-rocketmq</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -17,26 +17,4 @@
|
||||
<module>spring-cloud-starter-alicloud-schedulerx</module>
|
||||
<module>spring-cloud-starter-alicloud-sms</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
<check/>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -22,6 +22,7 @@ import org.apache.rocketmq.client.producer.TransactionCheckListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.stream.binder.AbstractMessageChannelBinder;
|
||||
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
|
||||
import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
|
||||
import org.springframework.cloud.stream.binder.ExtendedProducerProperties;
|
||||
import org.springframework.cloud.stream.binder.ExtendedPropertiesBinder;
|
||||
@ -53,19 +54,18 @@ public class RocketMQMessageChannelBinder extends
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(RocketMQMessageChannelBinder.class);
|
||||
|
||||
private final RocketMQExtendedBindingProperties extendedBindingProperties;
|
||||
private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
|
||||
private final InstrumentationManager instrumentationManager;
|
||||
private final ConsumersManager consumersManager;
|
||||
|
||||
private RocketMQExtendedBindingProperties extendedBindingProperties = new RocketMQExtendedBindingProperties();
|
||||
|
||||
public RocketMQMessageChannelBinder(ConsumersManager consumersManager,
|
||||
RocketMQExtendedBindingProperties extendedBindingProperties,
|
||||
RocketMQTopicProvisioner provisioningProvider,
|
||||
RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
|
||||
InstrumentationManager instrumentationManager) {
|
||||
super(null, provisioningProvider);
|
||||
this.consumersManager = consumersManager;
|
||||
this.extendedBindingProperties = extendedBindingProperties;
|
||||
this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
|
||||
this.instrumentationManager = instrumentationManager;
|
||||
}
|
||||
@ -143,6 +143,16 @@ public class RocketMQMessageChannelBinder extends
|
||||
return extendedBindingProperties.getExtendedProducerProperties(channelName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultsPrefix() {
|
||||
return extendedBindingProperties.getDefaultsPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
|
||||
return extendedBindingProperties.getExtendedPropertiesEntryClass();
|
||||
}
|
||||
|
||||
private <T> T getClassConfiguration(String destName, String className,
|
||||
Class<T> interfaceClass) {
|
||||
if (StringUtils.isEmpty(className)) {
|
||||
@ -184,4 +194,9 @@ public class RocketMQMessageChannelBinder extends
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setExtendedBindingProperties(
|
||||
RocketMQExtendedBindingProperties extendedBindingProperties) {
|
||||
this.extendedBindingProperties = extendedBindingProperties;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,8 +64,9 @@ public class RocketMQBinderAutoConfiguration {
|
||||
RocketMQTopicProvisioner provisioningProvider,
|
||||
ConsumersManager consumersManager) {
|
||||
RocketMQMessageChannelBinder binder = new RocketMQMessageChannelBinder(
|
||||
consumersManager, extendedBindingProperties, provisioningProvider,
|
||||
consumersManager, provisioningProvider,
|
||||
rocketBinderConfigurationProperties, instrumentationManager);
|
||||
binder.setExtendedBindingProperties(extendedBindingProperties);
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
@ -16,16 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.stream.binder.rocketmq.properties;
|
||||
|
||||
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
|
||||
|
||||
/**
|
||||
* @author Timur Valiev
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
public class RocketMQBindingProperties {
|
||||
public class RocketMQBindingProperties implements BinderSpecificPropertiesProvider {
|
||||
|
||||
private RocketMQConsumerProperties consumer = new RocketMQConsumerProperties();
|
||||
|
||||
private RocketMQProducerProperties producer = new RocketMQProducerProperties();
|
||||
|
||||
@Override
|
||||
public RocketMQConsumerProperties getConsumer() {
|
||||
return consumer;
|
||||
}
|
||||
@ -34,6 +37,7 @@ public class RocketMQBindingProperties {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RocketMQProducerProperties getProducer() {
|
||||
return producer;
|
||||
}
|
||||
|
@ -16,71 +16,27 @@
|
||||
|
||||
package org.springframework.cloud.stream.binder.rocketmq.properties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.stream.binder.ExtendedBindingProperties;
|
||||
import org.springframework.cloud.stream.binder.AbstractExtendedBindingProperties;
|
||||
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
|
||||
|
||||
/**
|
||||
* @author Timur Valiev
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.stream.rocketmq")
|
||||
public class RocketMQExtendedBindingProperties implements
|
||||
ExtendedBindingProperties<RocketMQConsumerProperties, RocketMQProducerProperties> {
|
||||
public class RocketMQExtendedBindingProperties extends
|
||||
AbstractExtendedBindingProperties<RocketMQConsumerProperties, RocketMQProducerProperties, RocketMQBindingProperties> {
|
||||
|
||||
private Map<String, RocketMQBindingProperties> bindings = new HashMap<>();
|
||||
private static final String DEFAULTS_PREFIX = "spring.cloud.stream.rocketmq.default";
|
||||
|
||||
public Map<String, RocketMQBindingProperties> getBindings() {
|
||||
return this.bindings;
|
||||
}
|
||||
|
||||
public void setBindings(Map<String, RocketMQBindingProperties> bindings) {
|
||||
this.bindings = bindings;
|
||||
@Override
|
||||
public String getDefaultsPrefix() {
|
||||
return DEFAULTS_PREFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized RocketMQConsumerProperties getExtendedConsumerProperties(
|
||||
String channelName) {
|
||||
if (bindings.containsKey(channelName)) {
|
||||
if (bindings.get(channelName).getConsumer() != null) {
|
||||
return bindings.get(channelName).getConsumer();
|
||||
}
|
||||
else {
|
||||
RocketMQConsumerProperties properties = new RocketMQConsumerProperties();
|
||||
this.bindings.get(channelName).setConsumer(properties);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RocketMQConsumerProperties properties = new RocketMQConsumerProperties();
|
||||
RocketMQBindingProperties rbp = new RocketMQBindingProperties();
|
||||
rbp.setConsumer(properties);
|
||||
bindings.put(channelName, rbp);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized RocketMQProducerProperties getExtendedProducerProperties(
|
||||
String channelName) {
|
||||
if (bindings.containsKey(channelName)) {
|
||||
if (bindings.get(channelName).getProducer() != null) {
|
||||
return bindings.get(channelName).getProducer();
|
||||
}
|
||||
else {
|
||||
RocketMQProducerProperties properties = new RocketMQProducerProperties();
|
||||
this.bindings.get(channelName).setProducer(properties);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RocketMQProducerProperties properties = new RocketMQProducerProperties();
|
||||
RocketMQBindingProperties rbp = new RocketMQBindingProperties();
|
||||
rbp.setProducer(properties);
|
||||
bindings.put(channelName, rbp);
|
||||
return properties;
|
||||
}
|
||||
public Class<? extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
|
||||
return RocketMQBindingProperties.class;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user