Customize load balanced requests according to the chosen ServiceInstance (#735)
This commit is contained in:
@@ -815,6 +815,33 @@ Sometimes, when load balancing is enabled for Feign clients, you may want to use
|
||||
spring.cloud.openfeign.oauth2.load-balanced=true
|
||||
----
|
||||
|
||||
=== Transform the load-balanced HTTP request
|
||||
|
||||
You can use the selected `ServiceInstance` to transform the load-balanced HTTP Request.
|
||||
|
||||
For `Request`, you need to implement and define `LoadBalancerFeignRequestTransformer`, as follows:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Bean
|
||||
public LoadBalancerFeignRequestTransformer transformer() {
|
||||
return new LoadBalancerFeignRequestTransformer() {
|
||||
|
||||
@Override
|
||||
public Request transformRequest(Request request, ServiceInstance instance) {
|
||||
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
|
||||
headers.put("X-ServiceId", Collections.singletonList(instance.getServiceId()));
|
||||
headers.put("X-InstanceId", Collections.singletonList(instance.getInstanceId()));
|
||||
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(),
|
||||
request.requestTemplate());
|
||||
}
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
If multiple transformers are defined, they are applied in the order in which beans are defined.
|
||||
Alternatively, you can use `LoadBalancerFeignRequestTransformer.DEFAULT_ORDER` to specify the order.
|
||||
|
||||
== Configuration properties
|
||||
|
||||
To see the list of all Spring Cloud OpenFeign related configuration properties please check link:appendix.html[the Appendix page].
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.loadbalancer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import feign.Client;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -36,6 +38,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* that uses {@link Client.Default} under the hood.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -46,9 +49,10 @@ class DefaultFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Conditional(OnRetryNotEnabledCondition.class)
|
||||
public Client feignClient(LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
return new FeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient,
|
||||
loadBalancerClientFactory);
|
||||
loadBalancerClientFactory, transformers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -58,9 +62,10 @@ class DefaultFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public Client feignRetryClient(LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
return new RetryableFeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient,
|
||||
loadBalancedRetryFactory, loadBalancerClientFactory);
|
||||
loadBalancedRetryFactory, loadBalancerClientFactory, transformers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.openfeign.loadbalancer;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import feign.Client;
|
||||
@@ -49,6 +51,7 @@ import static org.springframework.cloud.openfeign.loadbalancer.LoadBalancerUtils
|
||||
* {@link ServiceInstance} to use while resolving the request host.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@@ -62,9 +65,11 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
|
||||
private final LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
|
||||
private final List<LoadBalancerFeignRequestTransformer> transformers;
|
||||
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link FeignBlockingLoadBalancerClient#FeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancerClientFactory)}
|
||||
* {@link FeignBlockingLoadBalancerClient#FeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancerClientFactory, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
public FeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
@@ -72,13 +77,29 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
this.delegate = delegate;
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link FeignBlockingLoadBalancerClient#FeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancerClientFactory, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
public FeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
this.delegate = delegate;
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = Collections.emptyList();
|
||||
}
|
||||
|
||||
public FeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
this.delegate = delegate;
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = transformers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,7 +130,7 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
.body(message, StandardCharsets.UTF_8).build();
|
||||
}
|
||||
String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
|
||||
Request newRequest = buildRequest(request, reconstructedUrl);
|
||||
Request newRequest = buildRequest(request, reconstructedUrl, instance);
|
||||
return executeWithLoadBalancerLifecycleProcessing(delegate, options, newRequest, lbRequest, lbResponse,
|
||||
supportedLifecycleProcessors);
|
||||
}
|
||||
@@ -119,6 +140,16 @@ public class FeignBlockingLoadBalancerClient implements Client {
|
||||
request.charset(), request.requestTemplate());
|
||||
}
|
||||
|
||||
protected Request buildRequest(Request request, String reconstructedUrl, ServiceInstance instance) {
|
||||
Request newRequest = buildRequest(request, reconstructedUrl);
|
||||
if (transformers != null) {
|
||||
for (LoadBalancerFeignRequestTransformer transformer : transformers) {
|
||||
newRequest = transformer.transformRequest(newRequest, instance);
|
||||
}
|
||||
}
|
||||
return newRequest;
|
||||
}
|
||||
|
||||
// Visible for Sleuth instrumentation
|
||||
public Client getDelegate() {
|
||||
return delegate;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.loadbalancer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import feign.Client;
|
||||
import feign.hc5.ApacheHttp5Client;
|
||||
import org.apache.hc.client5.http.classic.HttpClient;
|
||||
@@ -40,6 +42,7 @@ import org.springframework.context.annotation.Import;
|
||||
* that uses {@link ApacheHttp5Client} under the hood.
|
||||
*
|
||||
* @author Nguyen Ky Thanh
|
||||
* @author changjin wei(魏昌进)
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ApacheHttp5Client.class)
|
||||
@@ -53,9 +56,11 @@ class HttpClient5FeignLoadBalancerConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Conditional(OnRetryNotEnabledCondition.class)
|
||||
public Client feignClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient5,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
Client delegate = new ApacheHttp5Client(httpClient5);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory,
|
||||
transformers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -65,10 +70,11 @@ class HttpClient5FeignLoadBalancerConfiguration {
|
||||
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient5,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
Client delegate = new ApacheHttp5Client(httpClient5);
|
||||
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
|
||||
loadBalancerClientFactory);
|
||||
loadBalancerClientFactory, transformers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.loadbalancer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import feign.Client;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.apache.http.client.HttpClient;
|
||||
@@ -42,6 +44,7 @@ import org.springframework.context.annotation.Import;
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author Nguyen Ky Thanh
|
||||
* @author changjin wei(魏昌进)
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -57,9 +60,11 @@ class HttpClientFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Conditional(OnRetryNotEnabledCondition.class)
|
||||
public Client feignClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory,
|
||||
transformers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -69,10 +74,11 @@ class HttpClientFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
|
||||
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
|
||||
loadBalancerClientFactory);
|
||||
loadBalancerClientFactory, transformers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2013-2022 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 org.springframework.cloud.openfeign.loadbalancer;
|
||||
|
||||
import feign.Request;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* Allows applications to transform the load-balanced {@link Request} given the chosen
|
||||
* {@link org.springframework.cloud.client.ServiceInstance}.
|
||||
*
|
||||
* @author changjin wei(魏昌进)
|
||||
*/
|
||||
@Order(LoadBalancerFeignRequestTransformer.DEFAULT_ORDER)
|
||||
public interface LoadBalancerFeignRequestTransformer {
|
||||
|
||||
/**
|
||||
* Order for the {@link LoadBalancerFeignRequestTransformer}.
|
||||
*/
|
||||
int DEFAULT_ORDER = 0;
|
||||
|
||||
/**
|
||||
* Allows transforming load-balanced requests based on the provided {@link ServiceInstance}.
|
||||
* @param request Original request.
|
||||
* @param instance ServiceInstance returned from LoadBalancer.
|
||||
* @return New request or original request
|
||||
*/
|
||||
Request transformRequest(Request request, ServiceInstance instance);
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.openfeign.loadbalancer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import feign.Client;
|
||||
import feign.okhttp.OkHttpClient;
|
||||
|
||||
@@ -39,6 +41,7 @@ import org.springframework.context.annotation.Import;
|
||||
* that uses {@link OkHttpClient} under the hood.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -53,9 +56,11 @@ class OkHttpFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Conditional(OnRetryNotEnabledCondition.class)
|
||||
public Client feignClient(okhttp3.OkHttpClient okHttpClient, LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
OkHttpClient delegate = new OkHttpClient(okHttpClient);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
|
||||
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory,
|
||||
transformers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -65,10 +70,11 @@ class OkHttpFeignLoadBalancerConfiguration {
|
||||
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, okhttp3.OkHttpClient okHttpClient,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
OkHttpClient delegate = new OkHttpClient(okHttpClient);
|
||||
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
|
||||
loadBalancerClientFactory);
|
||||
loadBalancerClientFactory, transformers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -65,6 +66,7 @@ import static org.springframework.cloud.openfeign.loadbalancer.LoadBalancerUtils
|
||||
* load-balanced with Spring Cloud LoadBalancer.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @since 2.2.6
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@@ -80,9 +82,11 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
|
||||
private final LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
|
||||
private final List<LoadBalancerFeignRequestTransformer> transformers;
|
||||
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link RetryableFeignBlockingLoadBalancerClient#RetryableFeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancedRetryFactory, LoadBalancerClientFactory)}
|
||||
* {@link RetryableFeignBlockingLoadBalancerClient#RetryableFeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancedRetryFactory, LoadBalancerClientFactory, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
public RetryableFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
@@ -92,14 +96,31 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link RetryableFeignBlockingLoadBalancerClient#RetryableFeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancedRetryFactory, LoadBalancerClientFactory, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
public RetryableFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
this.delegate = delegate;
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = Collections.emptyList();
|
||||
}
|
||||
|
||||
public RetryableFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory,
|
||||
List<LoadBalancerFeignRequestTransformer> transformers) {
|
||||
this.delegate = delegate;
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
|
||||
this.loadBalancerClientFactory = loadBalancerClientFactory;
|
||||
this.transformers = transformers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +179,7 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
}
|
||||
String reconstructedUrl = loadBalancerClient.reconstructURI(retrievedServiceInstance, originalUri)
|
||||
.toString();
|
||||
feignRequest = buildRequest(request, reconstructedUrl);
|
||||
feignRequest = buildRequest(request, reconstructedUrl, retrievedServiceInstance);
|
||||
}
|
||||
}
|
||||
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
|
||||
@@ -191,6 +212,16 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
|
||||
request.charset(), request.requestTemplate());
|
||||
}
|
||||
|
||||
protected Request buildRequest(Request request, String reconstructedUrl, ServiceInstance instance) {
|
||||
Request newRequest = buildRequest(request, reconstructedUrl);
|
||||
if (transformers != null) {
|
||||
for (LoadBalancerFeignRequestTransformer transformer : transformers) {
|
||||
newRequest = transformer.transformRequest(newRequest, instance);
|
||||
}
|
||||
}
|
||||
return newRequest;
|
||||
}
|
||||
|
||||
private RetryTemplate buildRetryTemplate(String serviceId, Request request, LoadBalancedRetryPolicy retryPolicy) {
|
||||
RetryTemplate retryTemplate = new RetryTemplate();
|
||||
BackOffPolicy backOffPolicy = this.loadBalancedRetryFactory.createBackOffPolicy(serviceId);
|
||||
|
||||
@@ -21,9 +21,11 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -66,6 +68,7 @@ import static org.mockito.Mockito.when;
|
||||
* {@link FeignBlockingLoadBalancerClient} and its delegates.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @see <a href=
|
||||
* "https://github.com/spring-cloud/spring-cloud-commons/blob/main/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java">BlockingLoadBalancerClientTests</a>
|
||||
*/
|
||||
@@ -80,8 +83,11 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
|
||||
private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties();
|
||||
|
||||
private final List<LoadBalancerFeignRequestTransformer> transformers = Arrays.asList(new InstanceIdTransformer(),
|
||||
new ServiceIdTransformer());
|
||||
|
||||
private final FeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new FeignBlockingLoadBalancerClient(
|
||||
delegate, loadBalancerClient, loadBalancerClientFactory);
|
||||
delegate, loadBalancerClient, loadBalancerClientFactory, transformers);
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
@@ -133,9 +139,11 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
Request actualRequest = captor.getValue();
|
||||
assertThat(actualRequest.httpMethod()).isEqualTo(Request.HttpMethod.GET);
|
||||
assertThat(actualRequest.url()).isEqualTo(url);
|
||||
assertThat(actualRequest.headers()).hasSize(1);
|
||||
assertThat(actualRequest.headers()).hasSize(3);
|
||||
assertThat(actualRequest.headers()).containsEntry(HttpHeaders.CONTENT_TYPE,
|
||||
Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
|
||||
assertThat(actualRequest.headers()).containsEntry("X-ServiceId", Collections.singletonList("test"));
|
||||
assertThat(actualRequest.headers()).containsEntry("X-InstanceId", Collections.singletonList("test-1"));
|
||||
assertThat(new String(actualRequest.body())).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@@ -253,4 +261,28 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
|
||||
}
|
||||
|
||||
private static class InstanceIdTransformer implements LoadBalancerFeignRequestTransformer {
|
||||
|
||||
@Override
|
||||
public Request transformRequest(Request request, ServiceInstance instance) {
|
||||
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
|
||||
headers.put("X-InstanceId", Collections.singletonList(instance.getInstanceId()));
|
||||
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(),
|
||||
request.requestTemplate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ServiceIdTransformer implements LoadBalancerFeignRequestTransformer {
|
||||
|
||||
@Override
|
||||
public Request transformRequest(Request request, ServiceInstance instance) {
|
||||
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
|
||||
headers.put("X-ServiceId", Collections.singletonList(instance.getServiceId()));
|
||||
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(),
|
||||
request.requestTemplate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -70,6 +72,7 @@ import static org.mockito.Mockito.when;
|
||||
* {@link RetryableFeignBlockingLoadBalancerClient} and its delegates.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author changjin wei(魏昌进)
|
||||
* @see <a href=
|
||||
* "https://github.com/spring-cloud/spring-cloud-commons/blob/main/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java">BlockingLoadBalancerClientTests</a>
|
||||
*/
|
||||
@@ -86,8 +89,11 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
|
||||
private final LoadBalancerProperties properties = new LoadBalancerProperties();
|
||||
|
||||
private final List<LoadBalancerFeignRequestTransformer> transformers = Arrays.asList(new InstanceIdTransformer(),
|
||||
new ServiceIdTransformer());
|
||||
|
||||
private final RetryableFeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new RetryableFeignBlockingLoadBalancerClient(
|
||||
delegate, loadBalancerClient, retryFactory, properties, loadBalancerClientFactory);
|
||||
delegate, loadBalancerClient, retryFactory, loadBalancerClientFactory, transformers);
|
||||
|
||||
private final ServiceInstance serviceInstance = new DefaultServiceInstance("test-a", "test", "testhost", 80, false);
|
||||
|
||||
@@ -197,9 +203,11 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
Request actualRequest = captor.getValue();
|
||||
assertThat(actualRequest.httpMethod()).isEqualTo(Request.HttpMethod.GET);
|
||||
assertThat(actualRequest.url()).isEqualTo(url);
|
||||
assertThat(actualRequest.headers()).hasSize(1);
|
||||
assertThat(actualRequest.headers()).hasSize(3);
|
||||
assertThat(actualRequest.headers()).containsEntry(HttpHeaders.CONTENT_TYPE,
|
||||
Collections.singletonList(MediaType.APPLICATION_JSON_VALUE));
|
||||
assertThat(actualRequest.headers()).containsEntry("X-ServiceId", Collections.singletonList("test"));
|
||||
assertThat(actualRequest.headers()).containsEntry("X-InstanceId", Collections.singletonList("test-1"));
|
||||
assertThat(new String(actualRequest.body())).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@@ -310,4 +318,28 @@ class RetryableFeignBlockingLoadBalancerClientTests {
|
||||
|
||||
}
|
||||
|
||||
private static class InstanceIdTransformer implements LoadBalancerFeignRequestTransformer {
|
||||
|
||||
@Override
|
||||
public Request transformRequest(Request request, ServiceInstance instance) {
|
||||
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
|
||||
headers.put("X-InstanceId", Collections.singletonList(instance.getInstanceId()));
|
||||
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(),
|
||||
request.requestTemplate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ServiceIdTransformer implements LoadBalancerFeignRequestTransformer {
|
||||
|
||||
@Override
|
||||
public Request transformRequest(Request request, ServiceInstance instance) {
|
||||
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
|
||||
headers.put("X-ServiceId", Collections.singletonList(instance.getServiceId()));
|
||||
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(),
|
||||
request.requestTemplate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user