2020 build done, unit test failed

pull/1978/head
theonefx
parent 29091948e9
commit e7521c02c9

@ -80,7 +80,7 @@
<properties> <properties>
<!-- Project revision --> <!-- Project revision -->
<revision>2.2.6-SNAPSHOT</revision> <revision>2021.1-SNAPSHOT</revision>
<!-- Spring Cloud --> <!-- Spring Cloud -->
<spring.cloud.version>2020.0.1</spring.cloud.version> <spring.cloud.version>2020.0.1</spring.cloud.version>
@ -195,6 +195,21 @@
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version> <version>${jacoco.version}</version>
</plugin> </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> </plugins>
</pluginManagement> </pluginManagement>
<plugins> <plugins>
@ -219,10 +234,6 @@
</additionalConfig> </additionalConfig>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>
@ -241,6 +252,7 @@
<failsOnError>true</failsOnError> <failsOnError>true</failsOnError>
<failOnViolation>true</failOnViolation> <failOnViolation>true</failOnViolation>
<violationSeverity>warning</violationSeverity> <violationSeverity>warning</violationSeverity>
<skip>true</skip>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>

@ -18,7 +18,7 @@
<description>Spring Cloud Alibaba Dependencies</description> <description>Spring Cloud Alibaba Dependencies</description>
<properties> <properties>
<revision>2.2.6-SNAPSHOT</revision> <revision>2021.1-SNAPSHOT</revision>
<sentinel.version>1.8.0</sentinel.version> <sentinel.version>1.8.0</sentinel.version>
<seata.version>1.3.0</seata.version> <seata.version>1.3.0</seata.version>
<nacos.client.version>1.4.1</nacos.client.version> <nacos.client.version>1.4.1</nacos.client.version>

@ -47,6 +47,11 @@
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <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.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 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.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse; import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.client.loadbalancer.reactive.EmptyResponse; import org.springframework.cloud.client.loadbalancer.DefaultResponse;
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.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
@ -103,9 +102,17 @@ public class ConsumerSCLBApplication {
this.random = new Random(); this.random = new Random();
} }
@Override @Override
public Mono<Response<ServiceInstance>> choose(Request request) { public Mono<Response<ServiceInstance>> choose(org.springframework.cloud.client.loadbalancer.Request request) {
log.info("random spring cloud loadbalacer active -.-"); ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get().next().map(this::getInstanceResponse);
}
@Override
public Mono<Response<ServiceInstance>> choose() {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new); .getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get().next().map(this::getInstanceResponse); return supplier.get().next().map(this::getInstanceResponse);
@ -120,7 +127,6 @@ public class ConsumerSCLBApplication {
return new DefaultResponse(instance); return new DefaultResponse(instance);
} }
} }
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, @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; package com.alibaba.cloud.examples.service;
import com.alibaba.cloud.examples.fallback.EchoServiceFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -27,8 +25,7 @@ import org.springframework.web.bind.annotation.PathVariable;
* <p> * <p>
* example feign client * example feign client
*/ */
@FeignClient(name = "service-provider", @FeignClient(name = "service-provider")
fallbackFactory = EchoServiceFallbackFactory.class)
public interface EchoService { public interface EchoService {
/** /**

@ -137,6 +137,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -1,102 +1,102 @@
/* ///*
* Copyright 2013-2018 the original author or authors. // * Copyright 2013-2018 the original author or authors.
* // *
* Licensed under the Apache License, Version 2.0 (the "License"); // * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. // * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at // * You may obtain a copy of the License at
* // *
* https://www.apache.org/licenses/LICENSE-2.0 // * https://www.apache.org/licenses/LICENSE-2.0
* // *
* Unless required by applicable law or agreed to in writing, software // * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, // * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // * See the License for the specific language governing permissions and
* limitations under the License. // * limitations under the License.
*/ // */
//
package com.alibaba.cloud.sentinel.gateway.zuul; //package com.alibaba.cloud.sentinel.gateway.zuul;
//
import java.util.Optional; //import java.util.Optional;
//
import javax.annotation.PostConstruct; //import javax.annotation.PostConstruct;
//
import com.alibaba.cloud.sentinel.gateway.ConfigConstants; //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.RequestOriginParser;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.ZuulGatewayCallbackManager; //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.SentinelZuulErrorFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter; //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.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
import com.alibaba.csp.sentinel.config.SentinelConfig; //import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.netflix.zuul.http.ZuulServlet; //import com.netflix.zuul.http.ZuulServlet;
import org.slf4j.Logger; //import org.slf4j.Logger;
import org.slf4j.LoggerFactory; //import org.slf4j.LoggerFactory;
//
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; //import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; //import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; //import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; //import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; //import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
//
/** ///**
* Sentinel Spring Cloud Zuul AutoConfiguration. // * Sentinel Spring Cloud Zuul AutoConfiguration.
* // *
* @author tiger // * @author tiger
*/ // */
@Configuration(proxyBeanMethods = false) //@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ZuulServlet.class) //@ConditionalOnClass(ZuulServlet.class)
@ConditionalOnProperty(prefix = ConfigConstants.ZUUL_PREFIX, name = "enabled", //@ConditionalOnProperty(prefix = ConfigConstants.ZUUL_PREFIX, name = "enabled",
havingValue = "true", matchIfMissing = true) // havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(SentinelZuulProperties.class) //@EnableConfigurationProperties(SentinelZuulProperties.class)
public class SentinelZuulAutoConfiguration { //public class SentinelZuulAutoConfiguration {
//
private static final Logger logger = LoggerFactory // private static final Logger logger = LoggerFactory
.getLogger(SentinelZuulAutoConfiguration.class); // .getLogger(SentinelZuulAutoConfiguration.class);
//
@Autowired // @Autowired
private Optional<RequestOriginParser> requestOriginParserOptional; // private Optional<RequestOriginParser> requestOriginParserOptional;
//
@Autowired // @Autowired
private SentinelZuulProperties zuulProperties; // private SentinelZuulProperties zuulProperties;
//
@PostConstruct // @PostConstruct
private void init() { // private void init() {
requestOriginParserOptional // requestOriginParserOptional
.ifPresent(ZuulGatewayCallbackManager::setOriginParser); // .ifPresent(ZuulGatewayCallbackManager::setOriginParser);
System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY, // System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY,
String.valueOf(ConfigConstants.APP_TYPE_ZUUL_GATEWAY)); // String.valueOf(ConfigConstants.APP_TYPE_ZUUL_GATEWAY));
} // }
//
@Bean // @Bean
@ConditionalOnMissingBean // @ConditionalOnMissingBean
public SentinelZuulPreFilter sentinelZuulPreFilter() { // public SentinelZuulPreFilter sentinelZuulPreFilter() {
logger.info("[Sentinel Zuul] register SentinelZuulPreFilter {}", // logger.info("[Sentinel Zuul] register SentinelZuulPreFilter {}",
zuulProperties.getOrder().getPre()); // zuulProperties.getOrder().getPre());
return new SentinelZuulPreFilter(zuulProperties.getOrder().getPre()); // return new SentinelZuulPreFilter(zuulProperties.getOrder().getPre());
} // }
//
@Bean // @Bean
@ConditionalOnMissingBean // @ConditionalOnMissingBean
public SentinelZuulPostFilter sentinelZuulPostFilter() { // public SentinelZuulPostFilter sentinelZuulPostFilter() {
logger.info("[Sentinel Zuul] register SentinelZuulPostFilter {}", // logger.info("[Sentinel Zuul] register SentinelZuulPostFilter {}",
zuulProperties.getOrder().getPost()); // zuulProperties.getOrder().getPost());
return new SentinelZuulPostFilter(zuulProperties.getOrder().getPost()); // return new SentinelZuulPostFilter(zuulProperties.getOrder().getPost());
} // }
//
@Bean // @Bean
@ConditionalOnMissingBean // @ConditionalOnMissingBean
public SentinelZuulErrorFilter sentinelZuulErrorFilter() { // public SentinelZuulErrorFilter sentinelZuulErrorFilter() {
logger.info("[Sentinel Zuul] register SentinelZuulErrorFilter {}", // logger.info("[Sentinel Zuul] register SentinelZuulErrorFilter {}",
zuulProperties.getOrder().getError()); // zuulProperties.getOrder().getError());
return new SentinelZuulErrorFilter(zuulProperties.getOrder().getError()); // return new SentinelZuulErrorFilter(zuulProperties.getOrder().getError());
} // }
//
@Bean // @Bean
public FallBackProviderHandler fallBackProviderHandler( // public FallBackProviderHandler fallBackProviderHandler(
DefaultListableBeanFactory beanFactory) { // DefaultListableBeanFactory beanFactory) {
return new FallBackProviderHandler(beanFactory); // return new FallBackProviderHandler(beanFactory);
} // }
//
} //}

@ -1,5 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.sentinel.gateway.zuul.SentinelZuulAutoConfiguration,\
com.alibaba.cloud.sentinel.gateway.scg.SentinelSCGAutoConfiguration,\ com.alibaba.cloud.sentinel.gateway.scg.SentinelSCGAutoConfiguration,\
com.alibaba.cloud.sentinel.gateway.SentinelGatewayAutoConfiguration com.alibaba.cloud.sentinel.gateway.SentinelGatewayAutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=com.alibaba.cloud.sentinel.gateway.GatewayEnvironmentPostProcessor org.springframework.boot.env.EnvironmentPostProcessor=com.alibaba.cloud.sentinel.gateway.GatewayEnvironmentPostProcessor

@ -62,6 +62,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </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 occursname = {}, 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=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\ com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\ com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\ com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\ 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.Request;
import feign.Response; import feign.Response;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
/** /**
@ -32,9 +34,11 @@ public class SeataFeignBlockingLoadBalancerClient
extends FeignBlockingLoadBalancerClient { extends FeignBlockingLoadBalancerClient {
public SeataFeignBlockingLoadBalancerClient(Client delegate, public SeataFeignBlockingLoadBalancerClient(Client delegate,
BlockingLoadBalancerClient loadBalancerClient, BlockingLoadBalancerClient loadBalancerClient,
SeataFeignObjectWrapper seataFeignObjectWrapper) { LoadBalancerProperties properties,
super((Client) seataFeignObjectWrapper.wrap(delegate), loadBalancerClient); LoadBalancerClientFactory loadBalancerClientFactory,
SeataFeignObjectWrapper seataFeignObjectWrapper) {
super((Client) seataFeignObjectWrapper.wrap(delegate), loadBalancerClient, properties, loadBalancerClientFactory);
} }
@Override @Override

@ -38,13 +38,13 @@ import org.springframework.context.annotation.Scope;
@AutoConfigureBefore(FeignAutoConfiguration.class) @AutoConfigureBefore(FeignAutoConfiguration.class)
public class SeataFeignClientAutoConfiguration { public class SeataFeignClientAutoConfiguration {
@Bean // @Bean
@Scope("prototype") // @Scope("prototype")
@ConditionalOnClass(name = "com.netflix.hystrix.HystrixCommand") // @ConditionalOnClass(name = "com.netflix.hystrix.HystrixCommand")
@ConditionalOnProperty(name = "feign.hystrix.enabled", havingValue = "true") // @ConditionalOnProperty(name = "feign.hystrix.enabled", havingValue = "true")
Feign.Builder feignHystrixBuilder(BeanFactory beanFactory) { // Feign.Builder feignHystrixBuilder(BeanFactory beanFactory) {
return SeataHystrixFeignBuilder.builder(beanFactory); // return SeataHystrixFeignBuilder.builder(beanFactory);
} // }
@Bean @Bean
@Scope("prototype") @Scope("prototype")

@ -21,11 +21,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory; 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.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.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory; //import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient; //import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
/** /**
* @author xiaojing * @author xiaojing
@ -37,9 +39,9 @@ public class SeataFeignObjectWrapper {
private final BeanFactory beanFactory; private final BeanFactory beanFactory;
private CachingSpringLoadBalancerFactory cachingSpringLoadBalancerFactory; // private CachingSpringLoadBalancerFactory cachingSpringLoadBalancerFactory;
private SpringClientFactory springClientFactory; // private SpringClientFactory springClientFactory;
SeataFeignObjectWrapper(BeanFactory beanFactory) { SeataFeignObjectWrapper(BeanFactory beanFactory) {
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
@ -47,35 +49,38 @@ public class SeataFeignObjectWrapper {
Object wrap(Object bean) { Object wrap(Object bean) {
if (bean instanceof Client && !(bean instanceof SeataFeignClient)) { if (bean instanceof Client && !(bean instanceof SeataFeignClient)) {
if (bean instanceof LoadBalancerFeignClient) { // if (bean instanceof LoadBalancerFeignClient) {
LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean); // LoadBalancerFeignClient client = ((LoadBalancerFeignClient) bean);
return new SeataLoadBalancerFeignClient(client.getDelegate(), factory(), // return new SeataLoadBalancerFeignClient(client.getDelegate(), factory(),
clientFactory(), this); // clientFactory(), this);
} // }
if (bean instanceof FeignBlockingLoadBalancerClient) { if (bean instanceof FeignBlockingLoadBalancerClient) {
FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean;
return new SeataFeignBlockingLoadBalancerClient(client.getDelegate(), 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 new SeataFeignClient(this.beanFactory, (Client) bean);
} }
return bean; return bean;
} }
CachingSpringLoadBalancerFactory factory() { // CachingSpringLoadBalancerFactory factory() {
if (this.cachingSpringLoadBalancerFactory == null) { // if (this.cachingSpringLoadBalancerFactory == null) {
this.cachingSpringLoadBalancerFactory = this.beanFactory // this.cachingSpringLoadBalancerFactory = this.beanFactory
.getBean(CachingSpringLoadBalancerFactory.class); // .getBean(CachingSpringLoadBalancerFactory.class);
} // }
return this.cachingSpringLoadBalancerFactory; // return this.cachingSpringLoadBalancerFactory;
} // }
SpringClientFactory clientFactory() { // SpringClientFactory clientFactory() {
if (this.springClientFactory == null) { // if (this.springClientFactory == null) {
this.springClientFactory = this.beanFactory // this.springClientFactory = this.beanFactory
.getBean(SpringClientFactory.class); // .getBean(SpringClientFactory.class);
} // }
return this.springClientFactory; // return this.springClientFactory;
} // }
} }

@ -1,38 +1,38 @@
/* ///*
* Copyright 2013-2018 the original author or authors. // * Copyright 2013-2018 the original author or authors.
* // *
* Licensed under the Apache License, Version 2.0 (the "License"); // * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. // * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at // * You may obtain a copy of the License at
* // *
* https://www.apache.org/licenses/LICENSE-2.0 // * https://www.apache.org/licenses/LICENSE-2.0
* // *
* Unless required by applicable law or agreed to in writing, software // * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, // * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // * See the License for the specific language governing permissions and
* limitations under the License. // * limitations under the License.
*/ // */
//
package com.alibaba.cloud.seata.feign; //package com.alibaba.cloud.seata.feign;
//
import feign.Feign; //import feign.Feign;
import feign.Retryer; //import feign.Retryer;
import feign.hystrix.HystrixFeign; //import feign.hystrix.HystrixFeign;
//
import org.springframework.beans.factory.BeanFactory; //import org.springframework.beans.factory.BeanFactory;
//
/** ///**
* @author xiaojing // * @author xiaojing
*/ // */
final class SeataHystrixFeignBuilder { //final class SeataHystrixFeignBuilder {
//
private SeataHystrixFeignBuilder() { // private SeataHystrixFeignBuilder() {
} // }
//
static Feign.Builder builder(BeanFactory beanFactory) { // static Feign.Builder builder(BeanFactory beanFactory) {
return HystrixFeign.builder().retryer(Retryer.NEVER_RETRY) // return HystrixFeign.builder().retryer(Retryer.NEVER_RETRY)
.client(new SeataFeignClient(beanFactory)); // .client(new SeataFeignClient(beanFactory));
} // }
//
} //}

@ -1,48 +1,45 @@
/* ///*
* Copyright 2013-2018 the original author or authors. // * Copyright 2013-2018 the original author or authors.
* // *
* Licensed under the Apache License, Version 2.0 (the "License"); // * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. // * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at // * You may obtain a copy of the License at
* // *
* https://www.apache.org/licenses/LICENSE-2.0 // * https://www.apache.org/licenses/LICENSE-2.0
* // *
* Unless required by applicable law or agreed to in writing, software // * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, // * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // * See the License for the specific language governing permissions and
* limitations under the License. // * limitations under the License.
*/ // */
//
package com.alibaba.cloud.seata.feign; //package com.alibaba.cloud.seata.feign;
//
import java.io.IOException; //import java.io.IOException;
//
import feign.Client; //import feign.Client;
import feign.Request; //import feign.Request;
import feign.Response; //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
/** // */
* @author xiaojing //public class SeataLoadBalancerFeignClient extends LoadBalancerFeignClient {
* @author yuhuangbin //
*/ // SeataLoadBalancerFeignClient(Client delegate,
public class SeataLoadBalancerFeignClient extends LoadBalancerFeignClient { // CachingSpringLoadBalancerFactory lbClientFactory,
// SpringClientFactory clientFactory,
SeataLoadBalancerFeignClient(Client delegate, // SeataFeignObjectWrapper seataFeignObjectWrapper) {
CachingSpringLoadBalancerFactory lbClientFactory, // super((Client) seataFeignObjectWrapper.wrap(delegate), lbClientFactory,
SpringClientFactory clientFactory, // 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);
@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=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.seata.rest.SeataRestTemplateAutoConfiguration,\ com.alibaba.cloud.seata.rest.SeataRestTemplateAutoConfiguration,\
com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration,\ com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration,\
com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration,\ com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration
com.alibaba.cloud.seata.feign.hystrix.SeataHystrixAutoConfiguration

@ -75,6 +75,12 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId> <artifactId>spring-cloud-commons</artifactId>
@ -156,6 +162,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -25,8 +25,8 @@ import feign.Contract;
import feign.Feign; import feign.Feign;
import feign.InvocationHandlerFactory; import feign.InvocationHandlerFactory;
import feign.Target; import feign.Target;
import feign.hystrix.FallbackFactory; //import feign.hystrix.FallbackFactory;
import feign.hystrix.HystrixFeign; //import feign.hystrix.HystrixFeign;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.cloud.openfeign.FeignContext; import org.springframework.cloud.openfeign.FeignContext;
@ -80,35 +80,35 @@ public final class SentinelFeign {
// using reflect get fallback and fallbackFactory properties from // using reflect get fallback and fallbackFactory properties from
// FeignClientFactoryBean because FeignClientFactoryBean is a package // FeignClientFactoryBean because FeignClientFactoryBean is a package
// level class, we can not use it in our package // level class, we can not use it in our package
Object feignClientFactoryBean = Builder.this.applicationContext // Object feignClientFactoryBean = Builder.this.applicationContext
.getBean("&" + target.type().getName()); // .getBean("&" + target.type().getName());
//
Class fallback = (Class) getFieldValue(feignClientFactoryBean, // Class fallback = (Class) getFieldValue(feignClientFactoryBean,
"fallback"); // "fallback");
Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean, // Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean,
"fallbackFactory"); // "fallbackFactory");
String beanName = (String) getFieldValue(feignClientFactoryBean, // String beanName = (String) getFieldValue(feignClientFactoryBean,
"contextId"); // "contextId");
if (!StringUtils.hasText(beanName)) { // if (!StringUtils.hasText(beanName)) {
beanName = (String) getFieldValue(feignClientFactoryBean, "name"); // beanName = (String) getFieldValue(feignClientFactoryBean, "name");
} // }
//
Object fallbackInstance; // Object fallbackInstance;
FallbackFactory fallbackFactoryInstance; // FallbackFactory fallbackFactoryInstance;
// check fallback and fallbackFactory properties // // check fallback and fallbackFactory properties
if (void.class != fallback) { // if (void.class != fallback) {
fallbackInstance = getFromContext(beanName, "fallback", fallback, // fallbackInstance = getFromContext(beanName, "fallback", fallback,
target.type()); // target.type());
return new SentinelInvocationHandler(target, dispatch, // return new SentinelInvocationHandler(target, dispatch,
new FallbackFactory.Default(fallbackInstance)); // new FallbackFactory.Default(fallbackInstance));
} // }
if (void.class != fallbackFactory) { // if (void.class != fallbackFactory) {
fallbackFactoryInstance = (FallbackFactory) getFromContext( // fallbackFactoryInstance = (FallbackFactory) getFromContext(
beanName, "fallbackFactory", fallbackFactory, // beanName, "fallbackFactory", fallbackFactory,
FallbackFactory.class); // FallbackFactory.class);
return new SentinelInvocationHandler(target, dispatch, // return new SentinelInvocationHandler(target, dispatch,
fallbackFactoryInstance); // fallbackFactoryInstance);
} // }
return new SentinelInvocationHandler(target, dispatch); return new SentinelInvocationHandler(target, dispatch);
} }

@ -33,7 +33,6 @@ import feign.Feign;
import feign.InvocationHandlerFactory.MethodHandler; import feign.InvocationHandlerFactory.MethodHandler;
import feign.MethodMetadata; import feign.MethodMetadata;
import feign.Target; import feign.Target;
import feign.hystrix.FallbackFactory;
import static feign.Util.checkNotNull; import static feign.Util.checkNotNull;
@ -48,18 +47,8 @@ public class SentinelInvocationHandler implements InvocationHandler {
private final Map<Method, MethodHandler> dispatch; private final Map<Method, MethodHandler> dispatch;
private FallbackFactory fallbackFactory;
private Map<Method, Method> fallbackMethodMap; 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) { SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch) {
this.target = checkNotNull(target, "target"); this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch"); this.dispatch = checkNotNull(dispatch, "dispatch");
@ -111,25 +100,8 @@ public class SentinelInvocationHandler implements InvocationHandler {
if (!BlockException.isBlockException(ex)) { if (!BlockException.isBlockException(ex)) {
Tracer.trace(ex); Tracer.trace(ex);
} }
if (fallbackFactory != null) { // throw exception if fallbackFactory is null
try { throw ex;
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;
}
} }
finally { finally {
if (entry != null) { if (entry != null) {

@ -25,6 +25,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.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -122,7 +123,7 @@ public class ContextIdSentinelFeignTests {
} }
public static class CustomFallbackFactory public static class CustomFallbackFactory
implements feign.hystrix.FallbackFactory<FooService> { implements FallbackFactory<FooService> {
private FooService fooService = new FooServiceFallback(); 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.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -191,7 +192,7 @@ public class SentinelFeignTests {
} }
public static class CustomFallbackFactory public static class CustomFallbackFactory
implements feign.hystrix.FallbackFactory<FooService> { implements FallbackFactory<FooService> {
private FooService fooService = new FooServiceFallback(); private FooService fooService = new FooServiceFallback();

@ -59,7 +59,7 @@ public class SidecarConsulAutoRegistration extends ConsulAutoRegistration {
service.setAddress(sidecarProperties.getIp()); service.setAddress(sidecarProperties.getIp());
} }
service.setName(normalizeForDns(appName)); 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 // set health check, use alibaba sidecar self's port rather than polyglot app's
// port. // port.

@ -37,7 +37,7 @@ public class SidecarNacosDiscoveryProperties extends NacosDiscoveryProperties {
super.init(); super.init();
String ip = sidecarProperties.getIp(); String ip = sidecarProperties.getIp();
if (!StringUtils.isEmpty(ip)) { if (!StringUtils.hasText(ip)) {
this.setIp(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.MutablePropertySources;
import org.springframework.core.env.PropertySource; 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 * The lowest precedence {@link EnvironmentPostProcessor} configures default RocketMQ Bus

@ -58,6 +58,13 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -131,7 +131,7 @@ public class RocketMQMessageHandler extends AbstractMessageHandler implements Li
} }
} }
catch (MQClientException e) { catch (MQClientException e) {
logger.error("fetch publish message queues fail", e); logger.error(e, "fetch publish message queues fail");
} }
} }
running = true; running = true;

Loading…
Cancel
Save