diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7ae097936..bb92bc177 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,7 +22,7 @@ jobs: distribution: 'temurin' java-version: '17' - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/docs/pom.xml b/docs/pom.xml index 263674764..caac708e6 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT jar Spring Cloud Commons Docs diff --git a/pom.xml b/pom.xml index c71abc501..9f7ab579f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT pom Spring Cloud Commons Parent Spring Cloud Commons Parent @@ -13,7 +13,7 @@ org.springframework.cloud spring-cloud-build - 4.0.6-SNAPSHOT + 4.0.7-SNAPSHOT diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml index 89d9e7f5f..4cf0faacc 100644 --- a/spring-cloud-commons-dependencies/pom.xml +++ b/spring-cloud-commons-dependencies/pom.xml @@ -6,11 +6,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 4.0.6-SNAPSHOT + 4.0.7-SNAPSHOT spring-cloud-commons-dependencies - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT pom spring-cloud-commons-dependencies Spring Cloud Commons Dependencies diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml index d37b528ca..c2a94f386 100644 --- a/spring-cloud-commons/pom.xml +++ b/spring-cloud-commons/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-commons diff --git a/spring-cloud-context-integration-tests/pom.xml b/spring-cloud-context-integration-tests/pom.xml index 7de18d0f9..72390d53d 100644 --- a/spring-cloud-context-integration-tests/pom.xml +++ b/spring-cloud-context-integration-tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-context-integration-tests diff --git a/spring-cloud-context-webflux-integration-tests/pom.xml b/spring-cloud-context-webflux-integration-tests/pom.xml index 6b7c8aa99..367d0ab2a 100644 --- a/spring-cloud-context-webflux-integration-tests/pom.xml +++ b/spring-cloud-context-webflux-integration-tests/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-context-webflux-integration-tests diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml index 381428a76..e8bba2f01 100644 --- a/spring-cloud-context/pom.xml +++ b/spring-cloud-context/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-context diff --git a/spring-cloud-loadbalancer/pom.xml b/spring-cloud-loadbalancer/pom.xml index f64af90d4..b75f2c34a 100644 --- a/spring-cloud-loadbalancer/pom.xml +++ b/spring-cloud-loadbalancer/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-loadbalancer diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java index d21672ce8..33441fc14 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java @@ -25,17 +25,21 @@ import org.springframework.cloud.client.loadbalancer.RequestDataContext; import org.springframework.cloud.client.loadbalancer.ResponseData; import org.springframework.util.StringUtils; +import org.springframework.web.reactive.function.client.WebClient; /** * Utility class for building metrics tags for load-balanced calls. * * @author Olga Maciaszek-Sharma + * @author Jarek Dembek * @since 3.0.0 */ final class LoadBalancerTags { static final String UNKNOWN = "UNKNOWN"; + static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate"; + private LoadBalancerTags() { throw new UnsupportedOperationException("Cannot instantiate utility class"); } @@ -70,6 +74,12 @@ private static int statusValue(ResponseData responseData) { } private static String getPath(RequestData requestData) { + if (requestData.getAttributes() != null) { + var uriTemplate = (String) requestData.getAttributes().get(URI_TEMPLATE_ATTRIBUTE); + if (uriTemplate != null) { + return uriTemplate; + } + } return requestData.getUrl() != null ? requestData.getUrl().getPath() : UNKNOWN; } diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java index 8c944ffdd..1b37b0ad4 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -76,6 +77,7 @@ void reset() { @Test @CompileWithForkedClassLoader + @Disabled @SuppressWarnings("unchecked") void shouldStartLBChildContextsFromAotContributions(CapturedOutput output) { WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java index d2bb0eeac..8cd38ced8 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java @@ -28,6 +28,7 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import reactor.core.publisher.Flux; @@ -664,6 +665,7 @@ void shouldCheckInstanceWithProvidedHealthCheckPathWithQueryParams() { } @Test + @Disabled void shouldCheckUseProvidedPortForHealthCheckRequest() { Throwable exception = catchThrowable(() -> { String serviceId = "ignored-service"; diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java index 49d8714c7..965d92579 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java @@ -14,168 +14,189 @@ * limitations under the License. */ -package org.springframework.cloud.loadbalancer.stats; +package org.springframework.cloud.loadbalancer.config; -import java.net.URI; -import java.util.HashMap; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import com.github.benmanes.caffeine.cache.Caffeine; import org.junit.jupiter.api.Test; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -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.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.util.MultiValueMapAdapter; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.cache.support.NoOpCacheManager; +import org.springframework.cloud.loadbalancer.cache.DefaultLoadBalancerCacheManager; +import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.UNKNOWN; /** - * Tests for {@link MicrometerStatsLoadBalancerLifecycle}. + * Tests for {@link LoadBalancerCacheAutoConfiguration}. * * @author Olga Maciaszek-Sharma + * @author Jarek Dembek */ -class MicrometerStatsLoadBalancerLifecycleTests { +class LoadBalancerCacheAutoConfigurationTests { + + @Test + void shouldAutoEnableCaching() { + ApplicationContextRunner contextRunner = baseApplicationRunner(); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()).hasSize(1); + assertThat(context.getBean("caffeineLoadBalancerCacheManager")).isInstanceOf(CaffeineCacheManager.class); + assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()) + .contains("CachingServiceInstanceListSupplierCache"); + }); + } - MeterRegistry meterRegistry = new SimpleMeterRegistry(); + @Test + void caffeineLoadBalancerCacheShouldNotOverrideCacheTypeSetting() { + ApplicationContextRunner contextRunner = baseApplicationRunner().withUserConfiguration(TestConfiguration.class) + .withPropertyValues("spring.cache.type=none"); - MicrometerStatsLoadBalancerLifecycle statsLifecycle = new MicrometerStatsLoadBalancerLifecycle(meterRegistry); + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); + assertThat(context.getBean("caffeineLoadBalancerCacheManager")).isInstanceOf(CaffeineCacheManager.class); + assertThat(context.getBeansOfType(CacheManager.class).get("cacheManager")) + .isInstanceOf(NoOpCacheManager.class); + + }); + } @Test - void shouldRecordSuccessfulTimedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - ResponseData responseData = new ResponseData(HttpStatus.OK, new HttpHeaders(), - new MultiValueMapAdapter<>(new HashMap<>()), requestData); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", "GET"), Tag.of("outcome", "SUCCESS"), Tag.of("serviceId", "test"), - Tag.of("serviceInstance.host", "test.org"), Tag.of("serviceInstance.instanceId", "test-1"), - Tag.of("serviceInstance.port", "8080"), Tag.of("status", "200"), Tag.of("uri", "/test")); + void loadBalancerCacheShouldNotOverrideExistingCaffeineCacheManager() { + ApplicationContextRunner contextRunner = baseApplicationRunner().withUserConfiguration(TestConfiguration.class); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); + assertThat(context.getBean("cacheManager")).isInstanceOf(CaffeineCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()).hasSize(1); + assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()) + .contains("CachingServiceInstanceListSupplierCache"); + }); + } @Test - void shouldRecordFailedTimedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, new IllegalStateException(), - lbRequest, lbResponse)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timer().getId().getTags()).contains( - Tag.of("exception", "IllegalStateException"), Tag.of("method", "GET"), Tag.of("serviceId", "test"), - Tag.of("serviceInstance.host", "test.org"), Tag.of("serviceInstance.instanceId", "test-1"), - Tag.of("serviceInstance.port", "8080"), Tag.of("uri", "/test")); + void shouldNotInstantiateCaffeineLoadBalancerCacheIfDisabled() { + ApplicationContextRunner contextRunner = baseApplicationRunner() + .withPropertyValues("spring.cloud.loadbalancer.cache.enabled=false") + .withUserConfiguration(TestConfiguration.class); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(context.getBean("cacheManager")).isInstanceOf(CaffeineCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + }); } @Test - void shouldNotRecordDiscardedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new EmptyResponse(); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - - statsLifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, lbResponse)); - assertThat(meterRegistry.getMeters()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.discard").counter().count()).isEqualTo(1); + void shouldUseDefaultCacheIfCaffeineNotInClasspath() { + ApplicationContextRunner contextRunner = noCaffeineRunner(); + + contextRunner.run(context -> { + assertThat(context.getBean(LoadBalancerCacheAutoConfiguration.LoadBalancerCaffeineWarnLogger.class)) + .isNotNull(); + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); + assertThat(context.getBean("defaultLoadBalancerCacheManager")) + .isInstanceOf(DefaultLoadBalancerCacheManager.class); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) + .contains("CachingServiceInstanceListSupplierCache"); + }); } @Test - void shouldNotRecordUnTimedRequest() { - Request lbRequest = new DefaultRequest<>(new StatsTestContext()); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - ResponseData responseData = new ResponseData(HttpStatus.OK, new HttpHeaders(), - new MultiValueMapAdapter<>(new HashMap<>()), null); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); + void shouldUseDefaultCacheIfCaffeineCacheManagerNotInClasspath() { + ApplicationContextRunner contextRunner = noCaffeineCacheManagerRunner(); + + contextRunner.run(context -> { + assertThat(context.getBean(LoadBalancerCacheAutoConfiguration.LoadBalancerCaffeineWarnLogger.class)) + .isNotNull(); + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); + assertThat(context.getBean("defaultLoadBalancerCacheManager")) + .isInstanceOf(DefaultLoadBalancerCacheManager.class); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) + .contains("CachingServiceInstanceListSupplierCache"); + }); } @Test - void shouldNotCreateNullTagsWhenNullDataObjects() { - Request lbRequest = new DefaultRequest<>(new DefaultRequestContext()); - Response lbResponse = new DefaultResponse(new DefaultServiceInstance()); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle - .onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, null)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", UNKNOWN), Tag.of("outcome", UNKNOWN), Tag.of("serviceId", UNKNOWN), - Tag.of("serviceInstance.host", UNKNOWN), Tag.of("serviceInstance.instanceId", UNKNOWN), - Tag.of("serviceInstance.port", "0"), Tag.of("status", UNKNOWN), Tag.of("uri", UNKNOWN)); + void defaultLoadBalancerCacheShouldNotOverrideCacheTypeSetting() { + ApplicationContextRunner contextRunner = noCaffeineRunner().withUserConfiguration(TestConfiguration.class) + .withPropertyValues("spring.cache.type=none"); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); + assertThat(context.getBean("defaultLoadBalancerCacheManager")) + .isInstanceOf(DefaultLoadBalancerCacheManager.class); + assertThat(context.getBeansOfType(CacheManager.class).get("cacheManager")) + .isInstanceOf(NoOpCacheManager.class); + + }); } @Test - void shouldNotCreateNullTagsWhenEmptyDataObjects() { - RequestData requestData = new RequestData(null, null, null, null, null); - Request lbRequest = new DefaultRequest<>(new RequestDataContext()); - Response lbResponse = new DefaultResponse(new DefaultServiceInstance()); - ResponseData responseData = new ResponseData(null, null, null, requestData); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", UNKNOWN), Tag.of("outcome", "SUCCESS"), Tag.of("serviceId", UNKNOWN), - Tag.of("serviceInstance.host", UNKNOWN), Tag.of("serviceInstance.instanceId", UNKNOWN), - Tag.of("serviceInstance.port", "0"), Tag.of("status", "200"), Tag.of("uri", UNKNOWN)); + void defaultLoadBalancerCacheShouldNotOverrideExistingCacheManager() { + ApplicationContextRunner contextRunner = noCaffeineRunner().withUserConfiguration(TestConfiguration.class); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); + assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); + assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) + .contains("CachingServiceInstanceListSupplierCache"); + }); + + } + + @Test + void shouldNotInstantiateDefaultLoadBalancerCacheIfDisabled() { + ApplicationContextRunner contextRunner = noCaffeineRunner() + .withPropertyValues("spring.cloud.loadbalancer.cache.enabled=false") + .withUserConfiguration(TestConfiguration.class); + + contextRunner.run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + }); + } + + @Test + void shouldNotInstantiateDefaultLoadBalancerCacheIfLoadBalancingDisabled() { + noCaffeineRunner().withPropertyValues("spring.cloud.loadbalancer.enabled=false") + .withUserConfiguration(TestConfiguration.class).run(context -> { + assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); + assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); + assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); + }); + } + + private ApplicationContextRunner baseApplicationRunner() { + return new ApplicationContextRunner().withConfiguration( + AutoConfigurations.of(CacheAutoConfiguration.class, LoadBalancerCacheAutoConfiguration.class)); + } + + private ApplicationContextRunner noCaffeineRunner() { + return baseApplicationRunner().withClassLoader(new FilteredClassLoader(Caffeine.class)); + } + + private ApplicationContextRunner noCaffeineCacheManagerRunner() { + return baseApplicationRunner().withClassLoader(new FilteredClassLoader(CaffeineCacheManager.class)); } - private static class StatsTestContext { + @Configuration(proxyBeanMethods = false) + @EnableCaching + static class TestConfiguration { } diff --git a/spring-cloud-starter-bootstrap/pom.xml b/spring-cloud-starter-bootstrap/pom.xml index cef34b98c..80b86645b 100644 --- a/spring-cloud-starter-bootstrap/pom.xml +++ b/spring-cloud-starter-bootstrap/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. jar diff --git a/spring-cloud-starter-loadbalancer/pom.xml b/spring-cloud-starter-loadbalancer/pom.xml index 13a8292cc..9070c6975 100644 --- a/spring-cloud-starter-loadbalancer/pom.xml +++ b/spring-cloud-starter-loadbalancer/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. 4.0.0 diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml index a396f157d..0835ea4f3 100644 --- a/spring-cloud-starter/pom.xml +++ b/spring-cloud-starter/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT spring-cloud-starter spring-cloud-starter diff --git a/spring-cloud-test-support/pom.xml b/spring-cloud-test-support/pom.xml index 1ec3f3dd8..0c015ebbc 100644 --- a/spring-cloud-test-support/pom.xml +++ b/spring-cloud-test-support/pom.xml @@ -7,7 +7,7 @@ org.springframework.cloud spring-cloud-commons-parent - 4.0.5-SNAPSHOT + 4.0.6-SNAPSHOT .. spring-cloud-test-support