mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
2020 build done, unit test failed
This commit is contained in:
parent
29091948e9
commit
e7521c02c9
22
pom.xml
22
pom.xml
@ -80,7 +80,7 @@
|
||||
|
||||
<properties>
|
||||
<!-- Project revision -->
|
||||
<revision>2.2.6-SNAPSHOT</revision>
|
||||
<revision>2021.1-SNAPSHOT</revision>
|
||||
|
||||
<!-- Spring Cloud -->
|
||||
<spring.cloud.version>2020.0.1</spring.cloud.version>
|
||||
@ -195,6 +195,21 @@
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
</plugin>
|
||||
|
||||
<!-- disable auto format from parent -->
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
<version>${spring-javaformat.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
@ -219,10 +234,6 @@
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
@ -241,6 +252,7 @@
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<description>Spring Cloud Alibaba Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.2.6-SNAPSHOT</revision>
|
||||
<revision>2021.1-SNAPSHOT</revision>
|
||||
<sentinel.version>1.8.0</sentinel.version>
|
||||
<seata.version>1.3.0</seata.version>
|
||||
<nacos.client.version>1.4.1</nacos.client.version>
|
||||
|
@ -47,6 +47,11 @@
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
|
@ -32,11 +32,10 @@ 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.EmptyResponse;
|
||||
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.client.loadbalancer.Response;
|
||||
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
|
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
|
||||
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
|
||||
@ -103,9 +102,17 @@ public class ConsumerSCLBApplication {
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Response<ServiceInstance>> choose(Request request) {
|
||||
log.info("random spring cloud loadbalacer active -.-");
|
||||
public Mono<Response<ServiceInstance>> choose(org.springframework.cloud.client.loadbalancer.Request request) {
|
||||
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
|
||||
.getIfAvailable(NoopServiceInstanceListSupplier::new);
|
||||
|
||||
return supplier.get().next().map(this::getInstanceResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Response<ServiceInstance>> choose() {
|
||||
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
|
||||
.getIfAvailable(NoopServiceInstanceListSupplier::new);
|
||||
return supplier.get().next().map(this::getInstanceResponse);
|
||||
@ -120,7 +127,6 @@ public class ConsumerSCLBApplication {
|
||||
|
||||
return new DefaultResponse(instance);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class,
|
||||
|
@ -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.fallback;
|
||||
|
||||
import com.alibaba.cloud.examples.service.EchoService;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* <p>
|
||||
* sentinel 降级处理
|
||||
*/
|
||||
public class EchoServiceFallback implements EchoService {
|
||||
|
||||
private Throwable throwable;
|
||||
|
||||
EchoServiceFallback(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用服务提供方的输出接口.
|
||||
* @param str 用户输入
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String echo(String str) {
|
||||
return "consumer-fallback-default-str" + throwable.getMessage();
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +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.fallback;
|
||||
|
||||
import feign.hystrix.FallbackFactory;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
@Component
|
||||
public class EchoServiceFallbackFactory implements FallbackFactory<EchoServiceFallback> {
|
||||
|
||||
@Override
|
||||
public EchoServiceFallback create(Throwable throwable) {
|
||||
return new EchoServiceFallback(throwable);
|
||||
}
|
||||
|
||||
}
|
@ -16,8 +16,6 @@
|
||||
|
||||
package com.alibaba.cloud.examples.service;
|
||||
|
||||
import com.alibaba.cloud.examples.fallback.EchoServiceFallbackFactory;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -27,8 +25,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
* <p>
|
||||
* example feign client
|
||||
*/
|
||||
@FeignClient(name = "service-provider",
|
||||
fallbackFactory = EchoServiceFallbackFactory.class)
|
||||
@FeignClient(name = "service-provider")
|
||||
public interface EchoService {
|
||||
|
||||
/**
|
||||
|
@ -137,6 +137,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,102 +1,102 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.sentinel.gateway.zuul;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.alibaba.cloud.sentinel.gateway.ConfigConstants;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.RequestOriginParser;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.ZuulGatewayCallbackManager;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
|
||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Sentinel Spring Cloud Zuul AutoConfiguration.
|
||||
*
|
||||
* @author tiger
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ZuulServlet.class)
|
||||
@ConditionalOnProperty(prefix = ConfigConstants.ZUUL_PREFIX, name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@EnableConfigurationProperties(SentinelZuulProperties.class)
|
||||
public class SentinelZuulAutoConfiguration {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(SentinelZuulAutoConfiguration.class);
|
||||
|
||||
@Autowired
|
||||
private Optional<RequestOriginParser> requestOriginParserOptional;
|
||||
|
||||
@Autowired
|
||||
private SentinelZuulProperties zuulProperties;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
requestOriginParserOptional
|
||||
.ifPresent(ZuulGatewayCallbackManager::setOriginParser);
|
||||
System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY,
|
||||
String.valueOf(ConfigConstants.APP_TYPE_ZUUL_GATEWAY));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SentinelZuulPreFilter sentinelZuulPreFilter() {
|
||||
logger.info("[Sentinel Zuul] register SentinelZuulPreFilter {}",
|
||||
zuulProperties.getOrder().getPre());
|
||||
return new SentinelZuulPreFilter(zuulProperties.getOrder().getPre());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SentinelZuulPostFilter sentinelZuulPostFilter() {
|
||||
logger.info("[Sentinel Zuul] register SentinelZuulPostFilter {}",
|
||||
zuulProperties.getOrder().getPost());
|
||||
return new SentinelZuulPostFilter(zuulProperties.getOrder().getPost());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SentinelZuulErrorFilter sentinelZuulErrorFilter() {
|
||||
logger.info("[Sentinel Zuul] register SentinelZuulErrorFilter {}",
|
||||
zuulProperties.getOrder().getError());
|
||||
return new SentinelZuulErrorFilter(zuulProperties.getOrder().getError());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FallBackProviderHandler fallBackProviderHandler(
|
||||
DefaultListableBeanFactory beanFactory) {
|
||||
return new FallBackProviderHandler(beanFactory);
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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.gateway.zuul;
|
||||
//
|
||||
//import java.util.Optional;
|
||||
//
|
||||
//import javax.annotation.PostConstruct;
|
||||
//
|
||||
//import com.alibaba.cloud.sentinel.gateway.ConfigConstants;
|
||||
//import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.RequestOriginParser;
|
||||
//import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.ZuulGatewayCallbackManager;
|
||||
//import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter;
|
||||
//import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter;
|
||||
//import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
|
||||
//import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
//import com.netflix.zuul.http.ZuulServlet;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
//import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//
|
||||
///**
|
||||
// * Sentinel Spring Cloud Zuul AutoConfiguration.
|
||||
// *
|
||||
// * @author tiger
|
||||
// */
|
||||
//@Configuration(proxyBeanMethods = false)
|
||||
//@ConditionalOnClass(ZuulServlet.class)
|
||||
//@ConditionalOnProperty(prefix = ConfigConstants.ZUUL_PREFIX, name = "enabled",
|
||||
// havingValue = "true", matchIfMissing = true)
|
||||
//@EnableConfigurationProperties(SentinelZuulProperties.class)
|
||||
//public class SentinelZuulAutoConfiguration {
|
||||
//
|
||||
// private static final Logger logger = LoggerFactory
|
||||
// .getLogger(SentinelZuulAutoConfiguration.class);
|
||||
//
|
||||
// @Autowired
|
||||
// private Optional<RequestOriginParser> requestOriginParserOptional;
|
||||
//
|
||||
// @Autowired
|
||||
// private SentinelZuulProperties zuulProperties;
|
||||
//
|
||||
// @PostConstruct
|
||||
// private void init() {
|
||||
// requestOriginParserOptional
|
||||
// .ifPresent(ZuulGatewayCallbackManager::setOriginParser);
|
||||
// System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY,
|
||||
// String.valueOf(ConfigConstants.APP_TYPE_ZUUL_GATEWAY));
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// @ConditionalOnMissingBean
|
||||
// public SentinelZuulPreFilter sentinelZuulPreFilter() {
|
||||
// logger.info("[Sentinel Zuul] register SentinelZuulPreFilter {}",
|
||||
// zuulProperties.getOrder().getPre());
|
||||
// return new SentinelZuulPreFilter(zuulProperties.getOrder().getPre());
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// @ConditionalOnMissingBean
|
||||
// public SentinelZuulPostFilter sentinelZuulPostFilter() {
|
||||
// logger.info("[Sentinel Zuul] register SentinelZuulPostFilter {}",
|
||||
// zuulProperties.getOrder().getPost());
|
||||
// return new SentinelZuulPostFilter(zuulProperties.getOrder().getPost());
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// @ConditionalOnMissingBean
|
||||
// public SentinelZuulErrorFilter sentinelZuulErrorFilter() {
|
||||
// logger.info("[Sentinel Zuul] register SentinelZuulErrorFilter {}",
|
||||
// zuulProperties.getOrder().getError());
|
||||
// return new SentinelZuulErrorFilter(zuulProperties.getOrder().getError());
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public FallBackProviderHandler fallBackProviderHandler(
|
||||
// DefaultListableBeanFactory beanFactory) {
|
||||
// return new FallBackProviderHandler(beanFactory);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -1,5 +1,4 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.sentinel.gateway.zuul.SentinelZuulAutoConfiguration,\
|
||||
com.alibaba.cloud.sentinel.gateway.scg.SentinelSCGAutoConfiguration,\
|
||||
com.alibaba.cloud.sentinel.gateway.SentinelGatewayAutoConfiguration
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=com.alibaba.cloud.sentinel.gateway.GatewayEnvironmentPostProcessor
|
@ -62,6 +62,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,31 +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.ribbon;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@ConditionalOnProperty(value = "ribbon.nacos.enabled", matchIfMissing = true)
|
||||
public @interface ConditionalOnRibbonNacos {
|
||||
|
||||
}
|
@ -1,38 +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.ribbon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.client.naming.core.Balancer;
|
||||
|
||||
/**
|
||||
* @author itmuch.com
|
||||
*/
|
||||
public class ExtendBalancer extends Balancer {
|
||||
|
||||
/**
|
||||
* Choose instance by weight.
|
||||
* @param instances Instance List
|
||||
* @return the chosen instance
|
||||
*/
|
||||
public static Instance getHostByRandomWeight2(List<Instance> instances) {
|
||||
return getHostByRandomWeight(instances);
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +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.ribbon;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.netflix.ribbon.PropertiesFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* integrated Ribbon by default.
|
||||
*
|
||||
* @author xiaojing
|
||||
* @author liujunjie
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnRibbonNacos
|
||||
public class NacosRibbonClientConfiguration {
|
||||
|
||||
@Autowired
|
||||
private PropertiesFactory propertiesFactory;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(IClientConfig config,
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties) {
|
||||
if (this.propertiesFactory.isSet(ServerList.class, config.getClientName())) {
|
||||
ServerList serverList = this.propertiesFactory.get(ServerList.class, config,
|
||||
config.getClientName());
|
||||
return serverList;
|
||||
}
|
||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||
serverList.initWithNiwsConfig(config);
|
||||
return serverList;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public NacosServerIntrospector nacosServerIntrospector() {
|
||||
return new NacosServerIntrospector();
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +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.ribbon;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.nacos.NacosServiceManager;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
|
||||
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Supports preferentially calling the ribbon load balancing rules of the same cluster
|
||||
* instance.
|
||||
*
|
||||
* @author itmuch.com
|
||||
*/
|
||||
public class NacosRule extends AbstractLoadBalancerRule {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NacosRule.class);
|
||||
|
||||
@Autowired
|
||||
private NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
|
||||
@Autowired
|
||||
private NacosServiceManager nacosServiceManager;
|
||||
|
||||
@Override
|
||||
public Server choose(Object key) {
|
||||
try {
|
||||
String clusterName = this.nacosDiscoveryProperties.getClusterName();
|
||||
String group = this.nacosDiscoveryProperties.getGroup();
|
||||
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
|
||||
String name = loadBalancer.getName();
|
||||
|
||||
NamingService namingService = nacosServiceManager
|
||||
.getNamingService(nacosDiscoveryProperties.getNacosProperties());
|
||||
List<Instance> instances = namingService.selectInstances(name, group, true);
|
||||
if (CollectionUtils.isEmpty(instances)) {
|
||||
LOGGER.warn("no instance in service {}", name);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Instance> instancesToChoose = instances;
|
||||
if (StringUtils.isNotBlank(clusterName)) {
|
||||
List<Instance> sameClusterInstances = instances.stream()
|
||||
.filter(instance -> Objects.equals(clusterName,
|
||||
instance.getClusterName()))
|
||||
.collect(Collectors.toList());
|
||||
if (!CollectionUtils.isEmpty(sameClusterInstances)) {
|
||||
instancesToChoose = sameClusterInstances;
|
||||
}
|
||||
else {
|
||||
LOGGER.warn(
|
||||
"A cross-cluster call occurs,name = {}, clusterName = {}, instance = {}",
|
||||
name, clusterName, instances);
|
||||
}
|
||||
}
|
||||
|
||||
Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose);
|
||||
|
||||
return new NacosServer(instance);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.warn("NacosRule error", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig iClientConfig) {
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +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.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author pbting
|
||||
*/
|
||||
public class NacosServer extends Server {
|
||||
|
||||
private final MetaInfo metaInfo;
|
||||
|
||||
private final Instance instance;
|
||||
|
||||
private final Map<String, String> metadata;
|
||||
|
||||
public NacosServer(final Instance instance) {
|
||||
super(instance.getIp(), instance.getPort());
|
||||
this.instance = instance;
|
||||
this.metaInfo = new MetaInfo() {
|
||||
@Override
|
||||
public String getAppName() {
|
||||
return instance.getServiceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerGroup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceIdForDiscovery() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return instance.getInstanceId();
|
||||
}
|
||||
};
|
||||
this.metadata = instance.getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaInfo getMetaInfo() {
|
||||
return metaInfo;
|
||||
}
|
||||
|
||||
public Instance getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Map<String, String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +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.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
public class NacosServerIntrospector extends DefaultServerIntrospector {
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetadata(Server server) {
|
||||
if (server instanceof NacosServer) {
|
||||
return ((NacosServer) server).getMetadata();
|
||||
}
|
||||
return super.getMetadata(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure(Server server) {
|
||||
if (server instanceof NacosServer) {
|
||||
return Boolean.valueOf(((NacosServer) server).getMetadata().get("secure"));
|
||||
}
|
||||
|
||||
return super.isSecure(server);
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +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.ribbon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author renhaojun
|
||||
*/
|
||||
public class NacosServerList extends AbstractServerList<NacosServer> {
|
||||
|
||||
private NacosDiscoveryProperties discoveryProperties;
|
||||
|
||||
private String serviceId;
|
||||
|
||||
public NacosServerList(NacosDiscoveryProperties discoveryProperties) {
|
||||
this.discoveryProperties = discoveryProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NacosServer> getInitialListOfServers() {
|
||||
return getServers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NacosServer> getUpdatedListOfServers() {
|
||||
return getServers();
|
||||
}
|
||||
|
||||
private List<NacosServer> getServers() {
|
||||
try {
|
||||
String group = discoveryProperties.getGroup();
|
||||
List<Instance> instances = discoveryProperties.namingServiceInstance()
|
||||
.selectInstances(serviceId, group, true);
|
||||
return instancesToServerList(instances);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Can not get service instances from nacos, serviceId=" + serviceId,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<NacosServer> instancesToServerList(List<Instance> instances) {
|
||||
List<NacosServer> result = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(instances)) {
|
||||
return result;
|
||||
}
|
||||
for (Instance instance : instances) {
|
||||
result.add(new NacosServer(instance));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig iClientConfig) {
|
||||
this.serviceId = iClientConfig.getClientName();
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +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.ribbon;
|
||||
|
||||
import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
* Auto-configuration} that sets up Ribbon for Nacos.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnBean(SpringClientFactory.class)
|
||||
@ConditionalOnRibbonNacos
|
||||
@ConditionalOnNacosDiscoveryEnabled
|
||||
@AutoConfigureAfter(RibbonAutoConfiguration.class)
|
||||
@RibbonClients(defaultConfiguration = NacosRibbonClientConfiguration.class)
|
||||
public class RibbonNacosAutoConfiguration {
|
||||
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
|
||||
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
|
||||
|
@ -1,78 +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.ribbon;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration;
|
||||
import com.netflix.client.config.DefaultClientConfigImpl;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
public class NacosRibbonClientConfigurationTests {
|
||||
|
||||
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(NacosRibbonTestConfiguration.class,
|
||||
NacosRibbonClientConfiguration.class,
|
||||
NacosDiscoveryClientConfiguration.class,
|
||||
RibbonNacosAutoConfiguration.class))
|
||||
.withPropertyValues("spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848")
|
||||
.withPropertyValues("spring.cloud.nacos.discovery.port=18080")
|
||||
.withPropertyValues("spring.cloud.nacos.discovery.service=myapp");
|
||||
|
||||
@Test
|
||||
public void testProperties() {
|
||||
|
||||
this.contextRunner.run(context -> {
|
||||
NacosServerList serverList = context.getBean(NacosServerList.class);
|
||||
assertThat(serverList.getServiceId()).isEqualTo("myapp");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableDiscoveryClient
|
||||
static class NacosRibbonTestConfiguration {
|
||||
|
||||
@Bean
|
||||
IClientConfig iClientConfig() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.setClientName("myapp");
|
||||
return config;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.ribbon;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration;
|
||||
import com.netflix.loadbalancer.ConfigurationBasedServerList;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
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.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author liujunjie
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = NacosRibbonClientPropertyOverrideTests.TestConfiguration.class,
|
||||
properties = { "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848",
|
||||
"spring.cloud.nacos.discovery.port=18080",
|
||||
"spring.cloud.nacos.discovery.service=remoteApp",
|
||||
"localApp.ribbon.NIWSServerListClassName="
|
||||
+ "com.netflix.loadbalancer.ConfigurationBasedServerList",
|
||||
"localApp.ribbon.listOfServers=127.0.0.1:19090",
|
||||
"localApp.ribbon.ServerListRefreshInterval=15000" })
|
||||
public class NacosRibbonClientPropertyOverrideTests {
|
||||
|
||||
@Autowired
|
||||
private SpringClientFactory factory;
|
||||
|
||||
@Test
|
||||
public void serverListOverridesToTest() {
|
||||
ConfigurationBasedServerList.class
|
||||
.cast(getLoadBalancer("localApp").getServerListImpl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serverListRemoteTest() {
|
||||
NacosServerList.class.cast(getLoadBalancer("remoteApp").getServerListImpl());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ZoneAwareLoadBalancer<Server> getLoadBalancer(String name) {
|
||||
return (ZoneAwareLoadBalancer<Server>) this.factory.getLoadBalancer(name);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@RibbonClients
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration({ UtilAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
|
||||
RibbonNacosAutoConfiguration.class, NacosDiscoveryClientConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,165 +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.ribbon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.nacos.test.NacosMockTest;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
|
||||
public class NacosServerListTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testEmptyInstancesReturnsEmptyList() throws Exception {
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties = mock(
|
||||
NacosDiscoveryProperties.class);
|
||||
|
||||
NamingService namingService = mock(NamingService.class);
|
||||
|
||||
when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService);
|
||||
when(namingService.selectInstances(anyString(), eq("DEFAULT"), eq(true)))
|
||||
.thenReturn(null);
|
||||
|
||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||
List<NacosServer> servers = serverList.getInitialListOfServers();
|
||||
assertThat(servers).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetServers() throws Exception {
|
||||
|
||||
ArrayList<Instance> instances = new ArrayList<>();
|
||||
instances.add(NacosMockTest.serviceInstance("test-service", false,
|
||||
Collections.emptyMap()));
|
||||
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties = mock(
|
||||
NacosDiscoveryProperties.class);
|
||||
|
||||
NamingService namingService = mock(NamingService.class);
|
||||
|
||||
when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService);
|
||||
when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT");
|
||||
when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT");
|
||||
when(namingService.selectInstances(eq("test-service"), eq("DEFAULT"), eq(true)))
|
||||
.thenReturn(instances);
|
||||
|
||||
IClientConfig clientConfig = mock(IClientConfig.class);
|
||||
when(clientConfig.getClientName()).thenReturn("test-service");
|
||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||
serverList.initWithNiwsConfig(clientConfig);
|
||||
List<NacosServer> servers = serverList.getInitialListOfServers();
|
||||
assertThat(servers).hasSize(1);
|
||||
|
||||
servers = serverList.getUpdatedListOfServers();
|
||||
assertThat(servers).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetServersWithInstanceStatus() throws Exception {
|
||||
ArrayList<Instance> instances = new ArrayList<>();
|
||||
|
||||
HashMap<String, String> map1 = new HashMap<>();
|
||||
map1.put("instanceNum", "1");
|
||||
HashMap<String, String> map2 = new HashMap<>();
|
||||
map2.put("instanceNum", "2");
|
||||
instances.add(NacosMockTest.serviceInstance("test-service", false, map1));
|
||||
instances.add(NacosMockTest.serviceInstance("test-service", true, map2));
|
||||
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties = mock(
|
||||
NacosDiscoveryProperties.class);
|
||||
|
||||
NamingService namingService = mock(NamingService.class);
|
||||
|
||||
when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService);
|
||||
when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT");
|
||||
when(namingService.selectInstances(eq("test-service"), eq("DEFAULT"), eq(true)))
|
||||
.thenReturn(instances.stream().filter(Instance::isHealthy)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
IClientConfig clientConfig = mock(IClientConfig.class);
|
||||
when(clientConfig.getClientName()).thenReturn("test-service");
|
||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||
serverList.initWithNiwsConfig(clientConfig);
|
||||
List<NacosServer> servers = serverList.getInitialListOfServers();
|
||||
assertThat(servers).hasSize(1);
|
||||
|
||||
NacosServer nacosServer = servers.get(0);
|
||||
|
||||
assertThat(nacosServer.getMetaInfo().getInstanceId())
|
||||
.isEqualTo(instances.get(1).getInstanceId());
|
||||
assertThat(nacosServer.getMetadata()).isEqualTo(map2);
|
||||
assertThat(nacosServer.getInstance().isHealthy()).isEqualTo(true);
|
||||
assertThat(nacosServer.getInstance().getServiceName()).isEqualTo("test-service");
|
||||
assertThat(nacosServer.getInstance().getMetadata().get("instanceNum"))
|
||||
.isEqualTo("2");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateServers() throws Exception {
|
||||
ArrayList<Instance> instances = new ArrayList<>();
|
||||
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("instanceNum", "1");
|
||||
instances.add(NacosMockTest.serviceInstance("test-service", true, map));
|
||||
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties = mock(
|
||||
NacosDiscoveryProperties.class);
|
||||
|
||||
NamingService namingService = mock(NamingService.class);
|
||||
|
||||
when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService);
|
||||
when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT");
|
||||
when(namingService.selectInstances(eq("test-service"), eq("DEFAULT"), eq(true)))
|
||||
.thenReturn(instances.stream().filter(Instance::isHealthy)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
IClientConfig clientConfig = mock(IClientConfig.class);
|
||||
when(clientConfig.getClientName()).thenReturn("test-service");
|
||||
NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
|
||||
serverList.initWithNiwsConfig(clientConfig);
|
||||
|
||||
List<NacosServer> servers = serverList.getUpdatedListOfServers();
|
||||
assertThat(servers).hasSize(1);
|
||||
|
||||
assertThat(servers.get(0).getInstance().isHealthy()).isEqualTo(true);
|
||||
assertThat(servers.get(0).getInstance().getMetadata().get("instanceNum"))
|
||||
.isEqualTo("1");
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,9 @@ import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
|
||||
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
|
||||
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
|
||||
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
|
||||
|
||||
/**
|
||||
@ -32,9 +34,11 @@ public class SeataFeignBlockingLoadBalancerClient
|
||||
extends FeignBlockingLoadBalancerClient {
|
||||
|
||||
public SeataFeignBlockingLoadBalancerClient(Client delegate,
|
||||
BlockingLoadBalancerClient loadBalancerClient,
|
||||
SeataFeignObjectWrapper seataFeignObjectWrapper) {
|
||||
super((Client) seataFeignObjectWrapper.wrap(delegate), loadBalancerClient);
|
||||
BlockingLoadBalancerClient loadBalancerClient,
|
||||
LoadBalancerProperties properties,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
SeataFeignObjectWrapper seataFeignObjectWrapper) {
|
||||
super((Client) seataFeignObjectWrapper.wrap(delegate), loadBalancerClient, properties, loadBalancerClientFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,13 +38,13 @@ import org.springframework.context.annotation.Scope;
|
||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
public class SeataFeignClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
@ConditionalOnClass(name = "com.netflix.hystrix.HystrixCommand")
|
||||
@ConditionalOnProperty(name = "feign.hystrix.enabled", havingValue = "true")
|
||||
Feign.Builder feignHystrixBuilder(BeanFactory beanFactory) {
|
||||
return SeataHystrixFeignBuilder.builder(beanFactory);
|
||||
}
|
||||
// @Bean
|
||||
// @Scope("prototype")
|
||||
// @ConditionalOnClass(name = "com.netflix.hystrix.HystrixCommand")
|
||||
// @ConditionalOnProperty(name = "feign.hystrix.enabled", havingValue = "true")
|
||||
// Feign.Builder feignHystrixBuilder(BeanFactory beanFactory) {
|
||||
// return SeataHystrixFeignBuilder.builder(beanFactory);
|
||||
// }
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
|
@ -21,11 +21,13 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
|
||||
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
|
||||
//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;
|
||||
//import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
//import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
@ -37,9 +39,9 @@ public class SeataFeignObjectWrapper {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
private CachingSpringLoadBalancerFactory cachingSpringLoadBalancerFactory;
|
||||
// private CachingSpringLoadBalancerFactory cachingSpringLoadBalancerFactory;
|
||||
|
||||
private SpringClientFactory springClientFactory;
|
||||
// private SpringClientFactory springClientFactory;
|
||||
|
||||
SeataFeignObjectWrapper(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
@ -47,35 +49,38 @@ public class SeataFeignObjectWrapper {
|
||||
|
||||
Object wrap(Object bean) {
|
||||
if (bean instanceof Client && !(bean instanceof SeataFeignClient)) {
|
||||
if (bean instanceof LoadBalancerFeignClient) {
|
||||
LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean);
|
||||
return new SeataLoadBalancerFeignClient(client.getDelegate(), factory(),
|
||||
clientFactory(), this);
|
||||
}
|
||||
// if (bean instanceof LoadBalancerFeignClient) {
|
||||
// LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean);
|
||||
// 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);
|
||||
beanFactory.getBean(BlockingLoadBalancerClient.class),
|
||||
beanFactory.getBean(LoadBalancerProperties.class),
|
||||
beanFactory.getBean(LoadBalancerClientFactory.class),
|
||||
this);
|
||||
}
|
||||
return new SeataFeignClient(this.beanFactory, (Client) bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
CachingSpringLoadBalancerFactory factory() {
|
||||
if (this.cachingSpringLoadBalancerFactory == null) {
|
||||
this.cachingSpringLoadBalancerFactory = this.beanFactory
|
||||
.getBean(CachingSpringLoadBalancerFactory.class);
|
||||
}
|
||||
return this.cachingSpringLoadBalancerFactory;
|
||||
}
|
||||
// CachingSpringLoadBalancerFactory factory() {
|
||||
// if (this.cachingSpringLoadBalancerFactory == null) {
|
||||
// this.cachingSpringLoadBalancerFactory = this.beanFactory
|
||||
// .getBean(CachingSpringLoadBalancerFactory.class);
|
||||
// }
|
||||
// return this.cachingSpringLoadBalancerFactory;
|
||||
// }
|
||||
|
||||
SpringClientFactory clientFactory() {
|
||||
if (this.springClientFactory == null) {
|
||||
this.springClientFactory = this.beanFactory
|
||||
.getBean(SpringClientFactory.class);
|
||||
}
|
||||
return this.springClientFactory;
|
||||
}
|
||||
// SpringClientFactory clientFactory() {
|
||||
// if (this.springClientFactory == null) {
|
||||
// this.springClientFactory = this.beanFactory
|
||||
// .getBean(SpringClientFactory.class);
|
||||
// }
|
||||
// return this.springClientFactory;
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
/*
|
||||
* 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 feign.Feign;
|
||||
import feign.Retryer;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
final class SeataHystrixFeignBuilder {
|
||||
|
||||
private SeataHystrixFeignBuilder() {
|
||||
}
|
||||
|
||||
static Feign.Builder builder(BeanFactory beanFactory) {
|
||||
return HystrixFeign.builder().retryer(Retryer.NEVER_RETRY)
|
||||
.client(new SeataFeignClient(beanFactory));
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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 feign.Feign;
|
||||
//import feign.Retryer;
|
||||
//import feign.hystrix.HystrixFeign;
|
||||
//
|
||||
//import org.springframework.beans.factory.BeanFactory;
|
||||
//
|
||||
///**
|
||||
// * @author xiaojing
|
||||
// */
|
||||
//final class SeataHystrixFeignBuilder {
|
||||
//
|
||||
// private SeataHystrixFeignBuilder() {
|
||||
// }
|
||||
//
|
||||
// static Feign.Builder builder(BeanFactory beanFactory) {
|
||||
// return HystrixFeign.builder().retryer(Retryer.NEVER_RETRY)
|
||||
// .client(new SeataFeignClient(beanFactory));
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -1,48 +1,45 @@
|
||||
/*
|
||||
* 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.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
* @author yuhuangbin
|
||||
*/
|
||||
public class SeataLoadBalancerFeignClient extends LoadBalancerFeignClient {
|
||||
|
||||
SeataLoadBalancerFeignClient(Client delegate,
|
||||
CachingSpringLoadBalancerFactory lbClientFactory,
|
||||
SpringClientFactory clientFactory,
|
||||
SeataFeignObjectWrapper seataFeignObjectWrapper) {
|
||||
super((Client) seataFeignObjectWrapper.wrap(delegate), lbClientFactory,
|
||||
clientFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
return super.execute(request, options);
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * @author xiaojing
|
||||
// * @author yuhuangbin
|
||||
// */
|
||||
//public class SeataLoadBalancerFeignClient extends LoadBalancerFeignClient {
|
||||
//
|
||||
// SeataLoadBalancerFeignClient(Client delegate,
|
||||
// CachingSpringLoadBalancerFactory lbClientFactory,
|
||||
// SpringClientFactory clientFactory,
|
||||
// SeataFeignObjectWrapper seataFeignObjectWrapper) {
|
||||
// super((Client) seataFeignObjectWrapper.wrap(delegate), lbClientFactory,
|
||||
// clientFactory);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Response execute(Request request, Request.Options options) throws IOException {
|
||||
// return super.execute(request, options);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -1,37 +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.hystrix;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(HystrixCommand.class)
|
||||
public class SeataHystrixAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
SeataHystrixConcurrencyStrategy seataHystrixConcurrencyStrategy() {
|
||||
return new SeataHystrixConcurrencyStrategy();
|
||||
}
|
||||
|
||||
}
|
@ -1,175 +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.hystrix;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.netflix.hystrix.HystrixThreadPoolKey;
|
||||
import com.netflix.hystrix.HystrixThreadPoolProperties;
|
||||
import com.netflix.hystrix.strategy.HystrixPlugins;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
|
||||
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
|
||||
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
|
||||
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
|
||||
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
|
||||
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
|
||||
import com.netflix.hystrix.strategy.properties.HystrixProperty;
|
||||
import io.seata.core.context.RootContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* @author xiaojing
|
||||
*/
|
||||
public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
|
||||
|
||||
private final Logger logger = LoggerFactory
|
||||
.getLogger(SeataHystrixConcurrencyStrategy.class);
|
||||
|
||||
private HystrixConcurrencyStrategy delegate;
|
||||
|
||||
public SeataHystrixConcurrencyStrategy() {
|
||||
try {
|
||||
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
|
||||
if (this.delegate instanceof SeataHystrixConcurrencyStrategy) {
|
||||
return;
|
||||
}
|
||||
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins
|
||||
.getInstance().getCommandExecutionHook();
|
||||
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
|
||||
.getEventNotifier();
|
||||
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
|
||||
.getMetricsPublisher();
|
||||
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
|
||||
.getPropertiesStrategy();
|
||||
logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher,
|
||||
propertiesStrategy);
|
||||
HystrixPlugins.reset();
|
||||
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
|
||||
HystrixPlugins.getInstance()
|
||||
.registerCommandExecutionHook(commandExecutionHook);
|
||||
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
|
||||
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
|
||||
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("Failed to register Seata Hystrix Concurrency Strategy", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
|
||||
HystrixMetricsPublisher metricsPublisher,
|
||||
HystrixPropertiesStrategy propertiesStrategy) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Current Hystrix plugins configuration is ["
|
||||
+ "concurrencyStrategy [" + this.delegate + "]," + "eventNotifier ["
|
||||
+ eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "],"
|
||||
+ "propertiesStrategy [" + propertiesStrategy + "]," + "]");
|
||||
logger.debug("Registering Seata Hystrix Concurrency Strategy.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
|
||||
HystrixProperty<Integer> corePoolSize,
|
||||
HystrixProperty<Integer> maximumPoolSize,
|
||||
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
|
||||
BlockingQueue<Runnable> workQueue) {
|
||||
return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
|
||||
keepAliveTime, unit, workQueue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
|
||||
HystrixThreadPoolProperties threadPoolProperties) {
|
||||
return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
|
||||
return this.delegate.getBlockingQueue(maxQueueSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> HystrixRequestVariable<T> getRequestVariable(
|
||||
HystrixRequestVariableLifecycle<T> rv) {
|
||||
return this.delegate.getRequestVariable(rv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K> Callable<K> wrapCallable(Callable<K> c) {
|
||||
if (c instanceof SeataContextCallable) {
|
||||
return c;
|
||||
}
|
||||
|
||||
Callable<K> wrappedCallable;
|
||||
if (this.delegate != null) {
|
||||
wrappedCallable = this.delegate.wrapCallable(c);
|
||||
}
|
||||
else {
|
||||
wrappedCallable = c;
|
||||
}
|
||||
if (wrappedCallable instanceof SeataContextCallable) {
|
||||
return wrappedCallable;
|
||||
}
|
||||
|
||||
return new SeataContextCallable<>(wrappedCallable,
|
||||
RequestContextHolder.getRequestAttributes());
|
||||
}
|
||||
|
||||
private static class SeataContextCallable<K> implements Callable<K> {
|
||||
|
||||
private final Callable<K> actual;
|
||||
|
||||
private final String xid;
|
||||
|
||||
private final RequestAttributes requestAttributes;
|
||||
|
||||
SeataContextCallable(Callable<K> actual, RequestAttributes requestAttribute) {
|
||||
this.actual = actual;
|
||||
this.requestAttributes = requestAttribute;
|
||||
this.xid = RootContext.getXID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public K call() throws Exception {
|
||||
try {
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||
if (!StringUtils.isEmpty(xid)) {
|
||||
RootContext.bind(xid);
|
||||
}
|
||||
return actual.call();
|
||||
}
|
||||
finally {
|
||||
if (!StringUtils.isEmpty(xid)) {
|
||||
RootContext.unbind();
|
||||
}
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.seata.rest.SeataRestTemplateAutoConfiguration,\
|
||||
com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration,\
|
||||
com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration,\
|
||||
com.alibaba.cloud.seata.feign.hystrix.SeataHystrixAutoConfiguration
|
||||
com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration
|
||||
|
||||
|
@ -75,6 +75,12 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
@ -156,6 +162,12 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -25,8 +25,8 @@ import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.InvocationHandlerFactory;
|
||||
import feign.Target;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
//import feign.hystrix.FallbackFactory;
|
||||
//import feign.hystrix.HystrixFeign;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.cloud.openfeign.FeignContext;
|
||||
@ -80,35 +80,35 @@ public final class SentinelFeign {
|
||||
// using reflect get fallback and fallbackFactory properties from
|
||||
// FeignClientFactoryBean because FeignClientFactoryBean is a package
|
||||
// level class, we can not use it in our package
|
||||
Object feignClientFactoryBean = Builder.this.applicationContext
|
||||
.getBean("&" + target.type().getName());
|
||||
|
||||
Class fallback = (Class) getFieldValue(feignClientFactoryBean,
|
||||
"fallback");
|
||||
Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean,
|
||||
"fallbackFactory");
|
||||
String beanName = (String) getFieldValue(feignClientFactoryBean,
|
||||
"contextId");
|
||||
if (!StringUtils.hasText(beanName)) {
|
||||
beanName = (String) getFieldValue(feignClientFactoryBean, "name");
|
||||
}
|
||||
|
||||
Object fallbackInstance;
|
||||
FallbackFactory fallbackFactoryInstance;
|
||||
// check fallback and fallbackFactory properties
|
||||
if (void.class != fallback) {
|
||||
fallbackInstance = getFromContext(beanName, "fallback", fallback,
|
||||
target.type());
|
||||
return new SentinelInvocationHandler(target, dispatch,
|
||||
new FallbackFactory.Default(fallbackInstance));
|
||||
}
|
||||
if (void.class != fallbackFactory) {
|
||||
fallbackFactoryInstance = (FallbackFactory) getFromContext(
|
||||
beanName, "fallbackFactory", fallbackFactory,
|
||||
FallbackFactory.class);
|
||||
return new SentinelInvocationHandler(target, dispatch,
|
||||
fallbackFactoryInstance);
|
||||
}
|
||||
// Object feignClientFactoryBean = Builder.this.applicationContext
|
||||
// .getBean("&" + target.type().getName());
|
||||
//
|
||||
// Class fallback = (Class) getFieldValue(feignClientFactoryBean,
|
||||
// "fallback");
|
||||
// Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean,
|
||||
// "fallbackFactory");
|
||||
// String beanName = (String) getFieldValue(feignClientFactoryBean,
|
||||
// "contextId");
|
||||
// if (!StringUtils.hasText(beanName)) {
|
||||
// beanName = (String) getFieldValue(feignClientFactoryBean, "name");
|
||||
// }
|
||||
//
|
||||
// Object fallbackInstance;
|
||||
// FallbackFactory fallbackFactoryInstance;
|
||||
// // check fallback and fallbackFactory properties
|
||||
// if (void.class != fallback) {
|
||||
// fallbackInstance = getFromContext(beanName, "fallback", fallback,
|
||||
// target.type());
|
||||
// return new SentinelInvocationHandler(target, dispatch,
|
||||
// new FallbackFactory.Default(fallbackInstance));
|
||||
// }
|
||||
// if (void.class != fallbackFactory) {
|
||||
// fallbackFactoryInstance = (FallbackFactory) getFromContext(
|
||||
// beanName, "fallbackFactory", fallbackFactory,
|
||||
// FallbackFactory.class);
|
||||
// return new SentinelInvocationHandler(target, dispatch,
|
||||
// fallbackFactoryInstance);
|
||||
// }
|
||||
return new SentinelInvocationHandler(target, dispatch);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ import feign.Feign;
|
||||
import feign.InvocationHandlerFactory.MethodHandler;
|
||||
import feign.MethodMetadata;
|
||||
import feign.Target;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
|
||||
import static feign.Util.checkNotNull;
|
||||
|
||||
@ -48,18 +47,8 @@ public class SentinelInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final Map<Method, MethodHandler> dispatch;
|
||||
|
||||
private FallbackFactory fallbackFactory;
|
||||
|
||||
private Map<Method, Method> fallbackMethodMap;
|
||||
|
||||
SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch,
|
||||
FallbackFactory fallbackFactory) {
|
||||
this.target = checkNotNull(target, "target");
|
||||
this.dispatch = checkNotNull(dispatch, "dispatch");
|
||||
this.fallbackFactory = fallbackFactory;
|
||||
this.fallbackMethodMap = toFallbackMethod(dispatch);
|
||||
}
|
||||
|
||||
SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch) {
|
||||
this.target = checkNotNull(target, "target");
|
||||
this.dispatch = checkNotNull(dispatch, "dispatch");
|
||||
@ -111,25 +100,8 @@ public class SentinelInvocationHandler implements InvocationHandler {
|
||||
if (!BlockException.isBlockException(ex)) {
|
||||
Tracer.trace(ex);
|
||||
}
|
||||
if (fallbackFactory != null) {
|
||||
try {
|
||||
Object fallbackResult = fallbackMethodMap.get(method)
|
||||
.invoke(fallbackFactory.create(ex), args);
|
||||
return fallbackResult;
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
// shouldn't happen as method is public due to being an
|
||||
// interface
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new AssertionError(e.getCause());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// throw exception if fallbackFactory is null
|
||||
throw ex;
|
||||
}
|
||||
// throw exception if fallbackFactory is null
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
if (entry != null) {
|
||||
|
@ -25,6 +25,7 @@ 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.FallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -122,7 +123,7 @@ public class ContextIdSentinelFeignTests {
|
||||
}
|
||||
|
||||
public static class CustomFallbackFactory
|
||||
implements feign.hystrix.FallbackFactory<FooService> {
|
||||
implements FallbackFactory<FooService> {
|
||||
|
||||
private FooService fooService = new FooServiceFallback();
|
||||
|
||||
|
@ -31,6 +31,7 @@ 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.FallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -191,7 +192,7 @@ public class SentinelFeignTests {
|
||||
}
|
||||
|
||||
public static class CustomFallbackFactory
|
||||
implements feign.hystrix.FallbackFactory<FooService> {
|
||||
implements FallbackFactory<FooService> {
|
||||
|
||||
private FooService fooService = new FooServiceFallback();
|
||||
|
||||
|
@ -59,7 +59,7 @@ public class SidecarConsulAutoRegistration extends ConsulAutoRegistration {
|
||||
service.setAddress(sidecarProperties.getIp());
|
||||
}
|
||||
service.setName(normalizeForDns(appName));
|
||||
service.setTags(createTags(properties));
|
||||
service.setTags(properties.getTags());
|
||||
|
||||
// set health check, use alibaba sidecar self's port rather than polyglot app's
|
||||
// port.
|
||||
|
@ -37,7 +37,7 @@ public class SidecarNacosDiscoveryProperties extends NacosDiscoveryProperties {
|
||||
super.init();
|
||||
|
||||
String ip = sidecarProperties.getIp();
|
||||
if (!StringUtils.isEmpty(ip)) {
|
||||
if (!StringUtils.hasText(ip)) {
|
||||
this.setIp(ip);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static org.springframework.cloud.bus.SpringCloudBusClient.INPUT;
|
||||
import static org.springframework.cloud.bus.BusConstants.INPUT;
|
||||
|
||||
/**
|
||||
* The lowest precedence {@link EnvironmentPostProcessor} configures default RocketMQ Bus
|
||||
|
@ -58,6 +58,13 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -131,7 +131,7 @@ public class RocketMQMessageHandler extends AbstractMessageHandler implements Li
|
||||
}
|
||||
}
|
||||
catch (MQClientException e) {
|
||||
logger.error("fetch publish message queues fail", e);
|
||||
logger.error(e, "fetch publish message queues fail");
|
||||
}
|
||||
}
|
||||
running = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user