mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
基于F版的一些适配性调整
This commit is contained in:
parent
c579109d2a
commit
0db3b26fd6
131
pom.xml
131
pom.xml
@ -45,8 +45,10 @@
|
||||
<email>flystar32@163.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>fangjian</name>
|
||||
<name>Jim Fang</name>
|
||||
<email>fangjian0423@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/fangjian0423</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>xiaolongzuo</name>
|
||||
@ -76,7 +78,9 @@
|
||||
<spring-cloud-openfeign.version>2.0.4.RELEASE</spring-cloud-openfeign.version>
|
||||
<spring-cloud-bus.version>2.0.2.RELEASE</spring-cloud-bus.version>
|
||||
<spring-cloud-gateway.version>2.0.4.RELEASE</spring-cloud-gateway.version>
|
||||
<spring-cloud-stream.version>Elmhurst.SR3</spring-cloud-stream.version>
|
||||
<spring-cloud-consul.version>2.0.3.RELEASE</spring-cloud-consul.version>
|
||||
<spring-cloud-config.version>2.0.5.RELEASE</spring-cloud-config.version>
|
||||
<spring-cloud-zookeeper.version>2.0.2.RELEASE</spring-cloud-zookeeper.version>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
@ -84,7 +88,7 @@
|
||||
<slf4j-api.version>1.7.25</slf4j-api.version>
|
||||
|
||||
<!-- Apache Dubbo -->
|
||||
<dubbo.version>2.7.3</dubbo.version>
|
||||
<dubbo.version>2.7.4.1</dubbo.version>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
|
||||
<!-- Apache RocketMQ -->
|
||||
@ -96,6 +100,13 @@
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<jacoco.version>0.8.3</jacoco.version>
|
||||
<spring-javaformat.version>0.0.9</spring-javaformat.version>
|
||||
|
||||
<!-- checkstyle -->
|
||||
<puppycrawl-tools-checkstyle.version>8.18</puppycrawl-tools-checkstyle.version>
|
||||
<spring-javaformat-checkstyle.version>0.0.7</spring-javaformat-checkstyle.version>
|
||||
<maven-checkstyle-plugin.version>3.0.0</maven-checkstyle-plugin.version>
|
||||
<nohttp-checkstyle.version>0.0.2.RELEASE</nohttp-checkstyle.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
@ -109,7 +120,7 @@
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Boot -->
|
||||
<!-- Spring Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
@ -143,7 +154,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<artifactId>spring-cloud-netflix-dependencies</artifactId>
|
||||
<version>${spring-cloud-netflix.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
@ -157,6 +168,14 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-dependencies</artifactId>
|
||||
<version>${spring-cloud-config.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-bus-dependencies</artifactId>
|
||||
@ -173,6 +192,14 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-dependencies</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-consul-dependencies</artifactId>
|
||||
@ -189,6 +216,21 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Dubbo Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-bom</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
@ -208,15 +250,7 @@
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
@ -230,6 +264,15 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@ -252,6 +295,56 @@
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
<version>${spring-javaformat.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>${maven-checkstyle-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>${puppycrawl-tools-checkstyle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-checkstyle</artifactId>
|
||||
<version>${spring-javaformat-checkstyle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build-tools</artifactId>
|
||||
<version>${spring-cloud-build.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.nohttp</groupId>
|
||||
<artifactId>nohttp-checkstyle</artifactId>
|
||||
<version>${nohttp-checkstyle.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>checkstyle-validation</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Checkstyle rules inherited from spring-cloud-build -->
|
||||
<suppressionsLocation>eclipse/checkstyle-suppressions.xml</suppressionsLocation>
|
||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@ -276,7 +369,17 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<profiles>
|
||||
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
<repositories>
|
||||
@ -338,6 +441,8 @@
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
@ -28,12 +28,6 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
|
@ -18,8 +18,8 @@
|
||||
<description>Spring Cloud Alibaba Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<sentinel.version>1.7.0</sentinel.version>
|
||||
<seata.version>0.9.0</seata.version>
|
||||
<sentinel.version>1.7.1</sentinel.version>
|
||||
<seata.version>1.1.0</seata.version>
|
||||
<nacos.client.version>1.2.1</nacos.client.version>
|
||||
<nacos.config.version>0.8.0</nacos.config.version>
|
||||
<aliyun.sdk.version>4.4.1</aliyun.sdk.version>
|
||||
@ -34,42 +34,6 @@
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- Alibaba -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>alicloud-context</artifactId>
|
||||
<version>${alicloud.context.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-edas</artifactId>
|
||||
<version>${aliyun.sdk.edas.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
<version>${aliyun.sdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SMS -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.mns</groupId>
|
||||
<artifactId>aliyun-sdk-mns</artifactId>
|
||||
<version>${aliyun.sdk.mns}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>${aliyun.java.sdk.dysmsapi}</version>
|
||||
</dependency>
|
||||
|
||||
<!--Nacos-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
@ -89,6 +53,7 @@
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-parameter-flow-control</artifactId>
|
||||
@ -99,31 +64,37 @@
|
||||
<artifactId>sentinel-datasource-extension</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-apollo</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-zookeeper</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-nacos</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-redis</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-web-servlet</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-zuul-adapter</artifactId>
|
||||
@ -134,21 +105,25 @@
|
||||
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-annotation-aspectj</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-dubbo-adapter</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
|
||||
@ -166,11 +141,13 @@
|
||||
<artifactId>sentinel-cluster-server-default</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-cluster-client-default</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-webflux-adapter</artifactId>
|
||||
@ -196,11 +173,6 @@
|
||||
</dependency>
|
||||
|
||||
<!-- Own dependencies -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sentinel</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
|
||||
@ -211,71 +183,6 @@
|
||||
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-oss</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-nacos-config-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-seata</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-acm</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-ans</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-schedulerx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-sms</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alicloud-context</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dubbo</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sidecar</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Own dependencies - Starters -->
|
||||
<dependency>
|
||||
@ -284,12 +191,6 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
@ -313,24 +214,6 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alicloud-ans</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alicloud-acm</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alicloud-schedulerx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
@ -368,6 +251,7 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<profiles>
|
||||
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
<repositories>
|
||||
@ -419,7 +303,16 @@
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/libs-release-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
</project>
|
||||
|
@ -6,7 +6,9 @@
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-alibaba-docs</artifactId>
|
||||
|
@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>nacos-discovery-example</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>nacos-discovery-consumer-sclb-example</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Example demonstrating how to use nacos discovery</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||
<!-- <artifactId>spring-cloud-starter-loadbalancer</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>${maven-deploy-plugin.version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/test`
|
||||
let n++
|
||||
done
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/divide-feign2?a=1`
|
||||
let n++
|
||||
done
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/divide-feign?a=1\&b=0`
|
||||
let n++
|
||||
done
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/index`
|
||||
let n++
|
||||
done
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/echo-rest/resttemplate`
|
||||
let n++
|
||||
done
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
n=1
|
||||
while [ $n -le 10 ]
|
||||
do
|
||||
echo `curl -s http://localhost:18083/sleep`
|
||||
let n++
|
||||
done
|
@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.alibaba.cloud.examples.ConsumerSCLBApplication.EchoService;
|
||||
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.EmptyResponse;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.Request;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.Response;
|
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
|
||||
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient(autoRegister = false)
|
||||
@EnableFeignClients
|
||||
public class ConsumerSCLBApplication {
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
@SentinelRestTemplate(urlCleanerClass = UrlCleaner.class, urlCleaner = "clean")
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
@SentinelRestTemplate
|
||||
public RestTemplate restTemplate1() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ConsumerSCLBApplication.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@LoadBalancerClient(value = "service-provider",
|
||||
configuration = MyLoadBalancerConfiguration.class)
|
||||
class MySCLBConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class RandomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(RandomLoadBalancer.class);
|
||||
|
||||
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
|
||||
|
||||
private final String serviceId;
|
||||
|
||||
private final Random random;
|
||||
|
||||
RandomLoadBalancer(
|
||||
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
|
||||
String serviceId) {
|
||||
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
|
||||
this.serviceId = serviceId;
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Response<ServiceInstance>> choose(Request request) {
|
||||
log.info("random spring cloud loadbalacer active -.-");
|
||||
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
|
||||
.getIfAvailable(NoopServiceInstanceListSupplier::new);
|
||||
return supplier.get().next().map(this::getInstanceResponse);
|
||||
}
|
||||
|
||||
private Response<ServiceInstance> getInstanceResponse(
|
||||
List<ServiceInstance> instances) {
|
||||
if (instances.isEmpty()) {
|
||||
return new EmptyResponse();
|
||||
}
|
||||
ServiceInstance instance = instances.get(random.nextInt(instances.size()));
|
||||
|
||||
return new DefaultResponse(instance);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class,
|
||||
configuration = FeignConfiguration.class)
|
||||
public interface EchoService {
|
||||
|
||||
@GetMapping("/echo/{str}")
|
||||
String echo(@PathVariable("str") String str);
|
||||
|
||||
@GetMapping("/divide")
|
||||
String divide(@RequestParam("a") Integer a, @RequestParam("b") Integer b);
|
||||
|
||||
default String divide(Integer a) {
|
||||
return divide(a, 0);
|
||||
}
|
||||
|
||||
@GetMapping("/notFound")
|
||||
String notFound();
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
class TestController {
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate1;
|
||||
|
||||
@Autowired
|
||||
private EchoService echoService;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
@GetMapping("/echo-rest/{str}")
|
||||
public String rest(@PathVariable String str) {
|
||||
return restTemplate.getForObject("http://service-provider/echo/" + str,
|
||||
String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/echo-feign/{str}")
|
||||
public String feign(@PathVariable String str) {
|
||||
return echoService.echo(str);
|
||||
}
|
||||
|
||||
@GetMapping("/index")
|
||||
public String index() {
|
||||
return restTemplate1.getForObject("http://service-provider", String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
public String test() {
|
||||
return restTemplate1.getForObject("http://service-provider/test",
|
||||
String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/sleep")
|
||||
public String sleep() {
|
||||
return restTemplate1.getForObject("http://service-provider/sleep",
|
||||
String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/notFound-feign")
|
||||
public String notFound() {
|
||||
return echoService.notFound();
|
||||
}
|
||||
|
||||
@GetMapping("/divide-feign")
|
||||
public String divide(@RequestParam Integer a, @RequestParam Integer b) {
|
||||
return echoService.divide(a, b);
|
||||
}
|
||||
|
||||
@GetMapping("/divide-feign2")
|
||||
public String divide(@RequestParam Integer a) {
|
||||
return echoService.divide(a);
|
||||
}
|
||||
|
||||
@GetMapping("/services/{service}")
|
||||
public Object client(@PathVariable String service) {
|
||||
return discoveryClient.getInstances(service);
|
||||
}
|
||||
|
||||
@GetMapping("/services")
|
||||
public Object services() {
|
||||
return discoveryClient.getServices();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FeignConfiguration {
|
||||
|
||||
@Bean
|
||||
public EchoServiceFallback echoServiceFallback() {
|
||||
return new EchoServiceFallback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class EchoServiceFallback implements EchoService {
|
||||
|
||||
@Override
|
||||
public String echo(@PathVariable("str") String str) {
|
||||
return "echo fallback";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String divide(@RequestParam Integer a, @RequestParam Integer b) {
|
||||
return "divide fallback";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String notFound() {
|
||||
return "notFound fallback";
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.cloud.examples.ConsumerSCLBApplication.RandomLoadBalancer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
public class MyLoadBalancerConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(
|
||||
Environment environment,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
|
||||
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
|
||||
ServiceInstanceListSupplier.class), name);
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
public class UrlCleaner {
|
||||
|
||||
public static String clean(String url) {
|
||||
System.out.println("enter urlCleaner");
|
||||
if (url.matches(".*/echo/.*")) {
|
||||
System.out.println("change url");
|
||||
url = url.replaceAll("/echo/.*", "/echo/{str}");
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
spring.application.name=service-consumer-sclb
|
||||
server.port=18083
|
||||
management.endpoints.web.exposure.include=*
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
|
||||
spring.cloud.nacos.username=nacos
|
||||
spring.cloud.nacos.password=nacos
|
||||
|
||||
spring.cloud.loadbalancer.ribbon.enabled=false
|
||||
|
||||
feign.sentinel.enabled=true
|
||||
|
||||
spring.cloud.sentinel.transport.dashboard=localhost:8080
|
||||
spring.cloud.sentinel.eager=true
|
||||
|
||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||
spring.cloud.sentinel.datasource.ds1.file.data-type=json
|
||||
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
spring.cloud.sentinel.datasource.ds2.file.file=classpath: degraderule.json
|
||||
spring.cloud.sentinel.datasource.ds2.file.data-type=json
|
||||
spring.cloud.sentinel.datasource.ds2.file.rule-type=degrade
|
@ -1,26 +0,0 @@
|
||||
[
|
||||
{
|
||||
"resource": "GET:http://service-provider/test",
|
||||
"count": 0.5,
|
||||
"grade": 1,
|
||||
"timeWindow": 30
|
||||
},
|
||||
{
|
||||
"resource": "GET:http://service-provider",
|
||||
"count": 0.5,
|
||||
"grade": 1,
|
||||
"timeWindow": 10
|
||||
},
|
||||
{
|
||||
"resource": "GET:http://service-provider/sleep",
|
||||
"count": 20.0,
|
||||
"grade": 0,
|
||||
"timeWindow": 30
|
||||
},
|
||||
{
|
||||
"resource": "GET:http://service-provider/divide",
|
||||
"count": 0.5,
|
||||
"grade": 1,
|
||||
"timeWindow": 30
|
||||
}
|
||||
]
|
@ -1,10 +0,0 @@
|
||||
[
|
||||
{
|
||||
"resource": "GET:http://service-provider/echo/{str}",
|
||||
"controlBehavior": 0,
|
||||
"count": 2,
|
||||
"grade": 1,
|
||||
"limitApp": "default",
|
||||
"strategy": 0
|
||||
}
|
||||
]
|
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>nacos-discovery-example</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>nacos-reactivediscovery-consumer-example</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Example demonstrating how to use nacos discovery</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||
<!-- <artifactId>spring-cloud-starter-loadbalancer</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>${maven-deploy-plugin.version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ConsumerReactiveApplication {
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
public WebClient.Builder webClient() {
|
||||
return WebClient.builder();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ConsumerReactiveApplication.class, args);
|
||||
}
|
||||
|
||||
@RestController
|
||||
class MyController {
|
||||
|
||||
@Autowired
|
||||
private ReactiveDiscoveryClient reactiveDiscoveryClient;
|
||||
|
||||
@Autowired
|
||||
private WebClient.Builder webClientBuilder;
|
||||
|
||||
@GetMapping("/all-services")
|
||||
public Flux<String> allServices() {
|
||||
return reactiveDiscoveryClient.getInstances("service-provider")
|
||||
.map(serviceInstance -> serviceInstance.getHost() + ":"
|
||||
+ serviceInstance.getPort());
|
||||
}
|
||||
|
||||
@GetMapping("/service-call/{name}")
|
||||
public Mono<String> serviceCall(@PathVariable("name") String name) {
|
||||
return webClientBuilder.build().get()
|
||||
.uri("http://service-provider/echo/" + name).retrieve()
|
||||
.bodyToMono(String.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
spring.application.name=service-consumer-reactive
|
||||
server.port=18083
|
||||
management.endpoints.web.exposure.include=*
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
|
||||
spring.cloud.nacos.username=nacos
|
||||
spring.cloud.nacos.password=nacos
|
||||
|
||||
spring.cloud.loadbalancer.ribbon.enabled=false
|
@ -18,8 +18,6 @@
|
||||
|
||||
<modules>
|
||||
<module>nacos-discovery-consumer-example</module>
|
||||
<module>nacos-discovery-consumer-sclb-example</module>
|
||||
<module>nacos-reactivediscovery-consumer-example</module>
|
||||
<module>nacos-discovery-provider-example</module>
|
||||
<module>nacos-discovery-spring-cloud-config-server-example</module>
|
||||
<module>nacos-discovery-spring-cloud-config-client-example</module>
|
||||
|
@ -16,18 +16,11 @@
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelCircuitBreakerFactory;
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder;
|
||||
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@ -54,18 +47,6 @@ public class ServiceApplication {
|
||||
return new JsonFlowRuleListConverter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<SentinelCircuitBreakerFactory> defaultConfig() {
|
||||
return factory -> {
|
||||
factory.configureDefault(
|
||||
id -> new SentinelConfigBuilder().resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100)
|
||||
.setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ServiceApplication.class, args);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package com.alibaba.cloud.examples;
|
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
@ -33,9 +32,6 @@ public class TestController {
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private CircuitBreakerFactory circuitBreakerFactory;
|
||||
|
||||
@GetMapping("/hello")
|
||||
@SentinelResource("resource")
|
||||
public String hello() {
|
||||
@ -58,17 +54,4 @@ public class TestController {
|
||||
return restTemplate.getForObject("http://www.taobao.com/test", String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/slow")
|
||||
public String slow() {
|
||||
return circuitBreakerFactory.create("slow").run(() -> {
|
||||
try {
|
||||
Thread.sleep(500L);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "slow";
|
||||
}, throwable -> "fallback");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,16 +16,9 @@
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.ReactiveSentinelCircuitBreakerFactory;
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder;
|
||||
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -53,23 +46,4 @@ public class MyConfiguration {
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<ReactiveSentinelCircuitBreakerFactory> slowCustomizer() {
|
||||
return factory -> {
|
||||
factory.configure(builder -> builder.rules(Collections.singletonList(
|
||||
new DegradeRule("slow_mono").setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setCount(100).setTimeWindow(5))),
|
||||
"slow_mono");
|
||||
factory.configure(builder -> builder.rules(Collections.singletonList(
|
||||
new DegradeRule("slow_flux").setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setCount(100).setTimeWindow(5))),
|
||||
"slow_flux");
|
||||
factory.configureDefault(id -> new SentinelConfigBuilder().resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
|
||||
.setCount(0.5).setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,11 +20,8 @@ import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
@ -32,9 +29,6 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
@RestController
|
||||
public class SentinelWebFluxController {
|
||||
|
||||
@Autowired
|
||||
private ReactiveCircuitBreakerFactory circuitBreakerFactory;
|
||||
|
||||
@GetMapping("/mono")
|
||||
public Mono<String> mono() {
|
||||
return Mono.just("simple string")
|
||||
@ -56,26 +50,4 @@ public class SentinelWebFluxController {
|
||||
.transform(new SentinelReactorTransformer<>("flux"));
|
||||
}
|
||||
|
||||
@GetMapping("/cbSlow")
|
||||
public Mono<String> cbSlow() {
|
||||
int delaySecs = 2;
|
||||
return WebClient.builder().baseUrl("http://httpbin.org/").build().get()
|
||||
.uri("/delay/" + delaySecs).retrieve().bodyToMono(String.class)
|
||||
.transform(it -> circuitBreakerFactory.create("slow_mono").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/cbError")
|
||||
public Mono<String> cbError() {
|
||||
String code = "500";
|
||||
return WebClient.builder().baseUrl("http://httpbin.org/").build().get()
|
||||
.uri("/status/" + code).retrieve().bodyToMono(String.class)
|
||||
.transform(it -> circuitBreakerFactory.create("cbError").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -104,30 +104,30 @@
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.jboss.resteasy</groupId>-->
|
||||
<!-- <artifactId>resteasy-jaxrs</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.jboss.resteasy</groupId>-->
|
||||
<!-- <artifactId>resteasy-client</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.jboss.resteasy</groupId>-->
|
||||
<!-- <artifactId>resteasy-netty4</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-netty4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.jboss.resteasy</groupId>-->
|
||||
<!-- <artifactId>resteasy-jackson-provider</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jackson-provider</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.jboss.resteasy</groupId>-->
|
||||
<!-- <artifactId>resteasy-jaxb-provider</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxb-provider</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
|
@ -23,7 +23,6 @@
|
||||
<module>spring-cloud-starter-bus-rocketmq</module>
|
||||
<module>spring-cloud-starter-dubbo</module>
|
||||
<module>spring-cloud-starter-alibaba-sidecar</module>
|
||||
<module>spring-cloud-circuitbreaker-sentinel</module>
|
||||
<module>spring-cloud-starter-alibaba-sentinel</module>
|
||||
<module>spring-cloud-alibaba-sentinel-datasource</module>
|
||||
<module>spring-cloud-alibaba-sentinel-gateway</module>
|
||||
|
@ -2,4 +2,4 @@ nacos = com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource
|
||||
file =com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource
|
||||
apollo = com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource
|
||||
zk = com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource
|
||||
redis = com.alibaba.csp.sentinel.datasource.redis.RedisDataSource
|
||||
redis = com.alibaba.csp.sentinel.datasource.redis.RedisDataSource
|
||||
|
@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-starters</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
|
||||
<name>Spring Cloud Circuit Breaker Sentinel</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-reactor-adapter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.adapter.reactor.EntryConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Sentinel implementation of {@link ReactiveCircuitBreaker}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class ReactiveSentinelCircuitBreaker implements ReactiveCircuitBreaker {
|
||||
|
||||
private final String resourceName;
|
||||
|
||||
private final EntryType entryType;
|
||||
|
||||
private final List<DegradeRule> rules;
|
||||
|
||||
public ReactiveSentinelCircuitBreaker(String resourceName, EntryType entryType,
|
||||
List<DegradeRule> rules) {
|
||||
Assert.hasText(resourceName, "resourceName cannot be blank");
|
||||
Assert.notNull(rules, "rules should not be null");
|
||||
this.resourceName = resourceName;
|
||||
this.entryType = entryType;
|
||||
this.rules = Collections.unmodifiableList(rules);
|
||||
|
||||
applyToSentinelRuleManager();
|
||||
}
|
||||
|
||||
public ReactiveSentinelCircuitBreaker(String resourceName, List<DegradeRule> rules) {
|
||||
this(resourceName, EntryType.OUT, rules);
|
||||
}
|
||||
|
||||
public ReactiveSentinelCircuitBreaker(String resourceName) {
|
||||
this(resourceName, EntryType.OUT, Collections.emptyList());
|
||||
}
|
||||
|
||||
private void applyToSentinelRuleManager() {
|
||||
if (this.rules == null || this.rules.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<DegradeRule> ruleSet = new HashSet<>(DegradeRuleManager.getRules());
|
||||
for (DegradeRule rule : this.rules) {
|
||||
if (rule == null) {
|
||||
continue;
|
||||
}
|
||||
rule.setResource(resourceName);
|
||||
ruleSet.add(rule);
|
||||
}
|
||||
DegradeRuleManager.loadRules(new ArrayList<>(ruleSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<T> run(Mono<T> toRun, Function<Throwable, Mono<T>> fallback) {
|
||||
Mono<T> toReturn = toRun.transform(new SentinelReactorTransformer<>(
|
||||
new EntryConfig(resourceName, entryType)));
|
||||
if (fallback != null) {
|
||||
toReturn = toReturn.onErrorResume(fallback);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Flux<T> run(Flux<T> toRun, Function<Throwable, Flux<T>> fallback) {
|
||||
Flux<T> toReturn = toRun.transform(new SentinelReactorTransformer<>(
|
||||
new EntryConfig(resourceName, entryType)));
|
||||
if (fallback != null) {
|
||||
toReturn = toReturn.onErrorResume(fallback);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(
|
||||
name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux" })
|
||||
@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.sentinel.enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public class ReactiveSentinelCircuitBreakerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class)
|
||||
public ReactiveCircuitBreakerFactory reactiveSentinelCircuitBreakerFactory() {
|
||||
return new ReactiveSentinelCircuitBreakerFactory();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(
|
||||
name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux" })
|
||||
public static class ReactiveSentinelCustomizerConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<Customizer<ReactiveSentinelCircuitBreakerFactory>> customizers = new ArrayList<>();
|
||||
|
||||
@Autowired(required = false)
|
||||
private ReactiveSentinelCircuitBreakerFactory factory;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
customizers.forEach(customizer -> customizer.customize(factory));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder.SentinelCircuitBreakerConfiguration;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Factory for {@link ReactiveSentinelCircuitBreaker}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class ReactiveSentinelCircuitBreakerFactory extends
|
||||
ReactiveCircuitBreakerFactory<SentinelCircuitBreakerConfiguration, SentinelConfigBuilder> {
|
||||
|
||||
private Function<String, SentinelConfigBuilder.SentinelCircuitBreakerConfiguration> defaultConfiguration = id -> new SentinelConfigBuilder()
|
||||
.resourceName(id).rules(new ArrayList<>()).build();
|
||||
|
||||
@Override
|
||||
public ReactiveCircuitBreaker create(String id) {
|
||||
Assert.hasText(id, "A CircuitBreaker must have an id.");
|
||||
SentinelConfigBuilder.SentinelCircuitBreakerConfiguration conf = getConfigurations()
|
||||
.computeIfAbsent(id, defaultConfiguration);
|
||||
return new ReactiveSentinelCircuitBreaker(id, conf.getEntryType(),
|
||||
conf.getRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SentinelConfigBuilder configBuilder(String id) {
|
||||
return new SentinelConfigBuilder(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefault(
|
||||
Function<String, SentinelCircuitBreakerConfiguration> defaultConfiguration) {
|
||||
this.defaultConfiguration = defaultConfiguration;
|
||||
}
|
||||
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Sentinel implementation of {@link CircuitBreaker}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class SentinelCircuitBreaker implements CircuitBreaker {
|
||||
|
||||
private final String resourceName;
|
||||
|
||||
private final EntryType entryType;
|
||||
|
||||
private final List<DegradeRule> rules;
|
||||
|
||||
public SentinelCircuitBreaker(String resourceName, EntryType entryType,
|
||||
List<DegradeRule> rules) {
|
||||
Assert.hasText(resourceName, "resourceName cannot be blank");
|
||||
Assert.notNull(rules, "rules should not be null");
|
||||
this.resourceName = resourceName;
|
||||
this.entryType = entryType;
|
||||
this.rules = Collections.unmodifiableList(rules);
|
||||
|
||||
applyToSentinelRuleManager();
|
||||
}
|
||||
|
||||
public SentinelCircuitBreaker(String resourceName, List<DegradeRule> rules) {
|
||||
this(resourceName, EntryType.OUT, rules);
|
||||
}
|
||||
|
||||
public SentinelCircuitBreaker(String resourceName) {
|
||||
this(resourceName, EntryType.OUT, Collections.emptyList());
|
||||
}
|
||||
|
||||
private void applyToSentinelRuleManager() {
|
||||
if (this.rules == null || this.rules.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<DegradeRule> ruleSet = new HashSet<>(DegradeRuleManager.getRules());
|
||||
for (DegradeRule rule : this.rules) {
|
||||
if (rule == null) {
|
||||
continue;
|
||||
}
|
||||
rule.setResource(resourceName);
|
||||
ruleSet.add(rule);
|
||||
}
|
||||
DegradeRuleManager.loadRules(new ArrayList<>(ruleSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
|
||||
Entry entry = null;
|
||||
try {
|
||||
entry = SphU.entry(resourceName, entryType);
|
||||
// If the SphU.entry() does not throw `BlockException`, it means that the
|
||||
// request can pass.
|
||||
return toRun.get();
|
||||
}
|
||||
catch (BlockException ex) {
|
||||
// SphU.entry() may throw BlockException which indicates that
|
||||
// the request was rejected (flow control or circuit breaking triggered).
|
||||
// So it should not be counted as the business exception.
|
||||
return fallback.apply(ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// For other kinds of exceptions, we'll trace the exception count via
|
||||
// Tracer.trace(ex).
|
||||
Tracer.trace(ex);
|
||||
return fallback.apply(ex);
|
||||
}
|
||||
finally {
|
||||
// Guarantee the invocation has been completed.
|
||||
if (entry != null) {
|
||||
entry.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for {@link SentinelCircuitBreaker}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ SphU.class })
|
||||
@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.sentinel.enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
public class SentinelCircuitBreakerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CircuitBreakerFactory.class)
|
||||
public CircuitBreakerFactory sentinelCircuitBreakerFactory() {
|
||||
return new SentinelCircuitBreakerFactory();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class SentinelCustomizerConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<Customizer<SentinelCircuitBreakerFactory>> customizers = new ArrayList<>();
|
||||
|
||||
@Autowired(required = false)
|
||||
private SentinelCircuitBreakerFactory factory;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
customizers.forEach(customizer -> customizer.customize(factory));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder.SentinelCircuitBreakerConfiguration;
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class SentinelCircuitBreakerFactory extends
|
||||
CircuitBreakerFactory<SentinelCircuitBreakerConfiguration, SentinelConfigBuilder> {
|
||||
|
||||
private Function<String, SentinelConfigBuilder.SentinelCircuitBreakerConfiguration> defaultConfiguration = id -> new SentinelConfigBuilder()
|
||||
.resourceName(id).entryType(EntryType.OUT).rules(new ArrayList<>()).build();
|
||||
|
||||
@Override
|
||||
public CircuitBreaker create(String id) {
|
||||
Assert.hasText(id, "A CircuitBreaker must have an id.");
|
||||
SentinelConfigBuilder.SentinelCircuitBreakerConfiguration conf = getConfigurations()
|
||||
.computeIfAbsent(id, defaultConfiguration);
|
||||
return new SentinelCircuitBreaker(id, conf.getEntryType(), conf.getRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SentinelConfigBuilder configBuilder(String id) {
|
||||
return new SentinelConfigBuilder(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefault(
|
||||
Function<String, SentinelCircuitBreakerConfiguration> defaultConfiguration) {
|
||||
this.defaultConfiguration = defaultConfiguration;
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.alibaba.csp.sentinel.EntryType;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.ConfigBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class SentinelConfigBuilder implements
|
||||
ConfigBuilder<SentinelConfigBuilder.SentinelCircuitBreakerConfiguration> {
|
||||
|
||||
private String resourceName;
|
||||
|
||||
private EntryType entryType;
|
||||
|
||||
private List<DegradeRule> rules;
|
||||
|
||||
public SentinelConfigBuilder() {
|
||||
}
|
||||
|
||||
public SentinelConfigBuilder(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
|
||||
public SentinelConfigBuilder resourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SentinelConfigBuilder entryType(EntryType entryType) {
|
||||
this.entryType = entryType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SentinelConfigBuilder rules(List<DegradeRule> rules) {
|
||||
this.rules = rules;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SentinelCircuitBreakerConfiguration build() {
|
||||
Assert.hasText(resourceName, "resourceName cannot be empty");
|
||||
List<DegradeRule> rules = Optional.ofNullable(this.rules)
|
||||
.orElse(new ArrayList<>());
|
||||
|
||||
EntryType entryType = Optional.ofNullable(this.entryType).orElse(EntryType.OUT);
|
||||
return new SentinelCircuitBreakerConfiguration()
|
||||
.setResourceName(this.resourceName).setEntryType(entryType)
|
||||
.setRules(rules);
|
||||
}
|
||||
|
||||
public static class SentinelCircuitBreakerConfiguration {
|
||||
|
||||
private String resourceName;
|
||||
|
||||
private EntryType entryType;
|
||||
|
||||
private List<DegradeRule> rules;
|
||||
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
public SentinelCircuitBreakerConfiguration setResourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntryType getEntryType() {
|
||||
return entryType;
|
||||
}
|
||||
|
||||
public SentinelCircuitBreakerConfiguration setEntryType(EntryType entryType) {
|
||||
this.entryType = entryType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<DegradeRule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
public SentinelCircuitBreakerConfiguration setRules(List<DegradeRule> rules) {
|
||||
this.rules = rules;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{"properties": [
|
||||
{
|
||||
"name": "spring.cloud.circuitbreaker.sentinel.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "enable sentinel circuitbreaker or not."
|
||||
}
|
||||
]}
|
@ -1,3 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.circuitbreaker.sentinel.SentinelCircuitBreakerAutoConfiguration,\
|
||||
com.alibaba.cloud.circuitbreaker.sentinel.ReactiveSentinelCircuitBreakerAutoConfiguration
|
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT,
|
||||
classes = ReactiveSentinelCircuitBreakerIntegrationTest.Application.class,
|
||||
properties = { "spring.cloud.discovery.client.health-indicator.enabled=false" })
|
||||
@DirtiesContext
|
||||
public class ReactiveSentinelCircuitBreakerIntegrationTest {
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 0;
|
||||
|
||||
@Autowired
|
||||
private ReactiveSentinelCircuitBreakerIntegrationTest.Application.DemoControllerService service;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
service.setPort(port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
StepVerifier.create(service.normal()).expectNext("normal").verifyComplete();
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
|
||||
// Then in the next 5s, the fallback method should be called.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
StepVerifier.create(service.slow()).expectNext("fallback").verifyComplete();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
// Recovered.
|
||||
StepVerifier.create(service.slow()).expectNext("slow").verifyComplete();
|
||||
|
||||
StepVerifier.create(service.normalFlux()).expectNext("normalflux")
|
||||
.verifyComplete();
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
// Then in the next 5s, the fallback method should be called.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
StepVerifier.create(service.slowFlux()).expectNext("flux_fallback")
|
||||
.verifyComplete();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
// Recovered.
|
||||
StepVerifier.create(service.slowFlux()).expectNext("slowflux").verifyComplete();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application {
|
||||
|
||||
@GetMapping("/slow")
|
||||
public Mono<String> slow() {
|
||||
return Mono.just("slow").delayElement(Duration.ofMillis(500));
|
||||
}
|
||||
|
||||
@GetMapping("/normal")
|
||||
public Mono<String> normal() {
|
||||
return Mono.just("normal");
|
||||
}
|
||||
|
||||
@GetMapping("/slow_flux")
|
||||
public Flux<String> slowFlux() {
|
||||
return Flux.just("slow", "flux").delayElements(Duration.ofMillis(500));
|
||||
}
|
||||
|
||||
@GetMapping("normal_flux")
|
||||
public Flux<String> normalFlux() {
|
||||
return Flux.just("normal", "flux");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<ReactiveSentinelCircuitBreakerFactory> slowCustomizer() {
|
||||
return factory -> {
|
||||
factory.configure(builder -> builder
|
||||
.rules(Collections.singletonList(new DegradeRule("slow_mono")
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100)
|
||||
.setTimeWindow(5))),
|
||||
"slow_mono");
|
||||
factory.configure(builder -> builder
|
||||
.rules(Collections.singletonList(new DegradeRule("slow_flux")
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100)
|
||||
.setTimeWindow(5))),
|
||||
"slow_flux");
|
||||
factory.configureDefault(id -> new SentinelConfigBuilder()
|
||||
.resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
|
||||
.setCount(0.5).setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
@Service
|
||||
public static class DemoControllerService {
|
||||
|
||||
private int port = 0;
|
||||
|
||||
private ReactiveCircuitBreakerFactory cbFactory;
|
||||
|
||||
DemoControllerService(ReactiveCircuitBreakerFactory cbFactory) {
|
||||
this.cbFactory = cbFactory;
|
||||
}
|
||||
|
||||
public Mono<String> slow() {
|
||||
return WebClient.builder().baseUrl("http://localhost:" + port).build()
|
||||
.get().uri("/slow").retrieve().bodyToMono(String.class)
|
||||
.transform(it -> cbFactory.create("slow_mono").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
public Mono<String> normal() {
|
||||
return WebClient.builder().baseUrl("http://localhost:" + port).build()
|
||||
.get().uri("/normal").retrieve().bodyToMono(String.class)
|
||||
.transform(it -> cbFactory.create("normal_mono").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
public Flux<String> slowFlux() {
|
||||
return WebClient.builder().baseUrl("http://localhost:" + port).build()
|
||||
.get().uri("/slow_flux").retrieve()
|
||||
.bodyToFlux(new ParameterizedTypeReference<String>() {
|
||||
}).transform(it -> cbFactory.create("slow_flux").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Flux.just("flux_fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
public Flux<String> normalFlux() {
|
||||
return WebClient.builder().baseUrl("http://localhost:" + port).build()
|
||||
.get().uri("/normal_flux").retrieve().bodyToFlux(String.class)
|
||||
.transform(it -> cbFactory.create("normal_flux").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Flux.just("flux_fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class ReactiveSentinelCircuitBreakerTest {
|
||||
|
||||
@Test
|
||||
public void testCreateWithNullRule() {
|
||||
String id = "testCreateReactiveCbWithNullRule";
|
||||
ReactiveSentinelCircuitBreaker cb = new ReactiveSentinelCircuitBreaker(id,
|
||||
Collections.singletonList(null));
|
||||
assertThat(Mono.just("foobar").transform(it -> cb.run(it)).block())
|
||||
.isEqualTo("foobar");
|
||||
assertThat(DegradeRuleManager.hasConfig(id)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runMono() {
|
||||
ReactiveCircuitBreaker cb = new ReactiveSentinelCircuitBreakerFactory()
|
||||
.create("foo");
|
||||
assertThat(Mono.just("foobar").transform(it -> cb.run(it)).block())
|
||||
.isEqualTo("foobar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runMonoWithFallback() {
|
||||
ReactiveCircuitBreaker cb = new ReactiveSentinelCircuitBreakerFactory()
|
||||
.create("foo");
|
||||
assertThat(Mono.error(new RuntimeException("boom"))
|
||||
.transform(it -> cb.run(it, t -> Mono.just("fallback"))).block())
|
||||
.isEqualTo("fallback");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runFlux() {
|
||||
ReactiveCircuitBreaker cb = new ReactiveSentinelCircuitBreakerFactory()
|
||||
.create("foo");
|
||||
assertThat(Flux.just("foobar", "hello world").transform(it -> cb.run(it))
|
||||
.collectList().block()).isEqualTo(Arrays.asList("foobar", "hello world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runFluxWithFallback() {
|
||||
ReactiveCircuitBreaker cb = new ReactiveSentinelCircuitBreakerFactory()
|
||||
.create("foo");
|
||||
assertThat(Flux.error(new RuntimeException("boom"))
|
||||
.transform(it -> cb.run(it, t -> Flux.just("fallback"))).collectList()
|
||||
.block()).isEqualTo(Arrays.asList("fallback"));
|
||||
}
|
||||
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT,
|
||||
classes = SentinelCircuitBreakerIntegrationTest.Application.class,
|
||||
properties = { "spring.cloud.discovery.client.health-indicator.enabled=false" })
|
||||
@DirtiesContext
|
||||
public class SentinelCircuitBreakerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private Application.DemoControllerService service;
|
||||
|
||||
@Test
|
||||
public void testSlow() throws Exception {
|
||||
// The first 5 requests should pass.
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
|
||||
// Then in the next 10s, the fallback method should be called.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertThat(service.slow()).isEqualTo("fallback");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
// Recovered.
|
||||
assertThat(service.slow()).isEqualTo("slow");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormal() {
|
||||
assertThat(service.normal()).isEqualTo("normal");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
DegradeRuleManager.loadRules(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void tearDown() {
|
||||
DegradeRuleManager.loadRules(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application {
|
||||
|
||||
@GetMapping("/slow")
|
||||
public String slow() throws InterruptedException {
|
||||
Thread.sleep(500);
|
||||
return "slow";
|
||||
}
|
||||
|
||||
@GetMapping("/normal")
|
||||
public String normal() {
|
||||
return "normal";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<SentinelCircuitBreakerFactory> slowCustomizer() {
|
||||
String slowId = "slow";
|
||||
List<DegradeRule> rules = Collections.singletonList(
|
||||
new DegradeRule(slowId).setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setCount(100).setTimeWindow(10));
|
||||
return factory -> {
|
||||
factory.configure(builder -> builder.rules(rules), slowId);
|
||||
factory.configureDefault(id -> new SentinelConfigBuilder()
|
||||
.resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
|
||||
.setCount(0.5).setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
@Service
|
||||
public static class DemoControllerService {
|
||||
|
||||
private TestRestTemplate rest;
|
||||
|
||||
private CircuitBreakerFactory cbFactory;
|
||||
|
||||
DemoControllerService(TestRestTemplate rest,
|
||||
CircuitBreakerFactory cbFactory) {
|
||||
this.rest = rest;
|
||||
this.cbFactory = cbFactory;
|
||||
}
|
||||
|
||||
public String slow() {
|
||||
return cbFactory.create("slow").run(
|
||||
() -> rest.getForObject("/slow", String.class), t -> "fallback");
|
||||
}
|
||||
|
||||
public String normal() {
|
||||
return cbFactory.create("normal").run(
|
||||
() -> rest.getForObject("/normal", String.class),
|
||||
t -> "fallback");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.circuitbreaker.sentinel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class SentinelCircuitBreakerTest {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
// Clear the rules.
|
||||
DegradeRuleManager.loadRules(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDirectlyThenRun() {
|
||||
// Create a circuit breaker without any circuit breaking rules.
|
||||
CircuitBreaker cb = new SentinelCircuitBreaker(
|
||||
"testSentinelCreateDirectlyThenRunA");
|
||||
assertThat(cb.run(() -> "Sentinel")).isEqualTo("Sentinel");
|
||||
assertThat(DegradeRuleManager.hasConfig("testSentinelCreateDirectlyThenRunA"))
|
||||
.isFalse();
|
||||
|
||||
CircuitBreaker cb2 = new SentinelCircuitBreaker(
|
||||
"testSentinelCreateDirectlyThenRunB",
|
||||
Collections.singletonList(
|
||||
new DegradeRule("testSentinelCreateDirectlyThenRunB")
|
||||
.setCount(100).setTimeWindow(10)));
|
||||
assertThat(cb2.run(() -> "Sentinel")).isEqualTo("Sentinel");
|
||||
assertThat(DegradeRuleManager.hasConfig("testSentinelCreateDirectlyThenRunB"))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithNullRule() {
|
||||
String id = "testCreateCbWithNullRule";
|
||||
CircuitBreaker cb = new SentinelCircuitBreaker(id,
|
||||
Collections.singletonList(null));
|
||||
assertThat(cb.run(() -> "Sentinel")).isEqualTo("Sentinel");
|
||||
assertThat(DegradeRuleManager.hasConfig(id)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFromFactoryThenRun() {
|
||||
CircuitBreaker cb = new SentinelCircuitBreakerFactory().create("testSentinelRun");
|
||||
assertThat(cb.run(() -> "foobar")).isEqualTo("foobar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunWithFallback() {
|
||||
CircuitBreaker cb = new SentinelCircuitBreakerFactory()
|
||||
.create("testSentinelRunWithFallback");
|
||||
assertThat(cb.<String>run(() -> {
|
||||
throw new RuntimeException("boom");
|
||||
}, t -> "fallback")).isEqualTo("fallback");
|
||||
}
|
||||
|
||||
}
|
@ -131,6 +131,20 @@
|
||||
<version>2.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -25,7 +25,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
|
||||
@ -39,7 +38,9 @@ import org.springframework.scheduling.TaskScheduler;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
@ConditionalOnBlockingDiscoveryEnabled
|
||||
//@ConditionalOnBlockingDiscoveryEnabled
|
||||
@ConditionalOnProperty(value = "spring.cloud.discovery.blocking.enabled",
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnNacosDiscoveryEnabled
|
||||
@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class,
|
||||
CommonsClientAutoConfiguration.class })
|
||||
|
@ -18,7 +18,6 @@ package com.alibaba.cloud.nacos.discovery.configclient;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration;
|
||||
import com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@ -36,8 +35,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
matchIfMissing = false)
|
||||
@Configuration
|
||||
@ImportAutoConfiguration({ NacosDiscoveryAutoConfiguration.class,
|
||||
NacosDiscoveryClientConfiguration.class,
|
||||
NacosReactiveDiscoveryClientConfiguration.class })
|
||||
NacosDiscoveryClientConfiguration.class})
|
||||
public class NacosDiscoveryClientConfigServiceBootstrapConfiguration {
|
||||
|
||||
}
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.nacos.discovery.reactive;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:echooy.mxq@gmail.com">echooymxq</a>
|
||||
**/
|
||||
public class NacosReactiveDiscoveryClient implements ReactiveDiscoveryClient {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(NacosReactiveDiscoveryClient.class);
|
||||
|
||||
private NacosServiceDiscovery serviceDiscovery;
|
||||
|
||||
public NacosReactiveDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
|
||||
this.serviceDiscovery = nacosServiceDiscovery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Spring Cloud Nacos Reactive Discovery Client";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ServiceInstance> getInstances(String serviceId) {
|
||||
|
||||
return Mono.justOrEmpty(serviceId).flatMapMany(loadInstancesFromNacos())
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
private Function<String, Publisher<ServiceInstance>> loadInstancesFromNacos() {
|
||||
return serviceId -> {
|
||||
try {
|
||||
return Flux.fromIterable(serviceDiscovery.getInstances(serviceId));
|
||||
}
|
||||
catch (NacosException e) {
|
||||
log.error("get service instance[{}] from nacos error!", serviceId, e);
|
||||
return Flux.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<String> getServices() {
|
||||
return Flux.defer(() -> {
|
||||
try {
|
||||
return Flux.fromIterable(serviceDiscovery.getServices());
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("get services from nacos server fail,", e);
|
||||
return Flux.empty();
|
||||
}
|
||||
}).subscribeOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.nacos.discovery.reactive;
|
||||
|
||||
import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled;
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
|
||||
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:echooy.mxq@gmail.com">echooymxq</a>
|
||||
**/
|
||||
@Configuration
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
@ConditionalOnReactiveDiscoveryEnabled
|
||||
@ConditionalOnNacosDiscoveryEnabled
|
||||
@AutoConfigureAfter({ NacosDiscoveryAutoConfiguration.class,
|
||||
ReactiveCompositeDiscoveryClientAutoConfiguration.class })
|
||||
@AutoConfigureBefore({ ReactiveCommonsClientAutoConfiguration.class })
|
||||
public class NacosReactiveDiscoveryClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public NacosReactiveDiscoveryClient nacosReactiveDiscoveryClient(
|
||||
NacosServiceDiscovery nacosServiceDiscovery) {
|
||||
return new NacosReactiveDiscoveryClient(nacosServiceDiscovery);
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
|
||||
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
|
||||
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.nacos.discovery.reactive;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:echooy.mxq@gmail.com">echooymxq</a>
|
||||
**/
|
||||
public class NacosReactiveDiscoveryClientConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(UtilAutoConfiguration.class,
|
||||
NacosDiscoveryAutoConfiguration.class,
|
||||
NacosReactiveDiscoveryClientConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testDefaultInitialization() {
|
||||
contextRunner.run(context -> assertThat(context)
|
||||
.hasSingleBean(ReactiveDiscoveryClient.class));
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.nacos.discovery.reactive;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:echooy.mxq@gmail.com">echooymxq</a>
|
||||
**/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class NacosReactiveDiscoveryClientTests {
|
||||
|
||||
@Mock
|
||||
private NacosServiceDiscovery serviceDiscovery;
|
||||
|
||||
@Mock
|
||||
private ServiceInstance serviceInstance;
|
||||
|
||||
@InjectMocks
|
||||
private NacosReactiveDiscoveryClient client;
|
||||
|
||||
@Test
|
||||
void testGetInstances() throws NacosException {
|
||||
|
||||
when(serviceDiscovery.getInstances("reactive-service"))
|
||||
.thenReturn(singletonList(serviceInstance));
|
||||
|
||||
Flux<ServiceInstance> instances = this.client.getInstances("reactive-service");
|
||||
|
||||
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetServices() throws NacosException {
|
||||
|
||||
when(serviceDiscovery.getServices())
|
||||
.thenReturn(Arrays.asList("reactive-service1", "reactive-service2"));
|
||||
|
||||
Flux<String> services = this.client.getServices();
|
||||
|
||||
StepVerifier.create(services).expectNext("reactive-service1", "reactive-service2")
|
||||
.expectComplete().verify();
|
||||
}
|
||||
|
||||
}
|
@ -86,12 +86,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||
<!-- <artifactId>spring-cloud-loadbalancer</artifactId>-->
|
||||
<!-- <optional>true</optional>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.seata.feign;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
|
||||
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
|
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
|
||||
|
||||
/**
|
||||
* @author yuhuangbin
|
||||
*/
|
||||
public class SeataFeignBlockingLoadBalancerClient
|
||||
extends FeignBlockingLoadBalancerClient {
|
||||
|
||||
public SeataFeignBlockingLoadBalancerClient(Client delegate,
|
||||
BlockingLoadBalancerClient loadBalancerClient,
|
||||
SeataFeignObjectWrapper seataFeignObjectWrapper) {
|
||||
super((Client) seataFeignObjectWrapper.wrap(delegate), loadBalancerClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
return super.execute(request, options);
|
||||
}
|
||||
|
||||
}
|
@ -21,9 +21,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
|
||||
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
|
||||
@ -51,11 +49,6 @@ public class SeataFeignObjectWrapper {
|
||||
return new SeataLoadBalancerFeignClient(client.getDelegate(), factory(),
|
||||
clientFactory(), this);
|
||||
}
|
||||
if (bean instanceof FeignBlockingLoadBalancerClient) {
|
||||
FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean;
|
||||
return new SeataFeignBlockingLoadBalancerClient(client.getDelegate(),
|
||||
beanFactory.getBean(BlockingLoadBalancerClient.class), this);
|
||||
}
|
||||
return new SeataFeignClient(this.beanFactory, (Client) bean);
|
||||
}
|
||||
return bean;
|
||||
|
@ -103,11 +103,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
|
||||
|
@ -74,7 +74,7 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator {
|
||||
// detail
|
||||
if (!sentinelProperties.isEnabled()) {
|
||||
detailMap.put("enabled", false);
|
||||
builder.up().withDetails(detailMap);
|
||||
withDetails(builder.up(), detailMap);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -139,11 +139,16 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
// If Dashboard and DataSource are both OK, the health status is UP
|
||||
if (dashboardUp && dataSourceUp) {
|
||||
builder.up().withDetails(detailMap);
|
||||
withDetails(builder.up(), detailMap);
|
||||
}
|
||||
else {
|
||||
builder.down().withDetails(detailMap);
|
||||
withDetails(builder.down(), detailMap);
|
||||
}
|
||||
}
|
||||
|
||||
private void withDetails(Health.Builder builder, Map<String, Object> detailMap) {
|
||||
for (String key : detailMap.keySet()) {
|
||||
builder.withDetail(key, detailMap.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ public class SentinelContractHolder implements Contract {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType) {
|
||||
List<MethodMetadata> metadatas = delegate.parseAndValidateMetadata(targetType);
|
||||
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
|
||||
List<MethodMetadata> metadatas = delegate.parseAndValidatateMetadata(targetType);
|
||||
metadatas.forEach(metadata -> METADATA_MAP
|
||||
.put(targetType.getName() + metadata.configKey(), metadata));
|
||||
return metadatas;
|
||||
|
@ -33,7 +33,6 @@ import org.springframework.cloud.openfeign.FeignContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link Feign.Builder} like {@link HystrixFeign.Builder}.
|
||||
@ -87,11 +86,7 @@ public final class SentinelFeign {
|
||||
"fallback");
|
||||
Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean,
|
||||
"fallbackFactory");
|
||||
String beanName = (String) getFieldValue(feignClientFactoryBean,
|
||||
"contextId");
|
||||
if (!StringUtils.hasText(beanName)) {
|
||||
beanName = (String) getFieldValue(feignClientFactoryBean, "name");
|
||||
}
|
||||
String beanName = (String) getFieldValue(feignClientFactoryBean, "name");
|
||||
|
||||
Object fallbackInstance;
|
||||
FallbackFactory fallbackFactoryInstance;
|
||||
|
@ -99,7 +99,7 @@ public class SentinelInvocationHandler implements InvocationHandler {
|
||||
}
|
||||
else {
|
||||
String resourceName = methodMetadata.template().method().toUpperCase()
|
||||
+ ":" + hardCodedTarget.url() + methodMetadata.template().path();
|
||||
+ ":" + hardCodedTarget.url() + methodMetadata.template().url();
|
||||
Entry entry = null;
|
||||
try {
|
||||
ContextUtil.enter(resourceName);
|
||||
|
@ -1,136 +1,136 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.sentinel;
|
||||
|
||||
import com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Add this unit test to verify https://github.com/alibaba/spring-cloud-alibaba/pull/838.
|
||||
*
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = { ContextIdSentinelFeignTests.TestConfig.class },
|
||||
properties = { "feign.sentinel.enabled=true" })
|
||||
public class ContextIdSentinelFeignTests {
|
||||
|
||||
@Autowired
|
||||
private EchoService echoService;
|
||||
|
||||
@Autowired
|
||||
private FooService fooService;
|
||||
|
||||
@Test
|
||||
public void testFeignClient() {
|
||||
assertThat(echoService.echo("test")).isEqualTo("echo fallback");
|
||||
assertThat(fooService.echo("test")).isEqualTo("foo fallback");
|
||||
assertThat(fooService.toString()).isNotEqualTo(echoService.toString());
|
||||
assertThat(fooService.hashCode()).isNotEqualTo(echoService.hashCode());
|
||||
assertThat(echoService.equals(fooService)).isEqualTo(Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration({ SentinelFeignAutoConfiguration.class })
|
||||
@EnableFeignClients
|
||||
public static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(contextId = "echoService", name = "service-provider",
|
||||
fallback = EchoServiceFallback.class,
|
||||
configuration = FeignConfiguration.class)
|
||||
public interface EchoService {
|
||||
|
||||
@GetMapping("/echo/{str}")
|
||||
String echo(@PathVariable("str") String str);
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(contextId = "fooService", value = "foo-service",
|
||||
fallbackFactory = CustomFallbackFactory.class,
|
||||
configuration = FeignConfiguration.class)
|
||||
public interface FooService {
|
||||
|
||||
@RequestMapping(path = "echo/{str}")
|
||||
String echo(@RequestParam("str") String param);
|
||||
|
||||
}
|
||||
|
||||
public static class FeignConfiguration {
|
||||
|
||||
@Bean
|
||||
public EchoServiceFallback echoServiceFallback() {
|
||||
return new EchoServiceFallback();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomFallbackFactory customFallbackFactory() {
|
||||
return new CustomFallbackFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class EchoServiceFallback implements EchoService {
|
||||
|
||||
@Override
|
||||
public String echo(@RequestParam("str") String param) {
|
||||
return "echo fallback";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FooServiceFallback implements FooService {
|
||||
|
||||
@Override
|
||||
public String echo(@RequestParam("str") String param) {
|
||||
return "foo fallback";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CustomFallbackFactory
|
||||
implements feign.hystrix.FallbackFactory<FooService> {
|
||||
|
||||
private FooService fooService = new FooServiceFallback();
|
||||
|
||||
@Override
|
||||
public FooService create(Throwable throwable) {
|
||||
return fooService;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * Copyright 2013-2018 the original author or authors.
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * https://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//
|
||||
//package com.alibaba.cloud.sentinel;
|
||||
//
|
||||
//import com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration;
|
||||
//import org.junit.Test;
|
||||
//import org.junit.runner.RunWith;
|
||||
//
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
//import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
//import org.springframework.boot.test.context.SpringBootTest;
|
||||
//import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
//import org.springframework.cloud.openfeign.FeignClient;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.test.context.junit4.SpringRunner;
|
||||
//import org.springframework.web.bind.annotation.GetMapping;
|
||||
//import org.springframework.web.bind.annotation.PathVariable;
|
||||
//import org.springframework.web.bind.annotation.RequestMapping;
|
||||
//import org.springframework.web.bind.annotation.RequestParam;
|
||||
//
|
||||
//import static org.assertj.core.api.Assertions.assertThat;
|
||||
//
|
||||
///**
|
||||
// * Add this unit test to verify https://github.com/alibaba/spring-cloud-alibaba/pull/838.
|
||||
// *
|
||||
// * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
// */
|
||||
//@RunWith(SpringRunner.class)
|
||||
//@SpringBootTest(classes = { ContextIdSentinelFeignTests.TestConfig.class },
|
||||
// properties = { "feign.sentinel.enabled=true" })
|
||||
//public class ContextIdSentinelFeignTests {
|
||||
//
|
||||
// @Autowired
|
||||
// private EchoService echoService;
|
||||
//
|
||||
// @Autowired
|
||||
// private FooService fooService;
|
||||
//
|
||||
// @Test
|
||||
// public void testFeignClient() {
|
||||
// assertThat(echoService.echo("test")).isEqualTo("echo fallback");
|
||||
// assertThat(fooService.echo("test")).isEqualTo("foo fallback");
|
||||
// assertThat(fooService.toString()).isNotEqualTo(echoService.toString());
|
||||
// assertThat(fooService.hashCode()).isNotEqualTo(echoService.hashCode());
|
||||
// assertThat(echoService.equals(fooService)).isEqualTo(Boolean.FALSE);
|
||||
// }
|
||||
//
|
||||
// @Configuration
|
||||
// @EnableAutoConfiguration
|
||||
// @ImportAutoConfiguration({ SentinelFeignAutoConfiguration.class })
|
||||
// @EnableFeignClients
|
||||
// public static class TestConfig {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @FeignClient(name = "service-provider",
|
||||
// fallback = EchoServiceFallback.class,
|
||||
// configuration = FeignConfiguration.class)
|
||||
// public interface EchoService {
|
||||
//
|
||||
// @GetMapping("/echo/{str}")
|
||||
// String echo(@PathVariable("str") String str);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @FeignClient(value = "foo-service",
|
||||
// fallbackFactory = CustomFallbackFactory.class,
|
||||
// configuration = FeignConfiguration.class)
|
||||
// public interface FooService {
|
||||
//
|
||||
// @RequestMapping(path = "echo/{str}")
|
||||
// String echo(@RequestParam("str") String param);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static class FeignConfiguration {
|
||||
//
|
||||
// @Bean
|
||||
// public EchoServiceFallback echoServiceFallback() {
|
||||
// return new EchoServiceFallback();
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public CustomFallbackFactory customFallbackFactory() {
|
||||
// return new CustomFallbackFactory();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static class EchoServiceFallback implements EchoService {
|
||||
//
|
||||
// @Override
|
||||
// public String echo(@RequestParam("str") String param) {
|
||||
// return "echo fallback";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static class FooServiceFallback implements FooService {
|
||||
//
|
||||
// @Override
|
||||
// public String echo(@RequestParam("str") String param) {
|
||||
// return "foo fallback";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static class CustomFallbackFactory
|
||||
// implements feign.hystrix.FallbackFactory<FooService> {
|
||||
//
|
||||
// private FooService fooService = new FooServiceFallback();
|
||||
//
|
||||
// @Override
|
||||
// public FooService create(Throwable throwable) {
|
||||
// return fooService;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -30,7 +30,6 @@ import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||
import org.springframework.cloud.consul.discovery.HeartbeatProperties;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulManagementRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration;
|
||||
@ -52,13 +51,12 @@ public class SidecarConsulAutoConfiguration {
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext applicationContext,
|
||||
ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
|
||||
ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
SidecarProperties sidecarProperties) {
|
||||
return SidecarConsulAutoRegistration.registration(
|
||||
autoServiceRegistrationProperties, properties, applicationContext,
|
||||
registrationCustomizers.getIfAvailable(),
|
||||
managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties,
|
||||
heartbeatProperties,
|
||||
sidecarProperties);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationP
|
||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||
import org.springframework.cloud.consul.discovery.HeartbeatProperties;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulManagementRegistrationCustomizer;
|
||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -38,17 +37,15 @@ public class SidecarConsulAutoRegistration extends ConsulAutoRegistration {
|
||||
public SidecarConsulAutoRegistration(NewService service,
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext context,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers) {
|
||||
HeartbeatProperties heartbeatProperties) {
|
||||
super(service, autoServiceRegistrationProperties, properties, context,
|
||||
heartbeatProperties, managementRegistrationCustomizers);
|
||||
heartbeatProperties);
|
||||
}
|
||||
|
||||
public static ConsulAutoRegistration registration(
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ConsulDiscoveryProperties properties, ApplicationContext context,
|
||||
List<ConsulRegistrationCustomizer> registrationCustomizers,
|
||||
List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers,
|
||||
HeartbeatProperties heartbeatProperties,
|
||||
SidecarProperties sidecarProperties) {
|
||||
|
||||
@ -72,7 +69,7 @@ public class SidecarConsulAutoRegistration extends ConsulAutoRegistration {
|
||||
|
||||
ConsulAutoRegistration registration = new ConsulAutoRegistration(service,
|
||||
autoServiceRegistrationProperties, properties, context,
|
||||
heartbeatProperties, managementRegistrationCustomizers);
|
||||
heartbeatProperties);
|
||||
customize(registrationCustomizers, registration);
|
||||
return registration;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ public class DubboServiceBeanMetadataResolver
|
||||
Class<?> targetType) {
|
||||
List<MethodMetadata> methodMetadataList = Collections.emptyList();
|
||||
try {
|
||||
methodMetadataList = contract.parseAndValidateMetadata(targetType);
|
||||
methodMetadataList = contract.parseAndValidatateMetadata(targetType);
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
// ignore
|
||||
@ -153,7 +153,7 @@ public class DubboServiceBeanMetadataResolver
|
||||
* Select feign contract methods
|
||||
* <p>
|
||||
* extract some code from
|
||||
* {@link Contract.BaseContract#parseAndValidateMetadata(Class)}.
|
||||
* {@link Contract.BaseContract#parseAndValidatateMetadata(Class)}.
|
||||
* @param targetType class of type
|
||||
* @return non-null
|
||||
*/
|
||||
|
@ -90,7 +90,7 @@ public class DubboTransportedMethodMetadataResolver {
|
||||
|
||||
private Map<String, RestMethodMetadata> resolveRestRequestMetadataMap(
|
||||
Class<?> targetType) {
|
||||
return contract.parseAndValidateMetadata(targetType).stream().collect(Collectors
|
||||
return contract.parseAndValidatateMetadata(targetType).stream().collect(Collectors
|
||||
.toMap(feign.MethodMetadata::configKey, this::restMethodMetadata));
|
||||
}
|
||||
|
||||
|
@ -46,17 +46,14 @@ import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.apache.rocketmq.spring.support.RocketMQUtil;
|
||||
|
||||
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;
|
||||
import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
|
||||
import org.springframework.cloud.stream.provisioning.ConsumerDestination;
|
||||
import org.springframework.cloud.stream.provisioning.ProducerDestination;
|
||||
import org.springframework.integration.StaticMessageHeaderAccessor;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallback;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallback.Status;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.support.StaticMessageHeaderAccessor;
|
||||
import org.springframework.integration.support.AcknowledgmentCallback;
|
||||
import org.springframework.integration.support.AcknowledgmentCallback.Status;
|
||||
import org.springframework.integration.core.MessageProducer;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
@ -71,12 +68,9 @@ public class RocketMQMessageChannelBinder extends
|
||||
implements
|
||||
ExtendedPropertiesBinder<MessageChannel, RocketMQConsumerProperties, RocketMQProducerProperties> {
|
||||
|
||||
private RocketMQExtendedBindingProperties extendedBindingProperties = new RocketMQExtendedBindingProperties();
|
||||
|
||||
private RocketMQExtendedBindingProperties extendedBindingProperties;
|
||||
private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
|
||||
|
||||
private final RocketMQProperties rocketMQProperties;
|
||||
|
||||
private final InstrumentationManager instrumentationManager;
|
||||
|
||||
private Map<String, String> topicInUse = new HashMap<>();
|
||||
@ -96,7 +90,7 @@ public class RocketMQMessageChannelBinder extends
|
||||
@Override
|
||||
protected MessageHandler createProducerMessageHandler(ProducerDestination destination,
|
||||
ExtendedProducerProperties<RocketMQProducerProperties> producerProperties,
|
||||
MessageChannel channel, MessageChannel errorChannel) throws Exception {
|
||||
MessageChannel errorChannel) throws Exception {
|
||||
if (producerProperties.getExtension().getEnabled()) {
|
||||
|
||||
// if producerGroup is empty, using destination
|
||||
@ -168,11 +162,7 @@ public class RocketMQMessageChannelBinder extends
|
||||
RocketMQMessageHandler messageHandler = new RocketMQMessageHandler(
|
||||
rocketMQTemplate, destination.getName(), producerGroup,
|
||||
producerProperties.getExtension().getTransactional(),
|
||||
instrumentationManager, producerProperties,
|
||||
((AbstractMessageChannel) channel).getChannelInterceptors().stream()
|
||||
.filter(channelInterceptor -> channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor)
|
||||
.map(channelInterceptor -> ((MessageConverterConfigurer.PartitioningInterceptor) channelInterceptor))
|
||||
.findFirst().orElse(null));
|
||||
instrumentationManager, producerProperties);
|
||||
messageHandler.setBeanFactory(this.getApplicationContext().getBeanFactory());
|
||||
messageHandler.setSync(producerProperties.getExtension().getSync());
|
||||
messageHandler.setHeaderMapper(createHeaderMapper(producerProperties));
|
||||
@ -187,14 +177,6 @@ public class RocketMQMessageChannelBinder extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MessageHandler createProducerMessageHandler(ProducerDestination destination,
|
||||
ExtendedProducerProperties<RocketMQProducerProperties> producerProperties,
|
||||
MessageChannel errorChannel) throws Exception {
|
||||
throw new UnsupportedOperationException(
|
||||
"The abstract binder should not call this method");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MessageProducer createConsumerEndpoint(ConsumerDestination destination,
|
||||
String group,
|
||||
@ -286,16 +268,6 @@ public class RocketMQMessageChannelBinder extends
|
||||
return topicInUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultsPrefix() {
|
||||
return extendedBindingProperties.getDefaultsPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
|
||||
return extendedBindingProperties.getExtendedPropertiesEntryClass();
|
||||
}
|
||||
|
||||
public void setExtendedBindingProperties(
|
||||
RocketMQExtendedBindingProperties extendedBindingProperties) {
|
||||
this.extendedBindingProperties = extendedBindingProperties;
|
||||
|
@ -38,7 +38,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.stream.binder.BinderHeaders;
|
||||
import org.springframework.cloud.stream.binder.ExtendedProducerProperties;
|
||||
import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.integration.support.DefaultErrorMessageStrategy;
|
||||
@ -81,20 +80,16 @@ public class RocketMQMessageHandler extends AbstractMessageHandler implements Li
|
||||
|
||||
private ExtendedProducerProperties<RocketMQProducerProperties> producerProperties;
|
||||
|
||||
private MessageConverterConfigurer.PartitioningInterceptor partitioningInterceptor;
|
||||
|
||||
public RocketMQMessageHandler(RocketMQTemplate rocketMQTemplate, String destination,
|
||||
String groupName, Boolean transactional,
|
||||
InstrumentationManager instrumentationManager,
|
||||
ExtendedProducerProperties<RocketMQProducerProperties> producerProperties,
|
||||
MessageConverterConfigurer.PartitioningInterceptor partitioningInterceptor) {
|
||||
ExtendedProducerProperties<RocketMQProducerProperties> producerProperties) {
|
||||
this.rocketMQTemplate = rocketMQTemplate;
|
||||
this.destination = destination;
|
||||
this.groupName = groupName;
|
||||
this.transactional = transactional;
|
||||
this.instrumentationManager = instrumentationManager;
|
||||
this.producerProperties = producerProperties;
|
||||
this.partitioningInterceptor = partitioningInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,8 +121,6 @@ public class RocketMQMessageHandler extends AbstractMessageHandler implements Li
|
||||
destination, producerProperties.getPartitionCount(),
|
||||
messageQueues.size()));
|
||||
producerProperties.setPartitionCount(messageQueues.size());
|
||||
partitioningInterceptor
|
||||
.setPartitionCount(producerProperties.getPartitionCount());
|
||||
}
|
||||
}
|
||||
catch (MQClientException e) {
|
||||
|
@ -40,8 +40,8 @@ import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallback;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallbackFactory;
|
||||
import org.springframework.integration.support.AcknowledgmentCallback;
|
||||
import org.springframework.integration.support.AcknowledgmentCallbackFactory;
|
||||
import org.springframework.integration.endpoint.AbstractMessageSource;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
@ -237,6 +237,11 @@ public class RocketMQMessageSource extends AbstractMessageSource<Object>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public static class RocketMQCallbackFactory
|
||||
implements AcknowledgmentCallbackFactory<RocketMQAckInfo> {
|
||||
|
||||
|
@ -16,19 +16,16 @@
|
||||
|
||||
package com.alibaba.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 implements BinderSpecificPropertiesProvider {
|
||||
public class RocketMQBindingProperties {
|
||||
|
||||
private RocketMQConsumerProperties consumer = new RocketMQConsumerProperties();
|
||||
|
||||
private RocketMQProducerProperties producer = new RocketMQProducerProperties();
|
||||
|
||||
@Override
|
||||
public RocketMQConsumerProperties getConsumer() {
|
||||
return consumer;
|
||||
}
|
||||
@ -37,7 +34,6 @@ public class RocketMQBindingProperties implements BinderSpecificPropertiesProvid
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RocketMQProducerProperties getProducer() {
|
||||
return producer;
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@ -16,28 +16,71 @@
|
||||
|
||||
package com.alibaba.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.AbstractExtendedBindingProperties;
|
||||
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
|
||||
import org.springframework.cloud.stream.binder.ExtendedBindingProperties;
|
||||
|
||||
/**
|
||||
* @author Timur Valiev
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.stream.rocketmq")
|
||||
public class RocketMQExtendedBindingProperties extends
|
||||
AbstractExtendedBindingProperties<RocketMQConsumerProperties, RocketMQProducerProperties, RocketMQBindingProperties> {
|
||||
public class RocketMQExtendedBindingProperties implements
|
||||
ExtendedBindingProperties<RocketMQConsumerProperties, RocketMQProducerProperties> {
|
||||
|
||||
private static final String DEFAULTS_PREFIX = "spring.cloud.stream.rocketmq.default";
|
||||
private Map<String, RocketMQBindingProperties> bindings = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String getDefaultsPrefix() {
|
||||
return DEFAULTS_PREFIX;
|
||||
public Map<String, RocketMQBindingProperties> getBindings() {
|
||||
return this.bindings;
|
||||
}
|
||||
|
||||
public void setBindings(Map<String, RocketMQBindingProperties> bindings) {
|
||||
this.bindings = bindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
|
||||
return RocketMQBindingProperties.class;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.cloud.stream.binder.rocketmq;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.alibaba.cloud.stream.binder.rocketmq.config.RocketMQBinderAutoConfiguration;
|
||||
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
|
||||
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
|
||||
@ -56,7 +58,7 @@ public class RocketMQAutoConfigurationTests {
|
||||
RocketMQBinderConfigurationProperties binderConfigurationProperties = context
|
||||
.getBean(RocketMQBinderConfigurationProperties.class);
|
||||
assertThat(binderConfigurationProperties.getNameServer())
|
||||
.isEqualTo("127.0.0.1:9876");
|
||||
.isEqualTo(Arrays.asList("127.0.0.1:9876"));
|
||||
RocketMQExtendedBindingProperties bindingProperties = context
|
||||
.getBean(RocketMQExtendedBindingProperties.class);
|
||||
assertThat(
|
||||
|
Loading…
x
Reference in New Issue
Block a user