You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2022/06/23 16:16:52 UTC
[incubator-shenyu] branch master updated: [type:refeactor] springcloud plugin use shenyu-loadbalancer (#3598)
This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new b769aaa5e [type:refeactor] springcloud plugin use shenyu-loadbalancer (#3598)
b769aaa5e is described below
commit b769aaa5e0ea3c061e27922e767b0f83a849bb73
Author: moremind <he...@hotmail.com>
AuthorDate: Fri Jun 24 00:16:42 2022 +0800
[type:refeactor] springcloud plugin use shenyu-loadbalancer (#3598)
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] shenyu-plugin-springcloud use shenyu-loadbalancer
* [ISSUE #3552] fix check style
---
shenyu-bootstrap/pom.xml | 11 -
.../shenyu-integrated-test-spring-cloud/pom.xml | 16 --
shenyu-plugin/shenyu-plugin-springcloud/pom.xml | 20 --
.../springcloud/loadbalance/LoadBalanceRule.java | 66 -----
.../client/CustomBlockingLoadBalancerClient.java | 61 -----
.../ShenyuSpringCloudLoadBalancerClient.java | 305 +++++++++++++++++++++
.../plugin/springcloud/SpringCloudPluginTest.java | 4 +-
.../loadbalance/LoadBalanceRuleTest.java | 75 -----
.../ShenyuSpringCloudLoadBalancerClientTest.java | 202 ++++++++++++++
.../SpringCloudPluginConfiguration.java | 61 +----
.../SpringCloudPluginConfigurationTest.java | 20 --
11 files changed, 520 insertions(+), 321 deletions(-)
diff --git a/shenyu-bootstrap/pom.xml b/shenyu-bootstrap/pom.xml
index 60cfd3aaa..eec17d6e2 100644
--- a/shenyu-bootstrap/pom.xml
+++ b/shenyu-bootstrap/pom.xml
@@ -266,17 +266,6 @@
<artifactId>spring-cloud-commons</artifactId>
<version>${spring-cloud-commons.version}</version>
</dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
- <version>${spring-cloud-netflix-ribbon.version}</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<!--shenyu springCloud plugin start-->
diff --git a/shenyu-integrated-test/shenyu-integrated-test-spring-cloud/pom.xml b/shenyu-integrated-test/shenyu-integrated-test-spring-cloud/pom.xml
index dc54216d3..9e87b124d 100644
--- a/shenyu-integrated-test/shenyu-integrated-test-spring-cloud/pom.xml
+++ b/shenyu-integrated-test/shenyu-integrated-test-spring-cloud/pom.xml
@@ -52,22 +52,6 @@
</exclusion>
</exclusions>
</dependency>
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
- <version>${spring-cloud-netflix-ribbon.version}</version>
- <exclusions>
- <exclusion>
- <artifactId>spring-cloud-context</artifactId>
- <groupId>org.springframework.cloud</groupId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/pom.xml b/shenyu-plugin/shenyu-plugin-springcloud/pom.xml
index 98bb22b14..f61c3cbf7 100644
--- a/shenyu-plugin/shenyu-plugin-springcloud/pom.xml
+++ b/shenyu-plugin/shenyu-plugin-springcloud/pom.xml
@@ -58,25 +58,5 @@
<artifactId>shenyu-loadbalancer</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
- <version>${spring-cloud-netflix-ribbon.version}</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-netflix-archaius</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>spring-cloud-starter</artifactId>
- <groupId>org.springframework.cloud</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-loadbalancer</artifactId>
- <version>${spring-cloud-commons.version}</version>
- </dependency>
</dependencies>
</project>
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRule.java b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRule.java
deleted file mode 100644
index f6c01c86c..000000000
--- a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRule.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shenyu.plugin.springcloud.loadbalance;
-
-import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.ZoneAvoidanceRule;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.shenyu.common.dto.convert.selector.SpringCloudSelectorHandle;
-import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
-import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
-import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The spring cloud loadbalancer rule.
- */
-public class LoadBalanceRule extends ZoneAvoidanceRule {
-
- @Override
- public Server choose(final Object key) {
- final LoadBalanceKey loadBalanceKey = LoadBalanceKeyHolder.getLoadBalanceKey();
- final List<Server> available = getPredicate().getEligibleServers(getLoadBalancer().getAllServers(), key);
- if (CollectionUtils.isEmpty(available)) {
- return null;
- }
- final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudPluginDataHandler.SELECTOR_CACHED.get().obtainHandle(loadBalanceKey.getSelectorId());
- if (!springCloudSelectorHandle.getGray()) {
- return super.choose(key);
- }
- List<Upstream> divideUpstreams = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(loadBalanceKey.getSelectorId());
- if (CollectionUtils.isEmpty(divideUpstreams)) {
- return super.choose(key);
- }
- //select server from available to choose
- final List<Upstream> choose = new ArrayList<>(available.size());
- for (Server server : available) {
- divideUpstreams.stream()
- .filter(Upstream::isStatus)
- .filter(upstream -> upstream.getUrl().equals(server.getHostPort()))
- .findFirst().ifPresent(choose::add);
- }
- if (CollectionUtils.isEmpty(choose)) {
- return super.choose(key);
- }
- Upstream upstream = LoadBalancerFactory.selector(choose, loadBalanceKey.getLoadBalance(), loadBalanceKey.getIp());
- return available.stream().filter(server -> server.getHostPort().equals(upstream.getUrl())).findFirst().orElse(null);
- }
-}
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/CustomBlockingLoadBalancerClient.java b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/CustomBlockingLoadBalancerClient.java
deleted file mode 100644
index 34d4c9959..000000000
--- a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/CustomBlockingLoadBalancerClient.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shenyu.plugin.springcloud.loadbalance.client;
-
-import org.springframework.cloud.client.ServiceInstance;
-import org.springframework.cloud.client.loadbalancer.Request;
-import org.springframework.cloud.client.loadbalancer.Response;
-import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
-import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
-import reactor.core.publisher.Mono;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * blocking loadbalancer client.
- */
-public class CustomBlockingLoadBalancerClient extends BlockingLoadBalancerClient {
- private final ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory;
-
- public CustomBlockingLoadBalancerClient(final ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory) {
- super(loadBalancerClientFactory);
- this.loadBalancerClientFactory = loadBalancerClientFactory;
- }
-
- @Override
- public <T> ServiceInstance choose(final String serviceId, final Request<T> request) {
- ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory.getInstance(serviceId);
- if (loadBalancer == null) {
- return null;
- }
- CompletableFuture<Response<ServiceInstance>> f = CompletableFuture.supplyAsync(() -> Mono.from(loadBalancer.choose(request)).block());
- Response<ServiceInstance> loadBalancerResponse = null;
- try {
- loadBalancerResponse = f.get(3, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- e.printStackTrace();
- }
- if (loadBalancerResponse == null) {
- return null;
- }
- return loadBalancerResponse.getServer();
- }
-}
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClient.java b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClient.java
new file mode 100644
index 000000000..95318999e
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClient.java
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.springcloud.loadbalance.client;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.common.dto.convert.selector.SpringCloudSelectorHandle;
+import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
+import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
+import org.apache.shenyu.plugin.springcloud.loadbalance.LoadBalanceKey;
+import org.apache.shenyu.plugin.springcloud.loadbalance.LoadBalanceKeyHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.client.loadbalancer.CompletionContext;
+import org.springframework.cloud.client.loadbalancer.DefaultRequest;
+import org.springframework.cloud.client.loadbalancer.DefaultRequestContext;
+import org.springframework.cloud.client.loadbalancer.DefaultResponse;
+import org.springframework.cloud.client.loadbalancer.EmptyResponse;
+import org.springframework.cloud.client.loadbalancer.HttpRequestLoadBalancerRequest;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycleValidator;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestAdapter;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools;
+import org.springframework.cloud.client.loadbalancer.Request;
+import org.springframework.cloud.client.loadbalancer.RequestData;
+import org.springframework.cloud.client.loadbalancer.RequestDataContext;
+import org.springframework.cloud.client.loadbalancer.ResponseData;
+import org.springframework.cloud.client.loadbalancer.TimedRequestContext;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.util.ReflectionUtils;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer.REQUEST;
+
+/**
+ * spring cloud plugin loadbalancer.
+ */
+public class ShenyuSpringCloudLoadBalancerClient implements LoadBalancerClient {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ShenyuSpringCloudLoadBalancerClient.class);
+
+ private final DiscoveryClient discoveryClient;
+
+ private final ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory;
+
+ public ShenyuSpringCloudLoadBalancerClient(final DiscoveryClient discoveryClient,
+ final ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory) {
+ this.discoveryClient = discoveryClient;
+ this.loadBalancerClientFactory = loadBalancerClientFactory;
+ }
+
+ @Override
+ public <T> T execute(final String serviceId, final LoadBalancerRequest<T> request) throws IOException {
+ String hint = getHint(serviceId);
+ LoadBalancerRequestAdapter<T, TimedRequestContext> lbRequest = new LoadBalancerRequestAdapter<>(request,
+ buildRequestContext(request, hint));
+ Set<LoadBalancerLifecycle> supportedLifecycleProcessors = getSupportedLifecycleProcessors(serviceId);
+ supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
+ ServiceInstance serviceInstance = choose(serviceId, lbRequest);
+ if (serviceInstance == null) {
+ supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
+ new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, new EmptyResponse())));
+ throw new IllegalStateException("No instances available for " + serviceId);
+ }
+ return execute(serviceId, serviceInstance, lbRequest);
+ }
+
+ @Override
+ public <T> T execute(final String serviceId, final ServiceInstance serviceInstance, final LoadBalancerRequest<T> request) throws IOException {
+ DefaultResponse defaultResponse = new DefaultResponse(serviceInstance);
+ Set<LoadBalancerLifecycle> supportedLifecycleProcessors = getSupportedLifecycleProcessors(serviceId);
+ Request lbRequest = request instanceof Request ? (Request) request : new DefaultRequest<>();
+ supportedLifecycleProcessors
+ .forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, new DefaultResponse(serviceInstance)));
+ try {
+ T response = request.apply(serviceInstance);
+ LoadBalancerProperties properties = loadBalancerClientFactory.getProperties(serviceId);
+ Object clientResponse = getClientResponse(response, properties.isUseRawStatusCodeInResponseData());
+ supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
+ lbRequest, defaultResponse, clientResponse)));
+ return response;
+ } catch (IOException ioException) {
+ supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
+ new CompletionContext<>(CompletionContext.Status.FAILED, ioException, lbRequest, defaultResponse)));
+ throw ioException;
+ } catch (Exception exception) {
+ supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
+ new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, defaultResponse)));
+ ReflectionUtils.rethrowRuntimeException(exception);
+ } finally {
+ LOG.info("execute serviceInstance error");
+ }
+ return null;
+ }
+
+ @Override
+ public URI reconstructURI(final ServiceInstance instance, final URI original) {
+ return LoadBalancerUriTools.reconstructURI(instance, original);
+ }
+
+ @Override
+ public ServiceInstance choose(final String serviceId) {
+ return choose(serviceId, REQUEST);
+ }
+
+ @Override
+ public <T> ServiceInstance choose(final String serviceId, final Request<T> request) {
+ final LoadBalanceKey loadBalanceKey = LoadBalanceKeyHolder.getLoadBalanceKey();
+ List<ServiceInstance> available = this.getServiceInstance(serviceId);
+ if (CollectionUtils.isEmpty(available)) {
+ return null;
+ }
+ final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudPluginDataHandler.SELECTOR_CACHED.get().obtainHandle(loadBalanceKey.getSelectorId());
+ // not gray flow
+ if (!springCloudSelectorHandle.getGray()) {
+ return this.doSelect(serviceId);
+ }
+ List<Upstream> divideUpstreams = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(loadBalanceKey.getSelectorId());
+ // gray flow,but upstream is null
+ if (CollectionUtils.isEmpty(divideUpstreams)) {
+ return this.doSelect(serviceId);
+ }
+ //select server from available to choose
+ final List<Upstream> choose = new ArrayList<>(available.size());
+ for (ServiceInstance serviceInstance : available) {
+ divideUpstreams.stream()
+ .filter(Upstream::isStatus)
+ .filter(upstream -> Objects.equals(buildUrl(upstream), String.valueOf(serviceInstance.getUri())))
+ .findFirst().ifPresent(choose::add);
+ }
+ if (CollectionUtils.isEmpty(choose)) {
+ return this.doSelect(serviceId);
+ }
+ // select by divideUpstreams
+ return this.doSelect(serviceId, choose);
+ }
+
+ private <T> TimedRequestContext buildRequestContext(final LoadBalancerRequest<T> delegate, final String hint) {
+ if (delegate instanceof HttpRequestLoadBalancerRequest) {
+ HttpRequest request = ((HttpRequestLoadBalancerRequest<?>) delegate).getHttpRequest();
+ if (request != null) {
+ RequestData requestData = new RequestData(request);
+ return new RequestDataContext(requestData, hint);
+ }
+ }
+ return new DefaultRequestContext(delegate, hint);
+ }
+
+ private Set<LoadBalancerLifecycle> getSupportedLifecycleProcessors(final String serviceId) {
+ return LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(
+ loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
+ DefaultRequestContext.class, Object.class, ServiceInstance.class);
+ }
+
+ private <T> Object getClientResponse(final T response, final boolean useRawStatusCodes) {
+ ClientHttpResponse clientHttpResponse = null;
+ if (response instanceof ClientHttpResponse) {
+ clientHttpResponse = (ClientHttpResponse) response;
+ }
+ if (clientHttpResponse != null) {
+ try {
+ if (useRawStatusCodes) {
+ return new ResponseData(null, clientHttpResponse);
+ }
+ return new ResponseData(clientHttpResponse, null);
+ } catch (IOException ignored) {
+ } finally {
+ clientHttpResponse.close();
+ }
+ }
+ return response;
+ }
+
+ /**
+ * build url.
+ * @param upstream upstream
+ * @return url
+ */
+ private static String buildUrl(final Upstream upstream) {
+ if (Objects.isNull(upstream)) {
+ return null;
+ }
+ String protocol = upstream.getProtocol();
+ if (StringUtils.isBlank(protocol)) {
+ protocol = "http://";
+ }
+ return protocol + upstream.getUrl().trim();
+ }
+
+ /**
+ * select serviceInstance by shenyu loadbalancer.
+ *
+ * @param serviceId serviceId
+ * @return ServiceInstance
+ */
+ private ServiceInstance doSelect(final String serviceId) {
+ List<Upstream> choose = this.buildUpstream(serviceId);
+ return this.doSelect(serviceId, choose);
+ }
+
+ /**
+ * execute loadbalancer by shenyu loadbalancer.
+ *
+ * @param serviceId serviceId
+ * @param upstreamList upstream list
+ * @return
+ */
+ private ServiceInstance doSelect(final String serviceId, final List<Upstream> upstreamList) {
+ final LoadBalanceKey loadBalanceKey = LoadBalanceKeyHolder.getLoadBalanceKey();
+ // default loadbalancer
+ if (Objects.isNull(loadBalanceKey) || StringUtils.isEmpty(loadBalanceKey.getLoadBalance())) {
+ loadBalanceKey.setLoadBalance("random");
+ }
+ Upstream upstream = LoadBalancerFactory.selector(upstreamList, loadBalanceKey.getLoadBalance(), loadBalanceKey.getIp());
+ List<ServiceInstance> instances = this.getServiceInstance(serviceId);
+
+ Optional<ServiceInstance> serviceInstance = instances.stream().filter(x -> {
+ String url = String.valueOf(x.getUri());
+ return url.equals(buildUrl(upstream));
+ }).findFirst();
+ if (serviceInstance.isPresent()) {
+ ServiceInstance instance = serviceInstance.get();
+ DefaultResponse defaultResponse = new DefaultResponse(instance);
+ return defaultResponse.getServer();
+ }
+ return null;
+ }
+
+ /**
+ * get service instance by serviceId.
+ *
+ * @param serviceId serviceId
+ * @return {@linkplain ServiceInstance}
+ */
+ private List<ServiceInstance> getServiceInstance(final String serviceId) {
+ List<String> serviceNames = discoveryClient.getServices().stream().map(String::toUpperCase).collect(Collectors.toList());
+ if (!serviceNames.contains(serviceId.toUpperCase())) {
+ return Collections.emptyList();
+ }
+ return discoveryClient.getInstances(serviceId);
+ }
+
+ /**
+ * build upstream by service instance.
+ *
+ * @param serviceId serviceId
+ * @return Upstream
+ */
+ private List<Upstream> buildUpstream(final String serviceId) {
+ List<ServiceInstance> serviceInstanceList = this.getServiceInstance(serviceId);
+ if (serviceInstanceList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return serviceInstanceList.stream().map(x -> {
+ String uri = x.getUri().toString();
+ String[] urlPart = uri.split("\\:\\//");
+ String protocol = urlPart[0];
+ String url = urlPart[1];
+ return Upstream.builder()
+ .protocol(protocol + "://")
+ .url(url)
+ .build();
+ }).collect(Collectors.toList());
+ }
+
+ private String getHint(final String serviceId) {
+ LoadBalancerProperties properties = loadBalancerClientFactory.getProperties(serviceId);
+ String defaultHint = properties.getHint().getOrDefault("default", "default");
+ String hintPropertyValue = properties.getHint().get(serviceId);
+ return hintPropertyValue != null ? hintPropertyValue : defaultHint;
+ }
+}
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/SpringCloudPluginTest.java b/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/SpringCloudPluginTest.java
index cb4cddfe5..c43953b2b 100644
--- a/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/SpringCloudPluginTest.java
+++ b/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/SpringCloudPluginTest.java
@@ -35,6 +35,7 @@ import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
+import org.apache.shenyu.plugin.springcloud.loadbalance.client.ShenyuSpringCloudLoadBalancerClient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -43,7 +44,6 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
-import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
@@ -74,7 +74,7 @@ import static org.mockito.Mockito.when;
public final class SpringCloudPluginTest {
@Mock
- private RibbonLoadBalancerClient loadBalancerClient;
+ private ShenyuSpringCloudLoadBalancerClient loadBalancerClient;
private SpringCloudPlugin springCloudPlugin;
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRuleTest.java b/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRuleTest.java
deleted file mode 100644
index 8f1a2e75e..000000000
--- a/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/LoadBalanceRuleTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shenyu.plugin.springcloud.loadbalance;
-
-import com.netflix.loadbalancer.BaseLoadBalancer;
-import com.netflix.loadbalancer.ILoadBalancer;
-import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.ZoneAvoidanceRule;
-import org.apache.shenyu.common.dto.SelectorData;
-import org.apache.shenyu.common.dto.convert.selector.DivideUpstream;
-import org.apache.shenyu.common.dto.convert.selector.SpringCloudSelectorHandle;
-import org.apache.shenyu.common.utils.GsonUtils;
-import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The Test Case For LoadBalanceRule.
- */
-public final class LoadBalanceRuleTest {
-
- private LoadBalanceRule loadBalanceRule = new LoadBalanceRule();
-
- private SpringCloudPluginDataHandler springCloudPluginDataHandler = new SpringCloudPluginDataHandler();
-
- @Test
- public void testChoose() {
- LoadBalanceKey loadBalanceKey = new LoadBalanceKey();
- loadBalanceKey.setIp("0.0.0.0");
- loadBalanceKey.setSelectorId("1");
- loadBalanceKey.setLoadBalance("random");
- LoadBalanceKeyHolder.setLoadBalanceKey(loadBalanceKey);
- ZoneAvoidanceRule zoneAvoidanceRule = new ZoneAvoidanceRule();
- ILoadBalancer lb = new BaseLoadBalancer();
- List<Server> list = new ArrayList<>();
- list.add(new Server("localhost", 8080));
- lb.addServers(list);
- loadBalanceRule.setLoadBalancer(lb);
- List<DivideUpstream> divideUpstreams = new ArrayList<>();
- DivideUpstream divideUpstream = DivideUpstream.builder()
- .upstreamUrl("localhost:8080")
- .build();
- divideUpstreams.add(divideUpstream);
- final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudSelectorHandle.builder()
- .serviceId("serviceId")
- .divideUpstreams(divideUpstreams)
- .gray(true)
- .build();
- final SelectorData selectorData = SelectorData.builder()
- .handle(GsonUtils.getInstance().toJson(springCloudSelectorHandle))
- .id("1")
- .build();
- springCloudPluginDataHandler.handlerSelector(selectorData);
- Server server = loadBalanceRule.choose(loadBalanceKey);
- Assertions.assertEquals(server.getHostPort(), "localhost:8080");
- }
-}
diff --git a/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClientTest.java b/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClientTest.java
new file mode 100644
index 000000000..653ee8f7c
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-springcloud/src/test/java/org/apache/shenyu/plugin/springcloud/loadbalance/client/ShenyuSpringCloudLoadBalancerClientTest.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.springcloud.loadbalance.client;
+
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.dto.convert.selector.DivideUpstream;
+import org.apache.shenyu.common.dto.convert.selector.SpringCloudSelectorHandle;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
+import org.apache.shenyu.plugin.springcloud.loadbalance.LoadBalanceKey;
+import org.apache.shenyu.plugin.springcloud.loadbalance.LoadBalanceKeyHolder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient;
+import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The Test Case For ShenyuSpringCloudLoadBalancerClientTest.
+ */
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class ShenyuSpringCloudLoadBalancerClientTest {
+ @Mock
+ private ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory;
+
+ private SimpleDiscoveryClient discoveryClient;
+
+ private ShenyuSpringCloudLoadBalancerClient loadBalancerClient;
+
+ private final SpringCloudPluginDataHandler springCloudPluginDataHandler = new SpringCloudPluginDataHandler();
+
+ @BeforeEach
+ public void setup() {
+ final List<DefaultServiceInstance> serviceInstanceList = new ArrayList<>();
+ DefaultServiceInstance defaultServiceInstance = new DefaultServiceInstance();
+ defaultServiceInstance.setServiceId("serviceId");
+ defaultServiceInstance.setUri(URI.create("http://localhost:8080"));
+ defaultServiceInstance.setInstanceId("serviceId");
+ defaultServiceInstance.setPort(8080);
+ defaultServiceInstance.setHost("localhost");
+ serviceInstanceList.add(defaultServiceInstance);
+ SimpleDiscoveryProperties simpleDiscoveryProperties = new SimpleDiscoveryProperties();
+ Map<String, List<DefaultServiceInstance>> serviceInstanceMap = new HashMap<>();
+ serviceInstanceMap.put(defaultServiceInstance.getInstanceId(), serviceInstanceList);
+ simpleDiscoveryProperties.setInstances(serviceInstanceMap);
+ discoveryClient = new SimpleDiscoveryClient(simpleDiscoveryProperties);
+ loadBalancerClient = new ShenyuSpringCloudLoadBalancerClient(discoveryClient, loadBalancerClientFactory);
+ }
+
+ @Test
+ public void testChoose() {
+ LoadBalanceKey loadBalanceKey = new LoadBalanceKey();
+ loadBalanceKey.setIp("0.0.0.0");
+ loadBalanceKey.setSelectorId("1");
+ loadBalanceKey.setLoadBalance("roundRobin");
+ LoadBalanceKeyHolder.setLoadBalanceKey(loadBalanceKey);
+
+ // serviceInstance is null
+ ServiceInstance serviceInstanceIsNull = loadBalancerClient.choose("test");
+ Assertions.assertNull(serviceInstanceIsNull);
+
+ // not gray flow
+ List<DivideUpstream> divideUpstreams = new ArrayList<>();
+ DivideUpstream divideUpstream = DivideUpstream.builder()
+ .upstreamUrl("localhost:8080")
+ .build();
+ divideUpstreams.add(divideUpstream);
+ final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudSelectorHandle.builder()
+ .serviceId("serviceId")
+ .divideUpstreams(divideUpstreams)
+ .gray(false)
+ .build();
+ final SelectorData selectorData = SelectorData.builder()
+ .handle(GsonUtils.getInstance().toJson(springCloudSelectorHandle))
+ .id("1")
+ .build();
+ springCloudPluginDataHandler.handlerSelector(selectorData);
+ ServiceInstance serviceInstance = loadBalancerClient.choose("serviceId");
+ Assertions.assertNotNull(serviceInstance);
+ Assertions.assertEquals(serviceInstance.getInstanceId(), "serviceId");
+
+ // gray flow
+ springCloudSelectorHandle.setGray(true);
+ final SelectorData selectorDataGray = SelectorData.builder()
+ .handle(GsonUtils.getInstance().toJson(springCloudSelectorHandle))
+ .id("1")
+ .build();
+ springCloudPluginDataHandler.handlerSelector(selectorDataGray);
+ ServiceInstance serviceInstanceGray = loadBalancerClient.choose("serviceId");
+ Assertions.assertNotNull(serviceInstanceGray);
+ Assertions.assertEquals(serviceInstanceGray.getHost(), "localhost");
+ }
+
+ @Test
+ public void testReconstructURI() {
+ LoadBalanceKey loadBalanceKey = new LoadBalanceKey();
+ loadBalanceKey.setIp("0.0.0.0");
+ loadBalanceKey.setSelectorId("1");
+ loadBalanceKey.setLoadBalance("roundRobin");
+ LoadBalanceKeyHolder.setLoadBalanceKey(loadBalanceKey);
+ List<DivideUpstream> divideUpstreams = new ArrayList<>();
+ DivideUpstream divideUpstream = DivideUpstream.builder()
+ .upstreamUrl("localhost:8080")
+ .build();
+ divideUpstreams.add(divideUpstream);
+ final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudSelectorHandle.builder()
+ .serviceId("serviceId")
+ .divideUpstreams(divideUpstreams)
+ .gray(false)
+ .build();
+ final SelectorData selectorData = SelectorData.builder()
+ .handle(GsonUtils.getInstance().toJson(springCloudSelectorHandle))
+ .id("1")
+ .build();
+ springCloudPluginDataHandler.handlerSelector(selectorData);
+ ServiceInstance serviceInstance = loadBalancerClient.choose("serviceId");
+ URI uri = loadBalancerClient.reconstructURI(serviceInstance, URI.create("/test"));
+ Assertions.assertEquals(uri.toString(), "http://localhost:8080/test");
+ }
+
+ @Test
+ public void testLoadBalancer() {
+ final List<DefaultServiceInstance> serviceInstances = new ArrayList<>();
+ DefaultServiceInstance defaultServiceInstance = new DefaultServiceInstance();
+ defaultServiceInstance.setServiceId("serviceId");
+ defaultServiceInstance.setUri(URI.create("http://localhost:8081"));
+ defaultServiceInstance.setInstanceId("serviceId");
+ defaultServiceInstance.setPort(8081);
+ defaultServiceInstance.setHost("localhost");
+
+ DefaultServiceInstance defaultServiceInstance2 = new DefaultServiceInstance();
+ defaultServiceInstance2.setServiceId("serviceId");
+ defaultServiceInstance2.setUri(URI.create("http://localhost:8080"));
+ defaultServiceInstance2.setInstanceId("serviceId");
+ defaultServiceInstance2.setPort(8080);
+ defaultServiceInstance2.setHost("localhost");
+ serviceInstances.add(defaultServiceInstance);
+ serviceInstances.add(defaultServiceInstance2);
+
+ SimpleDiscoveryProperties simpleDiscoveryProperties = new SimpleDiscoveryProperties();
+ Map<String, List<DefaultServiceInstance>> serviceInstanceMap = new HashMap<>();
+ serviceInstanceMap.put(defaultServiceInstance.getInstanceId(), serviceInstances);
+ simpleDiscoveryProperties.setInstances(serviceInstanceMap);
+ discoveryClient = new SimpleDiscoveryClient(simpleDiscoveryProperties);
+ loadBalancerClient = new ShenyuSpringCloudLoadBalancerClient(discoveryClient, loadBalancerClientFactory);
+
+ LoadBalanceKey loadBalanceKey = new LoadBalanceKey();
+ loadBalanceKey.setIp("0.0.0.0");
+ loadBalanceKey.setSelectorId("1");
+ loadBalanceKey.setLoadBalance("roundRobin");
+ LoadBalanceKeyHolder.setLoadBalanceKey(loadBalanceKey);
+ List<DivideUpstream> divideUpstreams = new ArrayList<>();
+ DivideUpstream divideUpstream = DivideUpstream.builder()
+ .upstreamUrl("localhost:8080")
+ .build();
+ divideUpstreams.add(divideUpstream);
+ final SpringCloudSelectorHandle springCloudSelectorHandle = SpringCloudSelectorHandle.builder()
+ .serviceId("serviceId")
+ .divideUpstreams(divideUpstreams)
+ .gray(false)
+ .build();
+ final SelectorData selectorData = SelectorData.builder()
+ .handle(GsonUtils.getInstance().toJson(springCloudSelectorHandle))
+ .id("1")
+ .build();
+ springCloudPluginDataHandler.handlerSelector(selectorData);
+ ServiceInstance serviceInstance = loadBalancerClient.choose("serviceId");
+ ServiceInstance serviceInstance2 = loadBalancerClient.choose("serviceId");
+ // if roundRobin, serviceInstance not equals serviceInstance2
+ Assertions.assertNotEquals(serviceInstance, serviceInstance2);
+ }
+}
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/main/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/main/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfiguration.java
index b21c9d835..0a6571278 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/main/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/main/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfiguration.java
@@ -17,33 +17,21 @@
package org.apache.shenyu.springboot.starter.plugin.springcloud;
-import com.netflix.client.config.CommonClientConfigKey;
-import com.netflix.client.config.IClientConfig;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.PollingServerListUpdater;
-import com.netflix.loadbalancer.ServerListUpdater;
-import org.apache.shenyu.common.config.ShenyuConfig;
-import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.plugin.api.ShenyuPlugin;
import org.apache.shenyu.plugin.api.context.ShenyuContextDecorator;
import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
import org.apache.shenyu.plugin.springcloud.SpringCloudPlugin;
import org.apache.shenyu.plugin.springcloud.context.SpringCloudShenyuContextDecorator;
import org.apache.shenyu.plugin.springcloud.handler.SpringCloudPluginDataHandler;
-import org.apache.shenyu.plugin.springcloud.loadbalance.LoadBalanceRule;
-import org.apache.shenyu.plugin.springcloud.loadbalance.client.CustomBlockingLoadBalancerClient;
+import org.apache.shenyu.plugin.springcloud.loadbalance.client.ShenyuSpringCloudLoadBalancerClient;
import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
-import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
-import org.springframework.cloud.netflix.ribbon.RibbonClientSpecification;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-
-import java.util.Optional;
/**
* The type Spring cloud plugin configuration.
@@ -52,17 +40,17 @@ import java.util.Optional;
@ConditionalOnProperty(value = {"shenyu.plugins.spring-cloud.enabled"}, havingValue = "true", matchIfMissing = true)
public class SpringCloudPluginConfiguration {
-
/**
- * custom blocking loadbalancer.
+ * shenyu springcloud loadbalancer.
+ *
+ * @param discoveryClient discoveryClient
* @param loadBalancerClientFactory loadBalancerFactory
- * @return loadBalancerClient
+ * @return {@linkplain LoadBalancerClient}
*/
- @ConditionalOnProperty(value = {"spring.cloud.loadbalancer.ribbon.enabled"}, havingValue = "false", matchIfMissing = true)
- @ConditionalOnClass(value = BlockingLoadBalancerClient.class)
@Bean
- public LoadBalancerClient blockingLoadBalancerClient(final ObjectProvider<LoadBalancerClientFactory> loadBalancerClientFactory) {
- return new CustomBlockingLoadBalancerClient(loadBalancerClientFactory.getIfAvailable());
+ public LoadBalancerClient shenyuSpringCloudLoadBalancerClient(final ObjectProvider<DiscoveryClient> discoveryClient,
+ final ObjectProvider<ReactiveLoadBalancer.Factory<ServiceInstance>> loadBalancerClientFactory) {
+ return new ShenyuSpringCloudLoadBalancerClient(discoveryClient.getIfAvailable(), loadBalancerClientFactory.getIfAvailable());
}
/**
@@ -96,31 +84,4 @@ public class SpringCloudPluginConfiguration {
return new SpringCloudPluginDataHandler();
}
- /**
- * Custom ribbon IRule.
- *
- * @return ribbonClientSpecification
- */
- @Bean
- public RibbonClientSpecification ribbonClientSpecification() {
- Class<?>[] classes = new Class[]{SpringCloudClientConfiguration.class};
- return new RibbonClientSpecification(String.join(".", Constants.DEFAULT.toLowerCase(), RibbonClientSpecification.class.getName()), classes);
- }
-
- static class SpringCloudClientConfiguration {
- @Bean
- public IRule ribbonRule() {
- return new LoadBalanceRule();
- }
-
- @Lazy
- @Bean
- public ServerListUpdater ribbonServerListUpdater(final IClientConfig config,
- final ShenyuConfig shenyuConfig) {
- Integer refreshInterval = Optional.ofNullable(shenyuConfig.getRibbon().getServerListRefreshInterval()).orElseGet(() -> 10000);
- config.set(CommonClientConfigKey.ServerListRefreshInterval, refreshInterval);
- return new PollingServerListUpdater(config);
- }
- }
-
}
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/test/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfigurationTest.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/test/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfigurationTest.java
index f9aebe02e..88fda9256 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/test/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfigurationTest.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-springcloud/src/test/java/org/apache/shenyu/springboot/starter/plugin/springcloud/SpringCloudPluginConfigurationTest.java
@@ -17,7 +17,6 @@
package org.apache.shenyu.springboot.starter.plugin.springcloud;
-import com.netflix.loadbalancer.IRule;
import org.apache.shenyu.common.enums.PluginEnum;
import org.apache.shenyu.plugin.api.ShenyuPlugin;
import org.apache.shenyu.plugin.api.context.ShenyuContextDecorator;
@@ -27,7 +26,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
-import org.springframework.cloud.netflix.ribbon.RibbonClientSpecification;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
@@ -77,22 +75,4 @@ public class SpringCloudPluginConfigurationTest {
}
);
}
-
- @Test
- public void testRibbonClientSpecification() {
- applicationContextRunner.run(context -> {
- RibbonClientSpecification specification = context.getBean("ribbonClientSpecification", RibbonClientSpecification.class);
- assertNotNull(specification);
- }
- );
- }
-
- @Test
- public void testLoadBalanceRulen() {
- applicationContextRunner.run(context -> {
- IRule rule = context.getBean("ribbonRule", IRule.class);
- assertNotNull(rule);
- }
- );
- }
}