diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 93227711..635afc04 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -1085,6 +1085,53 @@ public class CustomLoadBalancerConfiguration { } ---- +=== Transform the load-balanced HTTP request + +You can use the selected `ServiceInstance` to transform the load-balanced HTTP Request. + +For `RestTemplate`, you need to implement and define `LoadBalancerRequestTransformer` as follows: + +[source,java,indent=0] +---- + @Bean + public LoadBalancerRequestTransformer transformer() { + return new LoadBalancerRequestTransformer() { + @Override + public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { + return new HttpRequestWrapper(request) { + @Override + public HttpHeaders getHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.putAll(super.getHeaders()); + headers.add("X-InstanceId", instance.getInstanceId()); + return headers; + } + }; + } + }; + } +---- + +For `WebClient`, you need to implement and define `LoadBalancerClientRequestTransformer` as follows: + +[source,java,indent=0] +---- + @Bean + public LoadBalancerClientRequestTransformer transformer() { + return new LoadBalancerClientRequestTransformer() { + @Override + public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { + return ClientRequest.from(request) + .header("X-InstanceId", instance.getInstanceId()) + .build(); + } + }; + } +---- + +If multiple transformers are defined, they are applied in the order in which Beans are defined. +Alternatively, you can use `LoadBalancerRequestTransformer.DEFAULT_ORDER` or `LoadBalancerClientRequestTransformer.DEFAULT_ORDER` to specify the order. + [[spring-cloud-loadbalancer-starter]] === Spring Cloud LoadBalancer Starter diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java index b5f6134e..319e3d06 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -17,6 +17,7 @@ package org.springframework.cloud.client.loadbalancer.reactive; import java.net.URI; +import java.util.List; import java.util.Map; import org.springframework.cloud.client.ServiceInstance; @@ -43,9 +44,11 @@ public final class ExchangeFilterFunctionUtils { } static ClientRequest buildClientRequest(ClientRequest request, ServiceInstance serviceInstance, - String instanceIdCookieName, boolean addServiceInstanceCookie) { + String instanceIdCookieName, boolean addServiceInstanceCookie, + List transformers) { URI originalUrl = request.url(); - return ClientRequest.create(request.method(), LoadBalancerUriTools.reconstructURI(serviceInstance, originalUrl)) + ClientRequest clientRequest = ClientRequest + .create(request.method(), LoadBalancerUriTools.reconstructURI(serviceInstance, originalUrl)) .headers(headers -> headers.addAll(request.headers())).cookies(cookies -> { cookies.addAll(request.cookies()); if (!(instanceIdCookieName == null || instanceIdCookieName.length() == 0) @@ -53,6 +56,12 @@ public final class ExchangeFilterFunctionUtils { cookies.add(instanceIdCookieName, serviceInstance.getInstanceId()); } }).attributes(attributes -> attributes.putAll(request.attributes())).body(request.body()).build(); + if (transformers != null) { + for (LoadBalancerClientRequestTransformer transformer : transformers) { + clientRequest = transformer.transformRequest(clientRequest, serviceInstance); + } + } + return clientRequest; } static String serviceInstanceUnavailableMessage(String serviceId) { diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java new file mode 100644 index 00000000..2701cf53 --- /dev/null +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2020 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.client.loadbalancer.reactive; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.annotation.Order; +import org.springframework.web.reactive.function.client.ClientRequest; + +/** + * Allows applications to transform the load-balanced {@link ClientRequest} given the + * chosen {@link ServiceInstance}. + * + * @author Toshiaki Maki + */ +@Order(LoadBalancerClientRequestTransformer.DEFAULT_ORDER) +public interface LoadBalancerClientRequestTransformer { + + /** + * Order for the load balancer request tranformer. + */ + int DEFAULT_ORDER = 0; + + ClientRequest transformRequest(ClientRequest request, ServiceInstance instance); + +} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java index 18226887..42135a3c 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java @@ -16,6 +16,10 @@ package org.springframework.cloud.client.loadbalancer.reactive; +import java.util.Collections; +import java.util.List; + +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -45,8 +49,10 @@ public class ReactorLoadBalancerClientAutoConfiguration { matchIfMissing = true) @Bean public ReactorLoadBalancerExchangeFilterFunction loadBalancerExchangeFilterFunction( - ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties) { - return new ReactorLoadBalancerExchangeFilterFunction(loadBalancerFactory, properties); + ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties, + ObjectProvider> transformers) { + return new ReactorLoadBalancerExchangeFilterFunction(loadBalancerFactory, properties, + transformers.getIfAvailable(Collections::emptyList)); } @ConditionalOnMissingBean @@ -54,8 +60,10 @@ public class ReactorLoadBalancerClientAutoConfiguration { @Bean public RetryableLoadBalancerExchangeFilterFunction retryableLoadBalancerExchangeFilterFunction( ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties, - LoadBalancerRetryPolicy retryPolicy) { - return new RetryableLoadBalancerExchangeFilterFunction(retryPolicy, loadBalancerFactory, properties); + LoadBalancerRetryPolicy retryPolicy, + ObjectProvider> transformers) { + return new RetryableLoadBalancerExchangeFilterFunction(retryPolicy, loadBalancerFactory, properties, + transformers.getIfAvailable(Collections::emptyList)); } @ConditionalOnMissingBean diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java index 256f0bb6..d5735b66 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java @@ -17,6 +17,8 @@ package org.springframework.cloud.client.loadbalancer.reactive; import java.net.URI; +import java.util.Collections; +import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; @@ -61,10 +63,25 @@ public class ReactorLoadBalancerExchangeFilterFunction implements LoadBalancedEx private final LoadBalancerProperties properties; + private final List transformers; + + /** + * @deprecated Deprecated in favor of + * {@link #ReactorLoadBalancerExchangeFilterFunction(ReactiveLoadBalancer.Factory, LoadBalancerProperties, List)}. + * @param loadBalancerFactory the loadbalancer factory + * @param properties the properties for SC LoadBalancer + */ + @Deprecated public ReactorLoadBalancerExchangeFilterFunction(ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties) { + this(loadBalancerFactory, properties, Collections.emptyList()); + } + + public ReactorLoadBalancerExchangeFilterFunction(ReactiveLoadBalancer.Factory loadBalancerFactory, + LoadBalancerProperties properties, List transformers) { this.loadBalancerFactory = loadBalancerFactory; this.properties = properties; + this.transformers = transformers; } @Override @@ -106,7 +123,7 @@ public class ReactorLoadBalancerExchangeFilterFunction implements LoadBalancedEx LoadBalancerProperties.StickySession stickySessionProperties = properties.getStickySession(); ClientRequest newRequest = buildClientRequest(clientRequest, instance, stickySessionProperties.getInstanceIdCookieName(), - stickySessionProperties.isAddServiceInstanceCookie()); + stickySessionProperties.isAddServiceInstanceCookie(), transformers); supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse)); return next.exchange(newRequest) .doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java index 4d4d7233..288c719a 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -19,6 +19,7 @@ package org.springframework.cloud.client.loadbalancer.reactive; import java.io.IOException; import java.net.URI; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.TimeoutException; @@ -66,8 +67,7 @@ public class RetryableLoadBalancerExchangeFilterFunction implements LoadBalanced private static final Log LOG = LogFactory.getLog(RetryableLoadBalancerExchangeFilterFunction.class); private static final List> exceptions = Arrays.asList(IOException.class, - TimeoutException.class, - org.springframework.cloud.client.loadbalancer.reactive.RetryableStatusCodeException.class); + TimeoutException.class, RetryableStatusCodeException.class); private final LoadBalancerRetryPolicy retryPolicy; @@ -75,11 +75,25 @@ public class RetryableLoadBalancerExchangeFilterFunction implements LoadBalanced private final ReactiveLoadBalancer.Factory loadBalancerFactory; + private final List transformers; + + /** + * @deprecated Deprecated in favor of + * {@link #RetryableLoadBalancerExchangeFilterFunction(LoadBalancerRetryPolicy, ReactiveLoadBalancer.Factory, LoadBalancerProperties, List)}. + */ + @Deprecated public RetryableLoadBalancerExchangeFilterFunction(LoadBalancerRetryPolicy retryPolicy, ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties) { + this(retryPolicy, loadBalancerFactory, properties, Collections.emptyList()); + } + + public RetryableLoadBalancerExchangeFilterFunction(LoadBalancerRetryPolicy retryPolicy, + ReactiveLoadBalancer.Factory loadBalancerFactory, LoadBalancerProperties properties, + List transformers) { this.retryPolicy = retryPolicy; this.loadBalancerFactory = loadBalancerFactory; this.properties = properties; + this.transformers = transformers; } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -129,7 +143,7 @@ public class RetryableLoadBalancerExchangeFilterFunction implements LoadBalanced LoadBalancerProperties.StickySession stickySessionProperties = properties.getStickySession(); ClientRequest newRequest = buildClientRequest(clientRequest, instance, stickySessionProperties.getInstanceIdCookieName(), - stickySessionProperties.isAddServiceInstanceCookie()); + stickySessionProperties.isAddServiceInstanceCookie(), transformers); supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse)); return next.exchange(newRequest) .doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java new file mode 100644 index 00000000..5e4b27f9 --- /dev/null +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2012-2020 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.client.loadbalancer.reactive; + +import java.net.URI; +import java.util.Arrays; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFunction; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Tests for {@link LoadBalancerClientRequestTransformer}. + * + * @author Toshiaki Maki + */ +class LoadBalancerClientRequestTransformerTest { + + private final LoadBalancerProperties properties = new LoadBalancerProperties(); + + private final LoadBalancerRetryPolicy policy = new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy( + properties); + + private final ReactiveLoadBalancer.Factory factory = mock(ReactiveLoadBalancer.Factory.class); + + private final ClientRequest clientRequest = mock(ClientRequest.class); + + private final ClientResponse clientResponse = mock(ClientResponse.class); + + private final ExchangeFunction next = mock(ExchangeFunction.class); + + @BeforeEach + void setUp() { + when(factory.getInstance("testServiceId")).thenReturn(new TestReactiveLoadBalancer()); + when(clientRequest.method()).thenReturn(HttpMethod.GET); + when(clientRequest.url()).thenReturn(URI.create("http://testServiceId")); + when(clientRequest.headers()).thenReturn(new HttpHeaders()); + when(clientRequest.cookies()).thenReturn(new LinkedMultiValueMap<>()); + when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); + when(clientResponse.statusCode()).thenReturn(HttpStatus.OK); + } + + @Test + void transformReactorLoadBalancerExchangeFilterFunction() { + ArgumentCaptor captor = ArgumentCaptor.forClass(ClientRequest.class); + ReactorLoadBalancerExchangeFilterFunction filterFunction = new ReactorLoadBalancerExchangeFilterFunction( + factory, properties, Arrays.asList(new Transformer1(), new Transformer2())); + filterFunction.filter(clientRequest, next).subscribe(); + verify(next).exchange(captor.capture()); + HttpHeaders headers = captor.getValue().headers(); + assertThat(headers.getFirst("X-ServiceId")).isEqualTo("testServiceId"); + assertThat(headers.getFirst("X-InstanceId")).isEqualTo("testServiceId"); + } + + @Test + void transformRetryableLoadBalancerExchangeFilterFunction() { + ArgumentCaptor captor = ArgumentCaptor.forClass(ClientRequest.class); + RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( + policy, factory, properties, Arrays.asList(new Transformer1(), new Transformer2())); + filterFunction.filter(clientRequest, next).subscribe(); + verify(next).exchange(captor.capture()); + HttpHeaders headers = captor.getValue().headers(); + assertThat(headers.getFirst("X-ServiceId")).isEqualTo("testServiceId"); + assertThat(headers.getFirst("X-InstanceId")).isEqualTo("testServiceId"); + } + + class Transformer1 implements LoadBalancerClientRequestTransformer { + + @Override + public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { + return ClientRequest.from(request).header("X-ServiceId", instance.getServiceId()).build(); + } + + } + + class Transformer2 implements LoadBalancerClientRequestTransformer { + + @Override + public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { + return ClientRequest.from(request).header("X-InstanceId", instance.getInstanceId()).build(); + } + + } + +} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java index 45b6c2cc..a1c3eb3c 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java index 2cb8fd2c..5a183c8d 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java @@ -18,6 +18,7 @@ package org.springframework.cloud.client.loadbalancer.reactive; import java.io.IOException; import java.net.URI; +import java.util.Collections; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -57,7 +58,7 @@ class RetryableLoadBalancerExchangeFilterFunctionTests { private final ReactiveLoadBalancer.Factory factory = mock(ReactiveLoadBalancer.Factory.class); private final RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( - policy, factory, properties); + policy, factory, properties, Collections.emptyList()); private final ClientRequest clientRequest = mock(ClientRequest.class); @@ -137,7 +138,7 @@ class RetryableLoadBalancerExchangeFilterFunctionTests { properties.getRetry().getRetryableStatusCodes().add(404); LoadBalancerRetryPolicy policy = new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy(properties); RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( - policy, factory, properties); + policy, factory, properties, Collections.emptyList()); when(clientRequest.method()).thenReturn(HttpMethod.POST); when(clientResponse.statusCode()).thenReturn(HttpStatus.NOT_FOUND); when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java index 39ae4107..916432a0 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java @@ -67,7 +67,7 @@ class CachingServiceInstanceListSupplierTests { @Test void shouldNotHangOnCachingWhenDelegateReturnsInfiniteStream() { - assertTimeoutPreemptively(ofMillis(500), () -> { + assertTimeoutPreemptively(ofMillis(1000), () -> { blockingLoadBalancerClient.choose(SERVICE_ID); }); diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java index 3a84850d..d2081cbe 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java @@ -59,13 +59,13 @@ import static org.mockito.Mockito.when; * @author Spencer Gibb */ @SpringBootTest -public class LoadBalancerTests { +class LoadBalancerTests { @Autowired private LoadBalancerClientFactory clientFactory; @Test - public void roundRobbinLoadbalancerWorks() { + void roundRobbinLoadbalancerWorks() { ReactiveLoadBalancer reactiveLoadBalancer = this.clientFactory.getInstance("myservice", ReactiveLoadBalancer.class, ServiceInstance.class); @@ -101,7 +101,7 @@ public class LoadBalancerTests { } @Test - public void emptyHosts() { + void emptyHosts() { ResolvableType type = ResolvableType.forClassWithGenerics(ReactorLoadBalancer.class, ServiceInstance.class); ReactorLoadBalancer loadBalancer = this.clientFactory.getInstance("unknownservice", type); @@ -115,7 +115,7 @@ public class LoadBalancerTests { } @Test - public void staticConfigurationWorks() { + void staticConfigurationWorks() { String serviceId = "test1"; RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers .toProvider(serviceId, instance(serviceId, "1host", false), instance(serviceId, "2host-secure", true)), @@ -129,7 +129,7 @@ public class LoadBalancerTests { @SuppressWarnings("ConstantConditions") @Test - public void canPassHintViaRequest() { + void canPassHintViaRequest() { String serviceId = "test1"; RoundRobinLoadBalancer loadBalancer = new TestHintLoadBalancer(ServiceInstanceListSuppliers.toProvider( serviceId, instance(serviceId, "1host", false), instance(serviceId, "2host-secure", true)), serviceId); @@ -141,7 +141,7 @@ public class LoadBalancerTests { } @Test - public void selectedInstanceCallback() { + void selectedInstanceCallback() { String serviceId = "test1"; ServiceInstance serviceInstance = instance(serviceId, "1host", false); SameInstancePreferenceServiceInstanceListSupplier supplier = mock(