mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
commit
322c7db4a5
@ -18,7 +18,7 @@
|
|||||||
<description>Spring Cloud Alibaba Dependencies</description>
|
<description>Spring Cloud Alibaba Dependencies</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<sentinel.version>1.6.3</sentinel.version>
|
<sentinel.version>1.7.1</sentinel.version>
|
||||||
<oss.version>3.1.0</oss.version>
|
<oss.version>3.1.0</oss.version>
|
||||||
<seata.version>0.9.0</seata.version>
|
<seata.version>0.9.0</seata.version>
|
||||||
<nacos.client.version>1.1.4</nacos.client.version>
|
<nacos.client.version>1.1.4</nacos.client.version>
|
||||||
@ -198,6 +198,11 @@
|
|||||||
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
|
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
|
||||||
<version>${sentinel.version}</version>
|
<version>${sentinel.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.csp</groupId>
|
||||||
|
<artifactId>sentinel-spring-webmvc-adapter</artifactId>
|
||||||
|
<version>${sentinel.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!--Alibaba Seata-->
|
<!--Alibaba Seata-->
|
||||||
|
@ -18,6 +18,7 @@ package com.alibaba.cloud.examples;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@ -30,7 +31,9 @@ import org.springframework.boot.ApplicationArguments;
|
|||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -45,6 +48,52 @@ public class Application {
|
|||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(Application.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserConfig userConfig() {
|
||||||
|
return new UserConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "user")
|
||||||
|
class UserConfig {
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Map<String, Object> map;
|
||||||
|
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMap(Map<String, Object> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UserConfig{" + "age=" + age + ", name='" + name + '\'' + ", map=" + map
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -74,7 +123,7 @@ class SampleRunner implements ApplicationRunner {
|
|||||||
*
|
*
|
||||||
* user.name=Nacos user.age=25
|
* user.name=Nacos user.age=25
|
||||||
* @param configInfo latest config data for specific dataId in Nacos
|
* @param configInfo latest config data for specific dataId in Nacos
|
||||||
* server
|
* server
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void receiveConfigInfo(String configInfo) {
|
public void receiveConfigInfo(String configInfo) {
|
||||||
@ -101,19 +150,27 @@ class SampleRunner implements ApplicationRunner {
|
|||||||
@RefreshScope
|
@RefreshScope
|
||||||
class SampleController {
|
class SampleController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserConfig userConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NacosConfigManager nacosConfigManager;
|
||||||
|
|
||||||
@Value("${user.name}")
|
@Value("${user.name}")
|
||||||
String userName;
|
String userName;
|
||||||
|
|
||||||
@Value("${user.age:25}")
|
@Value("${user.age:25}")
|
||||||
Integer age;
|
Integer age;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NacosConfigManager nacosConfigManager;
|
|
||||||
|
|
||||||
@RequestMapping("/user")
|
@RequestMapping("/user")
|
||||||
public String simple() {
|
public String simple() {
|
||||||
return "Hello Nacos Config!" + "Hello " + userName + " " + age + "!"
|
return "Hello Nacos Config!" + "Hello " + userName + " " + age + " [UserConfig]: "
|
||||||
+ nacosConfigManager.getConfigService();
|
+ userConfig + "!" + nacosConfigManager.getConfigService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/bool")
|
||||||
|
public boolean bool() {
|
||||||
|
return (Boolean) (userConfig.getMap().get("2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ spring.cloud.nacos.config.shared-configs[2]= common222.properties
|
|||||||
spring.cloud.nacos.config.extension-configs[0].data-id= extension1.properties
|
spring.cloud.nacos.config.extension-configs[0].data-id= extension1.properties
|
||||||
spring.cloud.nacos.config.extension-configs[0].refresh= true
|
spring.cloud.nacos.config.extension-configs[0].refresh= true
|
||||||
spring.cloud.nacos.config.extension-configs[1]= extension2.properties
|
spring.cloud.nacos.config.extension-configs[1]= extension2.properties
|
||||||
|
spring.cloud.nacos.config.extension-configs[2].data-id= extension3.json
|
||||||
|
|
||||||
|
|
||||||
#spring.cloud.nacos.config.refresh-enabled=true
|
#spring.cloud.nacos.config.refresh-enabled=true
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
<?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.2.0.BUILD-SNAPSHOT</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>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>
|
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
n=1
|
||||||
|
while [ $n -le 10 ]
|
||||||
|
do
|
||||||
|
echo `curl -s http://localhost:18083/echo-feign/openfeign`
|
||||||
|
let n++
|
||||||
|
done
|
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
n=1
|
||||||
|
while [ $n -le 10 ]
|
||||||
|
do
|
||||||
|
echo `curl -s http://localhost:18083/echo-rest/resttemplate`
|
||||||
|
let n++
|
||||||
|
done
|
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* 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 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.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
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
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")
|
||||||
|
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 EchoService echoService;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.cloud.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
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.loadbalancer.ribbon.enabled=false
|
@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
/**
|
/**
|
||||||
* @author xiaojing
|
* @author xiaojing
|
||||||
*/
|
*/
|
||||||
@EnableDiscoveryClient(autoRegister = false)
|
@EnableDiscoveryClient
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class ProviderApplication {
|
public class ProviderApplication {
|
||||||
|
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
<?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.2.0.BUILD-SNAPSHOT</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>
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
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.loadbalancer.ribbon.enabled=false
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>nacos-discovery-consumer-example</module>
|
<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-provider-example</module>
|
||||||
<module>nacos-discovery-spring-cloud-config-server-example</module>
|
<module>nacos-discovery-spring-cloud-config-server-example</module>
|
||||||
<module>nacos-discovery-spring-cloud-config-client-example</module>
|
<module>nacos-discovery-spring-cloud-config-client-example</module>
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--<dependency>-->
|
<!--<dependency>-->
|
||||||
<!--<groupId>com.alibaba.csp</groupId>-->
|
<!--<groupId>com.alibaba.csp</groupId>-->
|
||||||
|
@ -16,11 +16,18 @@
|
|||||||
|
|
||||||
package com.alibaba.cloud.examples;
|
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.cloud.sentinel.annotation.SentinelRestTemplate;
|
||||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
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.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@ -47,6 +54,18 @@ public class ServiceApplication {
|
|||||||
return new JsonFlowRuleListConverter();
|
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) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(ServiceApplication.class, args);
|
SpringApplication.run(ServiceApplication.class, args);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.alibaba.cloud.examples;
|
|||||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@ -32,6 +33,9 @@ public class TestController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CircuitBreakerFactory circuitBreakerFactory;
|
||||||
|
|
||||||
@GetMapping("/hello")
|
@GetMapping("/hello")
|
||||||
@SentinelResource("resource")
|
@SentinelResource("resource")
|
||||||
public String hello() {
|
public String hello() {
|
||||||
@ -54,4 +58,17 @@ public class TestController {
|
|||||||
return restTemplate.getForObject("http://www.taobao.com/test", String.class);
|
return restTemplate.getForObject("http://www.taobao.com/test", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/slow")
|
||||||
|
public String slow() {
|
||||||
|
return circuitBreakerFactory.create("show").run(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "success";
|
||||||
|
}, throwable -> "fallback");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yuhuangbin
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
|
registry.addViewController("/errorPage").setViewName("errorPage");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,6 +9,9 @@ management.health.diskspace.enabled=false
|
|||||||
|
|
||||||
spring.cloud.sentinel.transport.dashboard=localhost:8080
|
spring.cloud.sentinel.transport.dashboard=localhost:8080
|
||||||
spring.cloud.sentinel.eager=true
|
spring.cloud.sentinel.eager=true
|
||||||
|
|
||||||
|
#spring.cloud.sentinel.block-page=/errorPage
|
||||||
|
#spring.cloud.sentinel.filter.enabled=false
|
||||||
#spring.cloud.sentinel.http-method-specify=false
|
#spring.cloud.sentinel.http-method-specify=false
|
||||||
|
|
||||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
This is error page.
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -64,7 +64,8 @@ public class NacosConfigAutoConfiguration {
|
|||||||
public NacosContextRefresher nacosContextRefresher(
|
public NacosContextRefresher nacosContextRefresher(
|
||||||
NacosConfigManager nacosConfigManager,
|
NacosConfigManager nacosConfigManager,
|
||||||
NacosRefreshHistory nacosRefreshHistory) {
|
NacosRefreshHistory nacosRefreshHistory) {
|
||||||
// Consider that it is not necessary to be compatible with the previous configuration
|
// Consider that it is not necessary to be compatible with the previous
|
||||||
|
// configuration
|
||||||
// and use the new configuration if necessary.
|
// and use the new configuration if necessary.
|
||||||
return new NacosContextRefresher(nacosConfigManager, nacosRefreshHistory);
|
return new NacosContextRefresher(nacosConfigManager, nacosRefreshHistory);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package com.alibaba.cloud.nacos.client;
|
package com.alibaba.cloud.nacos.client;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@ -111,17 +110,7 @@ public class NacosPropertySourceBuilder {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Map<String, Object> propertiesToMap(Properties properties) {
|
private Map<String, Object> propertiesToMap(Properties properties) {
|
||||||
Map<String, Object> result = new HashMap<>(16);
|
Map<String, Object> result = new HashMap<>(16);
|
||||||
Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();
|
properties.forEach((k, v) -> result.put(String.valueOf(k), v));
|
||||||
while (keys.hasMoreElements()) {
|
|
||||||
String key = keys.nextElement();
|
|
||||||
String value = properties.getProperty(key);
|
|
||||||
if (value != null) {
|
|
||||||
result.put(key, value.trim());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.put(key, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +111,12 @@ public abstract class AbstractNacosDataParser {
|
|||||||
/**
|
/**
|
||||||
* Generate key-value pairs from the map.
|
* Generate key-value pairs from the map.
|
||||||
*/
|
*/
|
||||||
protected Properties generateProperties(Map<String, String> map) {
|
protected Properties generateProperties(Map<String, Object> map) {
|
||||||
if (null == map || map.isEmpty()) {
|
if (null == map || map.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
if (StringUtils.isEmpty(key)) {
|
if (StringUtils.isEmpty(key)) {
|
||||||
continue;
|
continue;
|
||||||
@ -130,12 +130,12 @@ public abstract class AbstractNacosDataParser {
|
|||||||
/**
|
/**
|
||||||
* Reload the key ending in `value` if need.
|
* Reload the key ending in `value` if need.
|
||||||
*/
|
*/
|
||||||
protected Map<String, String> reloadMap(Map<String, String> map) {
|
protected Map<String, Object> reloadMap(Map<String, Object> map) {
|
||||||
if (map == null || map.isEmpty()) {
|
if (map == null || map.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> result = new HashMap<>(map);
|
Map<String, Object> result = new HashMap<>(map);
|
||||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
if (key.contains(DOT)) {
|
if (key.contains(DOT)) {
|
||||||
int idx = key.lastIndexOf(DOT);
|
int idx = key.lastIndexOf(DOT);
|
||||||
|
@ -17,18 +17,22 @@
|
|||||||
package com.alibaba.cloud.nacos.parser;
|
package com.alibaba.cloud.nacos.parser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zkz
|
* @author zkz
|
||||||
|
* @author yuhuangbin
|
||||||
*/
|
*/
|
||||||
public class NacosDataJsonParser extends AbstractNacosDataParser {
|
public class NacosDataJsonParser extends AbstractNacosDataParser {
|
||||||
|
|
||||||
@ -41,7 +45,7 @@ public class NacosDataJsonParser extends AbstractNacosDataParser {
|
|||||||
if (StringUtils.isEmpty(data)) {
|
if (StringUtils.isEmpty(data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> map = parseJSON2Map(data);
|
Map<String, Object> map = parseJSON2Map(data);
|
||||||
return this.generateProperties(this.reloadMap(map));
|
return this.generateProperties(this.reloadMap(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,44 +55,48 @@ public class NacosDataJsonParser extends AbstractNacosDataParser {
|
|||||||
* @return the map convert by json string
|
* @return the map convert by json string
|
||||||
* @throws IOException thrown if there is a problem parsing config.
|
* @throws IOException thrown if there is a problem parsing config.
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> parseJSON2Map(String json) throws IOException {
|
public static Map<String, Object> parseJSON2Map(String json) throws IOException {
|
||||||
Map<String, String> map = new HashMap<>(32);
|
Map<String, Object> result = new HashMap<>(32);
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
JsonNode jsonNode = mapper.readTree(json);
|
Map<String, Object> nacosDataMap = mapper.readValue(json, Map.class);
|
||||||
if (null == jsonNode) {
|
|
||||||
return map;
|
if (CollectionUtils.isEmpty(nacosDataMap)) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
parseJsonNode(map, jsonNode, "");
|
parseNacosDataMap(result, nacosDataMap, "");
|
||||||
return map;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseJsonNode(Map<String, String> jsonMap, JsonNode jsonNode,
|
private static void parseNacosDataMap(Map<String, Object> result,
|
||||||
String parentKey) {
|
Map<String, Object> dataMap, String parentKey) {
|
||||||
Iterator<String> fieldNames = jsonNode.fieldNames();
|
Set<Map.Entry<String, Object>> entries = dataMap.entrySet();
|
||||||
while (fieldNames.hasNext()) {
|
for (Iterator<Map.Entry<String, Object>> iterator = entries.iterator(); iterator
|
||||||
String name = fieldNames.next();
|
.hasNext();) {
|
||||||
String fullKey = StringUtils.isEmpty(parentKey) ? name
|
Map.Entry<String, Object> entry = iterator.next();
|
||||||
: parentKey + DOT + name;
|
String key = entry.getKey();
|
||||||
JsonNode resultValue = jsonNode.findValue(name);
|
Object value = entry.getValue();
|
||||||
if (null == resultValue) {
|
|
||||||
|
String fullKey = StringUtils.isEmpty(parentKey) ? key : key.startsWith("[")
|
||||||
|
? parentKey.concat(key) : parentKey.concat(DOT).concat(key);
|
||||||
|
|
||||||
|
if (value instanceof Map) {
|
||||||
|
Map<String, Object> map = (Map<String, Object>) value;
|
||||||
|
parseNacosDataMap(result, map, fullKey);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (resultValue.isArray()) {
|
else if (value instanceof Collection) {
|
||||||
Iterator<JsonNode> iterator = resultValue.elements();
|
int count = 0;
|
||||||
while (iterator != null && iterator.hasNext()) {
|
Collection<Object> collection = (Collection<Object>) value;
|
||||||
JsonNode next = iterator.next();
|
for (Object object : collection) {
|
||||||
if (null == next) {
|
parseNacosDataMap(result,
|
||||||
continue;
|
Collections.singletonMap("[" + (count++) + "]", object),
|
||||||
}
|
fullKey);
|
||||||
parseJsonNode(jsonMap, next, fullKey);
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (resultValue.isObject()) {
|
|
||||||
parseJsonNode(jsonMap, resultValue, fullKey);
|
result.put(fullKey, value);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
jsonMap.put(fullKey, resultValue.asText());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +50,13 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
if (StringUtils.isEmpty(data)) {
|
if (StringUtils.isEmpty(data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Map<String, String> map = parseXml2Map(data);
|
Map<String, Object> map = parseXml2Map(data);
|
||||||
return this.generateProperties(this.reloadMap(map));
|
return this.generateProperties(this.reloadMap(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> parseXml2Map(String xml) throws IOException {
|
private Map<String, Object> parseXml2Map(String xml) throws IOException {
|
||||||
xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", "");
|
xml = xml.replaceAll("\\r", "").replaceAll("\\n", "").replaceAll("\\t", "");
|
||||||
Map<String, String> map = new HashMap<>(32);
|
Map<String, Object> map = new HashMap<>(32);
|
||||||
try {
|
try {
|
||||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
|
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
|
||||||
.newDocumentBuilder();
|
.newDocumentBuilder();
|
||||||
@ -73,7 +73,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNodeList(NodeList nodeList, Map<String, String> map,
|
private void parseNodeList(NodeList nodeList, Map<String, Object> map,
|
||||||
String parentKey) {
|
String parentKey) {
|
||||||
if (nodeList == null || nodeList.getLength() < 1) {
|
if (nodeList == null || nodeList.getLength() < 1) {
|
||||||
return;
|
return;
|
||||||
@ -104,7 +104,7 @@ public class NacosDataXmlParser extends AbstractNacosDataParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNodeAttr(NamedNodeMap nodeMap, Map<String, String> map,
|
private void parseNodeAttr(NamedNodeMap nodeMap, Map<String, Object> map,
|
||||||
String parentKey) {
|
String parentKey) {
|
||||||
if (null == nodeMap || nodeMap.getLength() < 1) {
|
if (null == nodeMap || nodeMap.getLength() < 1) {
|
||||||
return;
|
return;
|
||||||
|
@ -39,6 +39,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -51,24 +52,23 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
|||||||
@PowerMockIgnore("javax.management.*")
|
@PowerMockIgnore("javax.management.*")
|
||||||
@PowerMockRunnerDelegate(SpringRunner.class)
|
@PowerMockRunnerDelegate(SpringRunner.class)
|
||||||
@PrepareForTest({ NacosConfigService.class })
|
@PrepareForTest({ NacosConfigService.class })
|
||||||
@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class,
|
@SpringBootTest(classes = NacosConfigurationXmlJsonTest.TestConfig.class, properties = {
|
||||||
properties = { "spring.application.name=xmlApp", "spring.profiles.active=dev",
|
"spring.application.name=xmlApp", "spring.profiles.active=dev",
|
||||||
"spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
"spring.cloud.nacos.config.server-addr=127.0.0.1:8848",
|
||||||
"spring.cloud.nacos.config.namespace=test-namespace",
|
"spring.cloud.nacos.config.namespace=test-namespace",
|
||||||
"spring.cloud.nacos.config.encode=utf-8",
|
"spring.cloud.nacos.config.encode=utf-8",
|
||||||
"spring.cloud.nacos.config.timeout=1000",
|
"spring.cloud.nacos.config.timeout=1000",
|
||||||
"spring.cloud.nacos.config.group=test-group",
|
"spring.cloud.nacos.config.group=test-group",
|
||||||
"spring.cloud.nacos.config.name=test-name",
|
"spring.cloud.nacos.config.name=test-name",
|
||||||
"spring.cloud.nacos.config.cluster-name=test-cluster",
|
"spring.cloud.nacos.config.cluster-name=test-cluster",
|
||||||
"spring.cloud.nacos.config.file-extension=xml",
|
"spring.cloud.nacos.config.file-extension=xml",
|
||||||
"spring.cloud.nacos.config.contextPath=test-contextpath",
|
"spring.cloud.nacos.config.contextPath=test-contextpath",
|
||||||
"spring.cloud.nacos.config.ext-config[0].data-id=ext-json-test.json",
|
"spring.cloud.nacos.config.ext-config[0].data-id=ext-json-test.json",
|
||||||
"spring.cloud.nacos.config.ext-config[1].data-id=ext-common02.properties",
|
"spring.cloud.nacos.config.ext-config[1].data-id=ext-common02.properties",
|
||||||
"spring.cloud.nacos.config.ext-config[1].group=GLOBAL_GROUP",
|
"spring.cloud.nacos.config.ext-config[1].group=GLOBAL_GROUP",
|
||||||
"spring.cloud.nacos.config.shared-dataids=shared-data1.properties",
|
"spring.cloud.nacos.config.shared-dataids=shared-data1.properties,shared-data.json",
|
||||||
"spring.cloud.nacos.config.accessKey=test-accessKey",
|
"spring.cloud.nacos.config.accessKey=test-accessKey",
|
||||||
"spring.cloud.nacos.config.secretKey=test-secretKey" },
|
"spring.cloud.nacos.config.secretKey=test-secretKey" }, webEnvironment = NONE)
|
||||||
webEnvironment = NONE)
|
|
||||||
public class NacosConfigurationXmlJsonTest {
|
public class NacosConfigurationXmlJsonTest {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -136,6 +136,22 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
return "shared-name=shared-value-1";
|
return "shared-name=shared-value-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("shared-data.json".equals(args[0])
|
||||||
|
&& "DEFAULT_GROUP".equals(args[1])) {
|
||||||
|
return "{\n" + " \"test\" : {\n"
|
||||||
|
+ " \"name\" : \"test\",\n"
|
||||||
|
+ " \"list\" : [\n" + " {\n"
|
||||||
|
+ " \"name\" :\"listname1\",\n"
|
||||||
|
+ " \"age\":1\n" + " },\n"
|
||||||
|
+ " {\n"
|
||||||
|
+ " \"name\" :\"listname2\",\n"
|
||||||
|
+ " \"age\":2\n" + " }\n"
|
||||||
|
+ " ],\n" + " \"metadata\" : {\n"
|
||||||
|
+ " \"intKey\" : 123,\n"
|
||||||
|
+ " \"booleanKey\" : true\n" + " }\n"
|
||||||
|
+ " }\n" + "}";
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -156,6 +172,9 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NacosRefreshHistory refreshHistory;
|
private NacosRefreshHistory refreshHistory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() throws Exception {
|
public void contextLoads() throws Exception {
|
||||||
|
|
||||||
@ -176,6 +195,27 @@ public class NacosConfigurationXmlJsonTest {
|
|||||||
|
|
||||||
checkoutEndpoint();
|
checkoutEndpoint();
|
||||||
|
|
||||||
|
checkJsonParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkJsonParser() {
|
||||||
|
assertThat(environment.getProperty("test.name", String.class)).isEqualTo("test");
|
||||||
|
|
||||||
|
assertThat(environment.getProperty("test.list[0].name", String.class))
|
||||||
|
.isEqualTo("listname1");
|
||||||
|
assertThat(environment.getProperty("test.list[0].age", Integer.class))
|
||||||
|
.isEqualTo(1);
|
||||||
|
|
||||||
|
assertThat(environment.getProperty("test.list[1].name", String.class))
|
||||||
|
.isEqualTo("listname2");
|
||||||
|
assertThat(environment.getProperty("test.list[1].age", Integer.class))
|
||||||
|
.isEqualTo(2);
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
(Integer) environment.getProperty("test.metadata.intKey", Object.class))
|
||||||
|
.isEqualTo(123);
|
||||||
|
assertThat((Boolean) environment.getProperty("test.metadata.booleanKey",
|
||||||
|
Object.class)).isEqualTo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkoutNacosConfigServerAddr() {
|
private void checkoutNacosConfigServerAddr() {
|
||||||
|
@ -44,9 +44,9 @@ public class NacosRibbonClientConfiguration {
|
|||||||
public ServerList<?> ribbonServerList(IClientConfig config,
|
public ServerList<?> ribbonServerList(IClientConfig config,
|
||||||
NacosDiscoveryProperties nacosDiscoveryProperties) {
|
NacosDiscoveryProperties nacosDiscoveryProperties) {
|
||||||
if (this.propertiesFactory.isSet(ServerList.class, config.getClientName())) {
|
if (this.propertiesFactory.isSet(ServerList.class, config.getClientName())) {
|
||||||
ServerList serverList = this.propertiesFactory.get(ServerList.class, config,
|
ServerList serverList = this.propertiesFactory.get(ServerList.class, config,
|
||||||
config.getClientName());
|
config.getClientName());
|
||||||
return serverList;
|
return serverList;
|
||||||
}
|
}
|
||||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||||
serverList.initWithNiwsConfig(config);
|
serverList.initWithNiwsConfig(config);
|
||||||
|
@ -35,50 +35,47 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liujunjie
|
* @author liujunjie
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(classes =
|
@SpringBootTest(classes = NacosRibbonClientPropertyOverrideTests.TestConfiguration.class,
|
||||||
NacosRibbonClientPropertyOverrideTests.TestConfiguration.class,
|
properties = { "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848",
|
||||||
properties = {"spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848",
|
"spring.cloud.nacos.discovery.port=18080",
|
||||||
"spring.cloud.nacos.discovery.port=18080",
|
"spring.cloud.nacos.discovery.service=remoteApp",
|
||||||
"spring.cloud.nacos.discovery.service=remoteApp",
|
"localApp.ribbon.NIWSServerListClassName="
|
||||||
"localApp.ribbon.NIWSServerListClassName="
|
+ "com.netflix.loadbalancer.ConfigurationBasedServerList",
|
||||||
+ "com.netflix.loadbalancer.ConfigurationBasedServerList",
|
"localApp.ribbon.listOfServers=127.0.0.1:19090",
|
||||||
"localApp.ribbon.listOfServers=127.0.0.1:19090",
|
"localApp.ribbon.ServerListRefreshInterval=15000" })
|
||||||
"localApp.ribbon.ServerListRefreshInterval=15000"})
|
|
||||||
public class NacosRibbonClientPropertyOverrideTests {
|
public class NacosRibbonClientPropertyOverrideTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SpringClientFactory factory;
|
private SpringClientFactory factory;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serverListOverridesToTest() {
|
||||||
|
ConfigurationBasedServerList.class
|
||||||
|
.cast(getLoadBalancer("localApp").getServerListImpl());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serverListOverridesToTest() {
|
public void serverListRemoteTest() {
|
||||||
ConfigurationBasedServerList.class
|
NacosServerList.class.cast(getLoadBalancer("remoteApp").getServerListImpl());
|
||||||
.cast(getLoadBalancer("localApp").getServerListImpl());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@SuppressWarnings("unchecked")
|
||||||
public void serverListRemoteTest() {
|
private ZoneAwareLoadBalancer<Server> getLoadBalancer(String name) {
|
||||||
NacosServerList.class
|
return (ZoneAwareLoadBalancer<Server>) this.factory.getLoadBalancer(name);
|
||||||
.cast(getLoadBalancer("remoteApp").getServerListImpl());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@Configuration
|
||||||
private ZoneAwareLoadBalancer<Server> getLoadBalancer(String name) {
|
@RibbonClients
|
||||||
return (ZoneAwareLoadBalancer<Server>) this.factory.getLoadBalancer(name);
|
@EnableAutoConfiguration
|
||||||
}
|
@ImportAutoConfiguration({ UtilAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
|
||||||
|
RibbonNacosAutoConfiguration.class, NacosDiscoveryClientConfiguration.class })
|
||||||
|
protected static class TestConfiguration {
|
||||||
|
|
||||||
@Configuration
|
}
|
||||||
@RibbonClients
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
@ImportAutoConfiguration({UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
ArchaiusAutoConfiguration.class, RibbonNacosAutoConfiguration.class,
|
|
||||||
NacosDiscoveryClientConfiguration.class})
|
|
||||||
protected static class TestConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,6 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.csp</groupId>
|
|
||||||
<artifactId>sentinel-web-servlet</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
@ -57,6 +52,11 @@
|
|||||||
<artifactId>sentinel-spring-webflux-adapter</artifactId>
|
<artifactId>sentinel-spring-webflux-adapter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.csp</groupId>
|
||||||
|
<artifactId>sentinel-spring-webmvc-adapter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
@ -26,6 +26,11 @@ public final class SentinelConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String PROPERTY_PREFIX = "spring.cloud.sentinel";
|
public static final String PROPERTY_PREFIX = "spring.cloud.sentinel";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block page key.
|
||||||
|
*/
|
||||||
|
public static final String BLOCK_PAGE_URL_CONF_KEY = "csp.sentinel.web.servlet.block.page";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block type.
|
* Block type.
|
||||||
*/
|
*/
|
||||||
@ -41,6 +46,21 @@ public final class SentinelConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String URLCLEANER_TYPE = "urlCleaner";
|
public static final String URLCLEANER_TYPE = "urlCleaner";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cold factor.
|
||||||
|
*/
|
||||||
|
public static final String COLD_FACTOR = "3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The charset.
|
||||||
|
*/
|
||||||
|
public static final String CHARSET = "UTF-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Sentinel api port.
|
||||||
|
*/
|
||||||
|
public static final String API_PORT = "8719";
|
||||||
|
|
||||||
private SentinelConstants() {
|
private SentinelConstants() {
|
||||||
throw new AssertionError("Must not instantiate constant utility class");
|
throw new AssertionError("Must not instantiate constant utility class");
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.alibaba.cloud.sentinel;
|
package com.alibaba.cloud.sentinel;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -26,7 +27,9 @@ import com.alibaba.csp.sentinel.log.LogBase;
|
|||||||
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
|
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +55,11 @@ public class SentinelProperties {
|
|||||||
*/
|
*/
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The process page when the flow control is triggered.
|
||||||
|
*/
|
||||||
|
private String blockPage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configurations about datasource, like 'nacos', 'apollo', 'file', 'zookeeper'.
|
* Configurations about datasource, like 'nacos', 'apollo', 'file', 'zookeeper'.
|
||||||
*/
|
*/
|
||||||
@ -75,7 +83,7 @@ public class SentinelProperties {
|
|||||||
private Servlet servlet = new Servlet();
|
private Servlet servlet = new Servlet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sentinel filter when the application is web, the configuration is effective.
|
* Sentinel interceptor when the application is web, the configuration is effective.
|
||||||
*/
|
*/
|
||||||
private Filter filter = new Filter();
|
private Filter filter = new Filter();
|
||||||
|
|
||||||
@ -174,12 +182,23 @@ public class SentinelProperties {
|
|||||||
this.httpMethodSpecify = httpMethodSpecify;
|
this.httpMethodSpecify = httpMethodSpecify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBlockPage() {
|
||||||
|
if (StringUtils.hasText(this.blockPage)) {
|
||||||
|
return this.blockPage;
|
||||||
|
}
|
||||||
|
return this.servlet.getBlockPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockPage(String blockPage) {
|
||||||
|
this.blockPage = blockPage;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Flow {
|
public static class Flow {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cold factor {@link SentinelConfig#COLD_FACTOR}.
|
* The cold factor {@link SentinelConfig#COLD_FACTOR}.
|
||||||
*/
|
*/
|
||||||
private String coldFactor = "3";
|
private String coldFactor = SentinelConstants.COLD_FACTOR;
|
||||||
|
|
||||||
public String getColdFactor() {
|
public String getColdFactor() {
|
||||||
return coldFactor;
|
return coldFactor;
|
||||||
@ -198,10 +217,15 @@ public class SentinelProperties {
|
|||||||
*/
|
*/
|
||||||
private String blockPage;
|
private String blockPage;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@DeprecatedConfigurationProperty(
|
||||||
|
reason = "replaced to SentinelProperties#blockPage.",
|
||||||
|
replacement = SentinelConstants.PROPERTY_PREFIX + ".block-page")
|
||||||
public String getBlockPage() {
|
public String getBlockPage() {
|
||||||
return blockPage;
|
return blockPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setBlockPage(String blockPage) {
|
public void setBlockPage(String blockPage) {
|
||||||
this.blockPage = blockPage;
|
this.blockPage = blockPage;
|
||||||
}
|
}
|
||||||
@ -224,7 +248,7 @@ public class SentinelProperties {
|
|||||||
* Charset when sentinel write or search metric file.
|
* Charset when sentinel write or search metric file.
|
||||||
* {@link SentinelConfig#CHARSET}
|
* {@link SentinelConfig#CHARSET}
|
||||||
*/
|
*/
|
||||||
private String charset = "UTF-8";
|
private String charset = SentinelConstants.CHARSET;
|
||||||
|
|
||||||
public String getFileSingleSize() {
|
public String getFileSingleSize() {
|
||||||
return fileSingleSize;
|
return fileSingleSize;
|
||||||
@ -257,7 +281,7 @@ public class SentinelProperties {
|
|||||||
/**
|
/**
|
||||||
* Sentinel api port, default value is 8719 {@link TransportConfig#SERVER_PORT}.
|
* Sentinel api port, default value is 8719 {@link TransportConfig#SERVER_PORT}.
|
||||||
*/
|
*/
|
||||||
private String port = "8719";
|
private String port = SentinelConstants.API_PORT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sentinel dashboard address, won't try to connect dashboard when address is
|
* Sentinel dashboard address, won't try to connect dashboard when address is
|
||||||
@ -314,18 +338,18 @@ public class SentinelProperties {
|
|||||||
public static class Filter {
|
public static class Filter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sentinel filter chain order.
|
* SentinelWebInterceptor order, will be register to InterceptorRegistry.
|
||||||
*/
|
*/
|
||||||
private int order = Ordered.HIGHEST_PRECEDENCE;
|
private int order = Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL pattern for sentinel filter, default is /*.
|
* URL pattern for SentinelWebInterceptor, default is /*.
|
||||||
*/
|
*/
|
||||||
private List<String> urlPatterns;
|
private List<String> urlPatterns = Arrays.asList("/*");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable to instance
|
* Enable to instance
|
||||||
* {@link com.alibaba.csp.sentinel.adapter.servlet.CommonFilter}.
|
* {@link com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor}.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
@ -16,18 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.cloud.sentinel;
|
package com.alibaba.cloud.sentinel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor;
|
||||||
import javax.servlet.Filter;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
|
||||||
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.DefaultBlockExceptionHandler;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcConfig;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -37,19 +33,22 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiaojing
|
* @author xiaojing
|
||||||
|
* @author yuhuangbin
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||||
@ConditionalOnClass(CommonFilter.class)
|
|
||||||
@ConditionalOnProperty(name = "spring.cloud.sentinel.enabled", matchIfMissing = true)
|
@ConditionalOnProperty(name = "spring.cloud.sentinel.enabled", matchIfMissing = true)
|
||||||
|
@ConditionalOnClass(SentinelWebInterceptor.class)
|
||||||
@EnableConfigurationProperties(SentinelProperties.class)
|
@EnableConfigurationProperties(SentinelProperties.class)
|
||||||
public class SentinelWebAutoConfiguration {
|
public class SentinelWebAutoConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory
|
private static final Logger log = LoggerFactory
|
||||||
.getLogger(SentinelWebAutoConfiguration.class);
|
.getLogger(SentinelWebAutoConfiguration.class);
|
||||||
@ -61,44 +60,61 @@ public class SentinelWebAutoConfiguration {
|
|||||||
private Optional<UrlCleaner> urlCleanerOptional;
|
private Optional<UrlCleaner> urlCleanerOptional;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Optional<UrlBlockHandler> urlBlockHandlerOptional;
|
private Optional<BlockExceptionHandler> blockExceptionHandlerOptional;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Optional<RequestOriginParser> requestOriginParserOptional;
|
private Optional<RequestOriginParser> requestOriginParserOptional;
|
||||||
|
|
||||||
@PostConstruct
|
@Autowired
|
||||||
public void init() {
|
private Optional<SentinelWebInterceptor> sentinelWebInterceptorOptional;
|
||||||
urlBlockHandlerOptional.ifPresent(WebCallbackManager::setUrlBlockHandler);
|
|
||||||
urlCleanerOptional.ifPresent(WebCallbackManager::setUrlCleaner);
|
@Override
|
||||||
requestOriginParserOptional.ifPresent(WebCallbackManager::setRequestOriginParser);
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
if (!sentinelWebInterceptorOptional.isPresent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SentinelProperties.Filter filterConfig = properties.getFilter();
|
||||||
|
registry.addInterceptor(sentinelWebInterceptorOptional.get())
|
||||||
|
.order(filterConfig.getOrder())
|
||||||
|
.addPathPatterns(filterConfig.getUrlPatterns());
|
||||||
|
log.info(
|
||||||
|
"[Sentinel Starter] register SentinelWebInterceptor with urlPatterns: {}.",
|
||||||
|
filterConfig.getUrlPatterns());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",
|
@ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",
|
||||||
matchIfMissing = true)
|
matchIfMissing = true)
|
||||||
public FilterRegistrationBean sentinelFilter() {
|
public SentinelWebInterceptor sentinelWebInterceptor(
|
||||||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
|
SentinelWebMvcConfig sentinelWebMvcConfig) {
|
||||||
|
return new SentinelWebInterceptor(sentinelWebMvcConfig);
|
||||||
|
}
|
||||||
|
|
||||||
SentinelProperties.Filter filterConfig = properties.getFilter();
|
@Bean
|
||||||
|
@ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled",
|
||||||
|
matchIfMissing = true)
|
||||||
|
public SentinelWebMvcConfig sentinelWebMvcConfig() {
|
||||||
|
SentinelWebMvcConfig sentinelWebMvcConfig = new SentinelWebMvcConfig();
|
||||||
|
sentinelWebMvcConfig.setHttpMethodSpecify(properties.getHttpMethodSpecify());
|
||||||
|
|
||||||
if (filterConfig.getUrlPatterns() == null
|
if (blockExceptionHandlerOptional.isPresent()) {
|
||||||
|| filterConfig.getUrlPatterns().isEmpty()) {
|
blockExceptionHandlerOptional
|
||||||
List<String> defaultPatterns = new ArrayList<>();
|
.ifPresent(sentinelWebMvcConfig::setBlockExceptionHandler);
|
||||||
defaultPatterns.add("/*");
|
}
|
||||||
filterConfig.setUrlPatterns(defaultPatterns);
|
else {
|
||||||
|
if (StringUtils.hasText(properties.getBlockPage())) {
|
||||||
|
sentinelWebMvcConfig.setBlockExceptionHandler(((request, response,
|
||||||
|
e) -> response.sendRedirect(properties.getBlockPage())));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sentinelWebMvcConfig
|
||||||
|
.setBlockExceptionHandler(new DefaultBlockExceptionHandler());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registration.addUrlPatterns(filterConfig.getUrlPatterns().toArray(new String[0]));
|
urlCleanerOptional.ifPresent(sentinelWebMvcConfig::setUrlCleaner);
|
||||||
Filter filter = new CommonFilter();
|
requestOriginParserOptional.ifPresent(sentinelWebMvcConfig::setOriginParser);
|
||||||
registration.setFilter(filter);
|
return sentinelWebMvcConfig;
|
||||||
registration.setOrder(filterConfig.getOrder());
|
|
||||||
registration.addInitParameter("HTTP_METHOD_SPECIFY",
|
|
||||||
String.valueOf(properties.getHttpMethodSpecify()));
|
|
||||||
log.info(
|
|
||||||
"[Sentinel Starter] register Sentinel CommonFilter with urlPatterns: {}.",
|
|
||||||
filterConfig.getUrlPatterns());
|
|
||||||
return registration;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import javax.annotation.PostConstruct;
|
|||||||
import com.alibaba.cloud.sentinel.SentinelProperties;
|
import com.alibaba.cloud.sentinel.SentinelProperties;
|
||||||
import com.alibaba.cloud.sentinel.datasource.converter.JsonConverter;
|
import com.alibaba.cloud.sentinel.datasource.converter.JsonConverter;
|
||||||
import com.alibaba.cloud.sentinel.datasource.converter.XmlConverter;
|
import com.alibaba.cloud.sentinel.datasource.converter.XmlConverter;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
|
||||||
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
|
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
|
||||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
import com.alibaba.csp.sentinel.init.InitExecutor;
|
import com.alibaba.csp.sentinel.init.InitExecutor;
|
||||||
@ -50,6 +49,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
|
||||||
|
import static com.alibaba.csp.sentinel.config.SentinelConfig.setConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiaojing
|
* @author xiaojing
|
||||||
* @author jiashuai.xie
|
* @author jiashuai.xie
|
||||||
@ -124,8 +126,8 @@ public class SentinelAutoConfiguration {
|
|||||||
System.setProperty(SentinelConfig.COLD_FACTOR,
|
System.setProperty(SentinelConfig.COLD_FACTOR,
|
||||||
properties.getFlow().getColdFactor());
|
properties.getFlow().getColdFactor());
|
||||||
}
|
}
|
||||||
if (StringUtils.hasText(properties.getServlet().getBlockPage())) {
|
if (StringUtils.hasText(properties.getBlockPage())) {
|
||||||
WebServletConfig.setBlockPage(properties.getServlet().getBlockPage());
|
setConfig(BLOCK_PAGE_URL_CONF_KEY, properties.getBlockPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// earlier initialize
|
// earlier initialize
|
||||||
|
@ -20,7 +20,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.alibaba.cloud.sentinel.SentinelProperties;
|
import com.alibaba.cloud.sentinel.SentinelProperties;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
|
||||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
import com.alibaba.csp.sentinel.log.LogBase;
|
import com.alibaba.csp.sentinel.log.LogBase;
|
||||||
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
|
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
|
||||||
@ -34,6 +33,8 @@ import com.alibaba.csp.sentinel.util.AppNameUtil;
|
|||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
|
|
||||||
|
import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint for Sentinel, contains ans properties and rules.
|
* Endpoint for Sentinel, contains ans properties and rules.
|
||||||
*
|
*
|
||||||
@ -56,7 +57,7 @@ public class SentinelEndpoint {
|
|||||||
result.put("appName", AppNameUtil.getAppName());
|
result.put("appName", AppNameUtil.getAppName());
|
||||||
result.put("logDir", LogBase.getLogBaseDir());
|
result.put("logDir", LogBase.getLogBaseDir());
|
||||||
result.put("logUsePid", LogBase.isLogNameUsePid());
|
result.put("logUsePid", LogBase.isLogNameUsePid());
|
||||||
result.put("blockPage", WebServletConfig.getBlockPage());
|
result.put("blockPage", SentinelConfig.getConfig(BLOCK_PAGE_URL_CONF_KEY));
|
||||||
result.put("metricsFileSize", SentinelConfig.singleMetricFileSize());
|
result.put("metricsFileSize", SentinelConfig.singleMetricFileSize());
|
||||||
result.put("metricsFileCharset", SentinelConfig.charset());
|
result.put("metricsFileCharset", SentinelConfig.charset());
|
||||||
result.put("totalMetricsFileCount", SentinelConfig.totalMetricFileCount());
|
result.put("totalMetricsFileCount", SentinelConfig.totalMetricFileCount());
|
||||||
|
@ -43,13 +43,13 @@
|
|||||||
"name": "spring.cloud.sentinel.filter.order",
|
"name": "spring.cloud.sentinel.filter.order",
|
||||||
"type": "java.lang.Integer",
|
"type": "java.lang.Integer",
|
||||||
"defaultValue": "Integer.MIN_VALUE",
|
"defaultValue": "Integer.MIN_VALUE",
|
||||||
"description": "sentinel filter chain order, will be set to FilterRegistrationBean."
|
"description": "SentinelWebInterceptor order, will be register to InterceptorRegistry."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spring.cloud.sentinel.filter.enabled",
|
"name": "spring.cloud.sentinel.filter.enabled",
|
||||||
"type": "java.lang.Boolean",
|
"type": "java.lang.Boolean",
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"description": "Enable to instance com.alibaba.csp.sentinel.adapter.servlet.CommonFilter."
|
"description": "Enable to register com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spring.cloud.sentinel.metric.charset",
|
"name": "spring.cloud.sentinel.metric.charset",
|
||||||
@ -79,10 +79,15 @@
|
|||||||
"description": "log file should with pid."
|
"description": "log file should with pid."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spring.cloud.sentinel.servlet.blockPage",
|
"name": "spring.cloud.sentinel.block-page",
|
||||||
"type": "java.lang.String",
|
"type": "java.lang.String",
|
||||||
"description": "the process page when the flow control is triggered."
|
"description": "the process page when the flow control is triggered."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spring.cloud.sentinel.servlet.block-page",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "recommoned use spring.cloud.sentinel.block-page."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spring.cloud.sentinel.flow.coldFactor",
|
"name": "spring.cloud.sentinel.flow.coldFactor",
|
||||||
"type": "java.lang.String",
|
"type": "java.lang.String",
|
||||||
|
@ -24,7 +24,6 @@ import com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration;
|
|||||||
import com.alibaba.cloud.sentinel.custom.SentinelBeanPostProcessor;
|
import com.alibaba.cloud.sentinel.custom.SentinelBeanPostProcessor;
|
||||||
import com.alibaba.cloud.sentinel.endpoint.SentinelEndpoint;
|
import com.alibaba.cloud.sentinel.endpoint.SentinelEndpoint;
|
||||||
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
|
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
|
||||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
import com.alibaba.csp.sentinel.log.LogBase;
|
import com.alibaba.csp.sentinel.log.LogBase;
|
||||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||||
@ -43,7 +42,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.web.server.LocalServerPort;
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpRequest;
|
import org.springframework.http.HttpRequest;
|
||||||
@ -55,6 +53,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@ -70,7 +69,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
|||||||
"spring.cloud.sentinel.filter.urlPatterns=/*,/test",
|
"spring.cloud.sentinel.filter.urlPatterns=/*,/test",
|
||||||
"spring.cloud.sentinel.metric.fileSingleSize=9999",
|
"spring.cloud.sentinel.metric.fileSingleSize=9999",
|
||||||
"spring.cloud.sentinel.metric.fileTotalCount=100",
|
"spring.cloud.sentinel.metric.fileTotalCount=100",
|
||||||
"spring.cloud.sentinel.servlet.blockPage=/error",
|
"spring.cloud.sentinel.blockPage=/error",
|
||||||
"spring.cloud.sentinel.flow.coldFactor=3",
|
"spring.cloud.sentinel.flow.coldFactor=3",
|
||||||
"spring.cloud.sentinel.eager=true",
|
"spring.cloud.sentinel.eager=true",
|
||||||
"spring.cloud.sentinel.log.switchPid=true",
|
"spring.cloud.sentinel.log.switchPid=true",
|
||||||
@ -84,9 +83,6 @@ public class SentinelAutoConfigurationTests {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SentinelProperties sentinelProperties;
|
private SentinelProperties sentinelProperties;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FilterRegistrationBean filterRegistrationBean;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SentinelBeanPostProcessor sentinelBeanPostProcessor;
|
private SentinelBeanPostProcessor sentinelBeanPostProcessor;
|
||||||
|
|
||||||
@ -130,9 +126,6 @@ public class SentinelAutoConfigurationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() throws Exception {
|
public void contextLoads() throws Exception {
|
||||||
|
|
||||||
assertThat(filterRegistrationBean).isNotNull();
|
|
||||||
assertThat(filterRegistrationBean).isNotNull();
|
|
||||||
assertThat(sentinelBeanPostProcessor).isNotNull();
|
assertThat(sentinelBeanPostProcessor).isNotNull();
|
||||||
|
|
||||||
checkSentinelLog();
|
checkSentinelLog();
|
||||||
@ -195,12 +188,6 @@ public class SentinelAutoConfigurationTests {
|
|||||||
assertThat(sentinelProperties.getLog().isSwitchPid()).isEqualTo(true);
|
assertThat(sentinelProperties.getLog().isSwitchPid()).isEqualTo(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFilter() {
|
|
||||||
assertThat(123).isEqualTo(filterRegistrationBean.getOrder());
|
|
||||||
assertThat(2).isEqualTo(filterRegistrationBean.getUrlPatterns().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSentinelSystemProperties() {
|
public void testSentinelSystemProperties() {
|
||||||
assertThat(LogBase.isLogNameUsePid()).isEqualTo(true);
|
assertThat(LogBase.isLogNameUsePid()).isEqualTo(true);
|
||||||
@ -212,7 +199,7 @@ public class SentinelAutoConfigurationTests {
|
|||||||
assertThat(SentinelConfig.singleMetricFileSize()).isEqualTo(9999);
|
assertThat(SentinelConfig.singleMetricFileSize()).isEqualTo(9999);
|
||||||
assertThat(SentinelConfig.totalMetricFileCount()).isEqualTo(100);
|
assertThat(SentinelConfig.totalMetricFileCount()).isEqualTo(100);
|
||||||
assertThat(SentinelConfig.charset()).isEqualTo("UTF-8");
|
assertThat(SentinelConfig.charset()).isEqualTo("UTF-8");
|
||||||
assertThat(WebServletConfig.getBlockPage()).isEqualTo("/error");
|
assertThat(SentinelConfig.getConfig(BLOCK_PAGE_URL_CONF_KEY)).isEqualTo("/error");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -16,18 +16,14 @@
|
|||||||
|
|
||||||
package com.alibaba.cloud.sentinel;
|
package com.alibaba.cloud.sentinel;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration;
|
import com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.DefaultBlockExceptionHandler;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
|
||||||
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcConfig;
|
||||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@ -53,7 +49,7 @@ public class SentinelBeanAutowiredTests {
|
|||||||
private UrlCleaner urlCleaner;
|
private UrlCleaner urlCleaner;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UrlBlockHandler urlBlockHandler;
|
private BlockExceptionHandler blockExceptionHandler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RequestOriginParser requestOriginParser;
|
private RequestOriginParser requestOriginParser;
|
||||||
@ -61,10 +57,13 @@ public class SentinelBeanAutowiredTests {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SentinelProperties sentinelProperties;
|
private SentinelProperties sentinelProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SentinelWebMvcConfig sentinelWebMvcConfig;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() throws Exception {
|
public void contextLoads() throws Exception {
|
||||||
assertThat(urlCleaner).isNotNull();
|
assertThat(urlCleaner).isNotNull();
|
||||||
assertThat(urlBlockHandler).isNotNull();
|
assertThat(blockExceptionHandler).isNotNull();
|
||||||
assertThat(requestOriginParser).isNotNull();
|
assertThat(requestOriginParser).isNotNull();
|
||||||
assertThat(sentinelProperties).isNotNull();
|
assertThat(sentinelProperties).isNotNull();
|
||||||
|
|
||||||
@ -80,10 +79,10 @@ public class SentinelBeanAutowiredTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBeanAutowired() {
|
public void testBeanAutowired() {
|
||||||
assertThat(WebCallbackManager.getUrlCleaner()).isEqualTo(urlCleaner);
|
assertThat(sentinelWebMvcConfig.getUrlCleaner()).isEqualTo(urlCleaner);
|
||||||
assertThat(WebCallbackManager.getUrlBlockHandler()).isEqualTo(urlBlockHandler);
|
assertThat(sentinelWebMvcConfig.getBlockExceptionHandler())
|
||||||
assertThat(WebCallbackManager.getRequestOriginParser())
|
.isEqualTo(blockExceptionHandler);
|
||||||
.isEqualTo(requestOriginParser);
|
assertThat(sentinelWebMvcConfig.getOriginParser()).isEqualTo(requestOriginParser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -113,15 +112,8 @@ public class SentinelBeanAutowiredTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public UrlBlockHandler urlBlockHandler() {
|
public BlockExceptionHandler blockExceptionHandler() {
|
||||||
return new UrlBlockHandler() {
|
return new DefaultBlockExceptionHandler();
|
||||||
@Override
|
|
||||||
public void blocked(HttpServletRequest httpServletRequest,
|
|
||||||
HttpServletResponse httpServletResponse, BlockException e)
|
|
||||||
throws IOException {
|
|
||||||
FilterUtil.blockRequest(httpServletRequest, httpServletResponse);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,8 @@ public final class RocketMQBinderUtils {
|
|||||||
result.setNameServer(rocketBinderConfigurationProperties.getNameServer());
|
result.setNameServer(rocketBinderConfigurationProperties.getNameServer());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.setNameServer(Arrays.asList(rocketMQProperties.getNameServer().split(";")));
|
result.setNameServer(
|
||||||
|
Arrays.asList(rocketMQProperties.getNameServer().split(";")));
|
||||||
}
|
}
|
||||||
if (rocketMQProperties.getProducer() == null
|
if (rocketMQProperties.getProducer() == null
|
||||||
|| StringUtils.isEmpty(rocketMQProperties.getProducer().getAccessKey())) {
|
|| StringUtils.isEmpty(rocketMQProperties.getProducer().getAccessKey())) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user