Merge branch '2.2.x'

This commit is contained in:
spencergibb
2020-06-17 17:16:50 -04:00
8 changed files with 95 additions and 49 deletions

View File

@@ -41,11 +41,9 @@
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
@@ -57,7 +55,6 @@
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
<plugin>

View File

@@ -31,7 +31,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.cloud.client.ServiceInstance;
@@ -73,6 +72,8 @@ public class EurekaConfigServerBootstrapConfiguration {
@ConditionalOnMissingBean(EurekaHttpClient.class)
@ConditionalOnClass(
name = "org.springframework.web.reactive.function.client.WebClient")
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled",
havingValue = "true")
public WebClientEurekaHttpClient configDiscoveryWebClientEurekaHttpClient(
EurekaClientConfigBean config) {
return (WebClientEurekaHttpClient) new WebClientTransportClientFactory()
@@ -81,7 +82,8 @@ public class EurekaConfigServerBootstrapConfiguration {
@Bean
@ConditionalOnMissingBean(EurekaHttpClient.class)
@ConditionalOnMissingClass("org.springframework.web.reactive.function.client.WebClient")
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled",
matchIfMissing = true, havingValue = "false")
public RestTemplateEurekaHttpClient configDiscoveryRestTemplateEurekaHttpClient(
EurekaClientConfigBean config) {
return (RestTemplateEurekaHttpClient) new RestTemplateTransportClientFactory()

View File

@@ -89,8 +89,7 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
}
private void setExchangeStrategies(WebClient.Builder builder) {
ObjectMapper objectMapper = mappingJacksonHttpMessageConverter()
.getObjectMapper();
ObjectMapper objectMapper = objectMapper();
ExchangeStrategies strategies = ExchangeStrategies.builder()
.codecs(clientDefaultCodecsConfigurer -> {
clientDefaultCodecsConfigurer.defaultCodecs()
@@ -105,11 +104,11 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
}
private void skipHttp400Error(WebClient.Builder builder) {
builder.filter(Http4xxErrorExchangeFilterFunction());
builder.filter(http4XxErrorExchangeFilterFunction());
}
// Skip over 4xx http errors
private ExchangeFilterFunction Http4xxErrorExchangeFilterFunction() {
private ExchangeFilterFunction http4XxErrorExchangeFilterFunction() {
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
// literally 400 pass the tests, not 4xxClientError
if (clientResponse.statusCode().value() == 400) {
@@ -132,54 +131,48 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
* {@link DeserializationFeature#UNWRAP_ROOT_VALUE}.
* {@link PropertyNamingStrategy.SnakeCaseStrategy} is applied to the underlying
* {@link ObjectMapper}.
* @deprecated to be removed.
* @return a {@link MappingJackson2HttpMessageConverter} object
*/
@Deprecated
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE));
SimpleModule jsonModule = new SimpleModule();
jsonModule.setSerializerModifier(createJsonSerializerModifier()); // keyFormatter,
// compact));
converter.getObjectMapper().registerModule(jsonModule);
converter.getObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true);
converter.getObjectMapper().configure(DeserializationFeature.UNWRAP_ROOT_VALUE,
true);
converter.getObjectMapper().addMixIn(Applications.class,
ApplicationsJsonMixIn.class);
converter.getObjectMapper().addMixIn(InstanceInfo.class,
InstanceInfoJsonMixIn.class);
// converter.getObjectMapper().addMixIn(DataCenterInfo.class,
// DataCenterInfoXmlMixIn.class);
// converter.getObjectMapper().addMixIn(InstanceInfo.PortWrapper.class,
// PortWrapperXmlMixIn.class);
// converter.getObjectMapper().addMixIn(Application.class,
// ApplicationXmlMixIn.class);
// converter.getObjectMapper().addMixIn(Applications.class,
// ApplicationsXmlMixIn.class);
converter.setObjectMapper(objectMapper());
return converter;
}
public static BeanSerializerModifier createJsonSerializerModifier() { // final
// KeyFormatter
// keyFormatter,
// final
// boolean
// compactMode)
// {
/**
* Provides the serialization configurations required by the Eureka Server. JSON
* content exchanged with eureka requires a root node matching the entity being
* serialized or deserialized. Achieved with
* {@link SerializationFeature#WRAP_ROOT_VALUE} and
* {@link DeserializationFeature#UNWRAP_ROOT_VALUE}.
* {@link PropertyNamingStrategy.SnakeCaseStrategy} is applied to the underlying
* {@link ObjectMapper}.
* @return a {@link ObjectMapper} object
*/
private ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
SimpleModule jsonModule = new SimpleModule();
jsonModule.setSerializerModifier(createJsonSerializerModifier());
objectMapper.registerModule(jsonModule);
objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
objectMapper.addMixIn(Applications.class, ApplicationsJsonMixIn.class);
objectMapper.addMixIn(InstanceInfo.class, InstanceInfoJsonMixIn.class);
return objectMapper;
}
@Deprecated // reduce visibility in future release
public static BeanSerializerModifier createJsonSerializerModifier() {
return new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config,
BeanDescription beanDesc, JsonSerializer<?> serializer) {
/*
* if (beanDesc.getBeanClass().isAssignableFrom(Applications.class)) {
* return new ApplicationsJsonBeanSerializer((BeanSerializerBase)
* serializer, keyFormatter); }
*/
if (beanDesc.getBeanClass().isAssignableFrom(InstanceInfo.class)) {
return new InstanceInfoJsonBeanSerializer(
(BeanSerializerBase) serializer, false);

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.eureka.loadbalancer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfigurationRegistrar;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
@@ -34,9 +35,10 @@ import org.springframework.core.env.Environment;
* @see EurekaLoadBalancerClientConfiguration
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(EurekaLoadBalancerProperties.class)
@EnableConfigurationProperties
@ConditionalOnClass(LoadBalancerClientConfigurationRegistrar.class)
@LoadBalancerClients(defaultConfiguration = EurekaLoadBalancerClientConfiguration.class)
@ConditionalOnProperty(name = "eureka.client.enabled", matchIfMissing = true)
public class LoadBalancerEurekaAutoConfiguration {
/**

View File

@@ -123,7 +123,7 @@ public class DefaultManagementMetadataProvider implements ManagementMetadataProv
String refinedContextPath = '/'
+ StringUtils.trimLeadingCharacter(contextPath, '/');
URL base = new URL(scheme, hostname, port, refinedContextPath);
String refinedStatusPath = StringUtils.trimLeadingCharacter(statusPath, '/');
String refinedStatusPath = refinedStatusPath(statusPath, contextPath);
return new URL(base, refinedStatusPath).toString();
}
catch (MalformedURLException e) {
@@ -133,6 +133,13 @@ public class DefaultManagementMetadataProvider implements ManagementMetadataProv
}
}
private String refinedStatusPath(String statusPath, String contextPath) {
if (statusPath.startsWith(contextPath) && !"/".equals(contextPath)) {
statusPath = StringUtils.replace(statusPath, contextPath, "");
}
return StringUtils.trimLeadingCharacter(statusPath, '/');
}
private String getErrorMessage(String scheme, String hostname, int port,
String contextPath, String statusPath) {
return String.format(

View File

@@ -325,6 +325,20 @@ public class EurekaClientAutoConfigurationTests {
.as("Wrong health check: " + instance.getHealthCheckUrl()).isTrue();
}
@Test
public void healthCheckUrlPathWithServerPortAndContextPathKebobCase() {
TestPropertyValues.of("server.port=8989",
"server.servlet.context-path=/servletContextPath",
"eureka.instance.health-check-url-path=${server.servlet.context-path:}/myHealthCheck")
.applyTo(this.context);
setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context
.getBean(EurekaInstanceConfigBean.class);
assertThat(instance.getHealthCheckUrl())
.as("Wrong health check: " + instance.getHealthCheckUrl())
.endsWith(":8989/servletContextPath/myHealthCheck");
}
@Test
public void statusPageUrlPathAndManagementPortKabobCase() {
TestPropertyValues

View File

@@ -22,6 +22,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.WebClientEurekaHttpClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,7 +37,8 @@ public class EurekaConfigServerBootstrapConfigurationWebClientTests {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations
.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.withPropertyValues("spring.cloud.config.discovery.enabled=true",
"eureka.client.webclient.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).hasSingleBean(WebClientEurekaHttpClient.class);
@@ -45,4 +47,19 @@ public class EurekaConfigServerBootstrapConfigurationWebClientTests {
});
}
@Test
public void properBeansCreatedWhenEnabledWebClientDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations
.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context)
.hasSingleBean(ConfigServerInstanceProvider.Function.class);
});
}
}

View File

@@ -18,6 +18,8 @@ package org.springframework.cloud.netflix.eureka.loadbalancer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig;
@@ -72,4 +74,16 @@ class EurekaLoadBalancerClientConfigurationTests {
assertThat(zoneConfig.getZone()).isEqualTo("is.a.test.com");
}
@Test
public void disabledViaProperty() {
new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(LoadBalancerEurekaAutoConfiguration.class))
.withPropertyValues("eureka.client.enabled=false").run(context -> {
assertThat(context)
.doesNotHaveBean(EurekaLoadBalancerProperties.class);
assertThat(context).doesNotHaveBean(LoadBalancerZoneConfig.class);
});
}
}