mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-05 16:59:28 +00:00
Simplify BaseUrl code and cache resolved URLs
See gh-47680
This commit is contained in:
+3
-7
@@ -59,7 +59,7 @@ public final class BaseUrlUriBuilderFactory implements UriBuilderFactory {
|
||||
|
||||
@Override
|
||||
public UriBuilder uriString(String uriTemplate) {
|
||||
return createDelegate().uriString(uriTemplate);
|
||||
return this.baseUrl.getUriBuilderFactory().uriString(uriTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,16 +69,12 @@ public final class BaseUrlUriBuilderFactory implements UriBuilderFactory {
|
||||
|
||||
@Override
|
||||
public URI expand(String uriTemplate, Map<String, ?> uriVariables) {
|
||||
return createDelegate().expand(uriTemplate, uriVariables);
|
||||
return this.baseUrl.getUriBuilderFactory().expand(uriTemplate, uriVariables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI expand(String uriTemplate, @Nullable Object... uriVariables) {
|
||||
return createDelegate().expand(uriTemplate, uriVariables);
|
||||
}
|
||||
|
||||
private UriBuilderFactory createDelegate() {
|
||||
return this.baseUrl.getUriBuilderFactory();
|
||||
return this.baseUrl.getUriBuilderFactory().expand(uriTemplate, uriVariables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+26
-43
@@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
|
||||
@@ -30,38 +31,53 @@ import org.springframework.web.util.UriBuilderFactory;
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public interface BaseUrl {
|
||||
public final class BaseUrl {
|
||||
|
||||
/**
|
||||
* Default base URL suitable for mock environments.
|
||||
* {@link BaseUrl} that resolves to {@code http://localhost}.
|
||||
*/
|
||||
BaseUrl DEFAULT = BaseUrl.of("http://localhost");
|
||||
public static final BaseUrl LOCALHOST = BaseUrl.of("http://localhost");
|
||||
|
||||
private final boolean https;
|
||||
|
||||
private final Supplier<String> resolver;
|
||||
|
||||
private BaseUrl(boolean https, Supplier<String> resolver) {
|
||||
this.https = https;
|
||||
this.resolver = SingletonSupplier.of(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the URL will ultimately resolve to an HTTPS address.
|
||||
* @return if the URL is HTTPS
|
||||
*/
|
||||
boolean isHttps();
|
||||
public boolean isHttps() {
|
||||
return this.https;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link UriBuilderFactory} that applies the base URL.
|
||||
* @return a {@link UriBuilderFactory}
|
||||
*/
|
||||
UriBuilderFactory getUriBuilderFactory();
|
||||
public UriBuilderFactory getUriBuilderFactory() {
|
||||
return new DefaultUriBuilderFactory(this.resolver.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance that applies the given {@code path}.
|
||||
* @param path a path to append
|
||||
* @return a new instance with the path added
|
||||
*/
|
||||
BaseUrl withPath(String path);
|
||||
public BaseUrl withPath(String path) {
|
||||
return new BaseUrl(this.https, () -> this.resolver.get() + path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link BaseUrl}.
|
||||
* @param url the URL to use
|
||||
* @return a new {@link BaseUrl} instance
|
||||
*/
|
||||
static BaseUrl of(String url) {
|
||||
public static BaseUrl of(String url) {
|
||||
Assert.notNull(url, "'url' must not be null");
|
||||
return of(StringUtils.startsWithIgnoreCase(url, "https"), () -> url);
|
||||
}
|
||||
@@ -72,42 +88,9 @@ public interface BaseUrl {
|
||||
* @param resolver the resolver used to supply the actual URL
|
||||
* @return a new {@link BaseUrl} instance
|
||||
*/
|
||||
static BaseUrl of(boolean https, Supplier<String> resolver) {
|
||||
return new DefaultBaseUrl(https, resolver);
|
||||
}
|
||||
|
||||
final class DefaultBaseUrl implements BaseUrl {
|
||||
|
||||
private final boolean https;
|
||||
|
||||
private final Supplier<String> resolver;
|
||||
|
||||
private DefaultBaseUrl(boolean https, Supplier<String> resolver) {
|
||||
Assert.notNull(resolver, "'resolver' must not be null");
|
||||
this.https = https;
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHttps() {
|
||||
return this.https;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriBuilderFactory getUriBuilderFactory() {
|
||||
return new DefaultUriBuilderFactory(resolve());
|
||||
}
|
||||
|
||||
String resolve() {
|
||||
return this.resolver.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseUrl withPath(String path) {
|
||||
Supplier<String> updatedResolver = () -> this.resolver.get() + path;
|
||||
return new DefaultBaseUrl(this.https, updatedResolver);
|
||||
}
|
||||
|
||||
public static BaseUrl of(boolean https, Supplier<String> resolver) {
|
||||
Assert.notNull(resolver, "'resolver' must not be null");
|
||||
return new BaseUrl(https, resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-9
@@ -47,14 +47,6 @@ public class BaseUrlProviders {
|
||||
this.providers = providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provided {@link BaseUrl} or {@link BaseUrl#DEFAULT}.
|
||||
* @return the base URL
|
||||
*/
|
||||
public BaseUrl getBaseUrlOrDefault() {
|
||||
return getBaseUrl(BaseUrl.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provided {@link BaseUrl} or {@code null}.
|
||||
* @return the base URL or {@code null}
|
||||
@@ -75,7 +67,6 @@ public class BaseUrlProviders {
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(fallback);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-5
@@ -33,11 +33,6 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
class BaseUrlProvidersTests {
|
||||
|
||||
@Test
|
||||
void getBaseUrlOrDefaultWhenNoProvidedBaseUrlReturnsDefault() {
|
||||
assertThat(new BaseUrlProviders(Collections.emptyList()).getBaseUrlOrDefault()).isSameAs(BaseUrl.DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBaseUrlWhenNoProvidedBaseUrlReturnsNull() {
|
||||
assertThat(new BaseUrlProviders(Collections.emptyList()).getBaseUrl()).isNull();
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ class BaseUrlTests {
|
||||
assertThat(atomicInteger.get()).isZero();
|
||||
assertThat(baseUrl.isHttps()).isTrue();
|
||||
assertThat(resolve(baseUrl, "")).isEqualTo("1");
|
||||
assertThat(resolve(baseUrl, "")).isEqualTo("2");
|
||||
assertThat(resolve(baseUrl, "")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,7 +94,7 @@ class BaseUrlTests {
|
||||
BaseUrl baseUrl = BaseUrl.of(true, () -> "https://example.com/" + atomicInteger.incrementAndGet());
|
||||
assertThat(resolve(baseUrl.withPath("/context"), "")).isEqualTo("https://example.com/1/context");
|
||||
assertThat(resolve(baseUrl.withPath("/context").withPath("/test"), "/path"))
|
||||
.isEqualTo("https://example.com/2/context/test/path");
|
||||
.isEqualTo("https://example.com/1/context/test/path");
|
||||
}
|
||||
|
||||
private String resolve(BaseUrl baseUrl, String path) {
|
||||
|
||||
+3
-4
@@ -60,10 +60,9 @@ public final class HttpGraphQlTesterAutoConfiguration {
|
||||
private WebTestClient configureGraphQlWebTestClient(WebTestClient webTestClient, @Nullable BaseUrl baseUrl,
|
||||
String graphQlPath) {
|
||||
WebTestClient.Builder builder = webTestClient.mutate();
|
||||
if (baseUrl != null) {
|
||||
return builder.uriBuilderFactory(BaseUrlUriBuilderFactory.get(baseUrl.withPath(graphQlPath))).build();
|
||||
}
|
||||
return builder.baseUrl(graphQlPath).build();
|
||||
return (baseUrl != null)
|
||||
? builder.uriBuilderFactory(BaseUrlUriBuilderFactory.get(baseUrl.withPath(graphQlPath))).build()
|
||||
: builder.baseUrl(graphQlPath).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-3
@@ -46,10 +46,9 @@ public final class TestRestTemplateAutoConfiguration {
|
||||
TestRestTemplate testRestTemplate(ObjectProvider<RestTemplateBuilder> builderProvider,
|
||||
ApplicationContext applicationContext) {
|
||||
RestTemplateBuilder builder = builderProvider.getIfAvailable(RestTemplateBuilder::new);
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrlOrDefault();
|
||||
boolean sslEnabled = baseUrl != null && baseUrl.isHttps();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrl(BaseUrl.LOCALHOST);
|
||||
TestRestTemplate template = new TestRestTemplate(builder, null, null,
|
||||
sslEnabled ? SSL_OPTIONS : DEFAULT_OPTIONS);
|
||||
baseUrl.isHttps() ? SSL_OPTIONS : DEFAULT_OPTIONS);
|
||||
template.setUriTemplateHandler(BaseUrlUriBuilderFactory.get(baseUrl));
|
||||
return template;
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public final class MockMvcWebClientAutoConfiguration {
|
||||
@ConditionalOnMissingBean({ WebClient.class, MockMvcWebClientBuilder.class })
|
||||
@ConditionalOnBean(MockMvc.class)
|
||||
MockMvcWebClientBuilder mockMvcWebClientBuilder(MockMvc mockMvc, ApplicationContext applicationContext) {
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrl(BaseUrl.LOCALHOST);
|
||||
return MockMvcWebClientBuilder.mockMvcSetup(mockMvc).withDelegate(new BaseUrlWebClient(baseUrl));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public final class MockMvcWebDriverAutoConfiguration {
|
||||
@ConditionalOnMissingBean({ WebDriver.class, MockMvcHtmlUnitDriverBuilder.class })
|
||||
@ConditionalOnBean(MockMvc.class)
|
||||
MockMvcHtmlUnitDriverBuilder mockMvcHtmlUnitDriverBuilder(MockMvc mockMvc, ApplicationContext applicationContext) {
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(applicationContext).getBaseUrl(BaseUrl.LOCALHOST);
|
||||
MockMvcHtmlUnitDriverBuilder builder = MockMvcHtmlUnitDriverBuilder.mockMvcSetup(mockMvc)
|
||||
.withDelegate(new BaseUrlWebConnectionHtmlUnitDriver(baseUrl, BrowserVersion.CHROME));
|
||||
return builder;
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ abstract class AbstractSampleActuatorCustomSecurityTests {
|
||||
}
|
||||
|
||||
private TestRestTemplate configure(TestRestTemplate restTemplate) {
|
||||
BaseUrl baseUrl = new BaseUrlProviders(getApplicationContext()).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(getApplicationContext()).getBaseUrl();
|
||||
restTemplate.setUriTemplateHandler(BaseUrlUriBuilderFactory.get(baseUrl));
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class CorsSampleActuatorApplicationTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
RestTemplateBuilder builder = new RestTemplateBuilder();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrl();
|
||||
builder = builder.uriTemplateHandler(BaseUrlUriBuilderFactory.get(baseUrl));
|
||||
this.testRestTemplate = new TestRestTemplate(builder);
|
||||
}
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class SampleActuatorExtensionApplicationTests {
|
||||
void healthExtensionWithAuthHeader() {
|
||||
TestRestTemplate restTemplate = new TestRestTemplate(
|
||||
this.restTemplateBuilder.defaultHeader("Authorization", "Bearer secret"));
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrl();
|
||||
restTemplate.setUriTemplateHandler(BaseUrlUriBuilderFactory.get(baseUrl));
|
||||
ResponseEntity<Map> entity = restTemplate.getForEntity("/myextension/health", Map.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class CorsSampleActuatorApplicationTests {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
RestTemplateBuilder builder = new RestTemplateBuilder();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrlOrDefault();
|
||||
BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrl();
|
||||
builder = builder.uriTemplateHandler(BaseUrlUriBuilderFactory.get(baseUrl));
|
||||
this.testRestTemplate = new TestRestTemplate(builder);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user