From 3e4da3cc3761d0e28a22e8d370ce76d3132ca84b Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 27 Feb 2018 12:52:37 -0800 Subject: [PATCH] Polish --- ...earchHealthIndicatorAutoConfiguration.java | 2 +- ...sReactiveHealthIndicatorConfiguration.java | 2 +- .../data/redis/RedisAutoConfiguration.java | 2 +- .../bind/AppSystemPropertiesTests.java | 42 +++-- .../client/SampleWebClientConfiguration.java | 5 +- .../docs/web/client/SampleWebClientTests.java | 4 +- ...plicationPluginActionIntegrationTests.java | 2 +- .../properties/bind/BindConverter.java | 176 +++++++++--------- .../JettyServletWebServerFactoryTests.java | 38 ++-- 9 files changed, 139 insertions(+), 134 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorAutoConfiguration.java index 20bcd7be086d..0c382594b013 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/redis/RedisReactiveHealthIndicatorConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/redis/RedisReactiveHealthIndicatorConfiguration.java index d2a23b46fa0e..291955a68e1b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/redis/RedisReactiveHealthIndicatorConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/redis/RedisReactiveHealthIndicatorConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java index 05fd4b72fda2..2c9a369853cd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java index 76730e3998b5..4264c370e2fb 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java @@ -41,36 +41,46 @@ public class AppSystemPropertiesTests { @Test public void bindWithDefaultUnit() { - this.contextRunner.withPropertyValues("app.system.session-timeout=40", - "app.system.read-timeout=5000").run(assertBinding(p -> { - assertThat(p.getSessionTimeout()).isEqualTo(Duration.ofSeconds(40)); - assertThat(p.getReadTimeout()).isEqualTo(Duration.ofMillis(5000)); - })); + this.contextRunner + .withPropertyValues("app.system.session-timeout=40", + "app.system.read-timeout=5000") + .run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()) + .isEqualTo(Duration.ofSeconds(40)); + assertThat(properties.getReadTimeout()) + .isEqualTo(Duration.ofMillis(5000)); + })); } @Test public void bindWithExplicitUnit() { this.contextRunner.withPropertyValues("app.system.session-timeout=1h", - "app.system.read-timeout=5s").run(assertBinding(p -> { - assertThat(p.getSessionTimeout()).isEqualTo(Duration.ofMinutes(60)); - assertThat(p.getReadTimeout()).isEqualTo(Duration.ofMillis(5000)); - })); + "app.system.read-timeout=5s").run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()) + .isEqualTo(Duration.ofMinutes(60)); + assertThat(properties.getReadTimeout()) + .isEqualTo(Duration.ofMillis(5000)); + })); } @Test public void bindWithIso8601Format() { - this.contextRunner.withPropertyValues("app.system.session-timeout=PT15S", - "app.system.read-timeout=PT0.5S").run(assertBinding(p -> { - assertThat(p.getSessionTimeout()).isEqualTo(Duration.ofSeconds(15)); - assertThat(p.getReadTimeout()).isEqualTo(Duration.ofMillis(500)); - })); + this.contextRunner + .withPropertyValues("app.system.session-timeout=PT15S", + "app.system.read-timeout=PT0.5S") + .run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()) + .isEqualTo(Duration.ofSeconds(15)); + assertThat(properties.getReadTimeout()) + .isEqualTo(Duration.ofMillis(500)); + })); } private ContextConsumer assertBinding( - Consumer appSystemProperties) { + Consumer properties) { return (context) -> { assertThat(context).hasSingleBean(AppSystemProperties.class); - appSystemProperties.accept(context.getBean(AppSystemProperties.class)); + properties.accept(context.getBean(AppSystemProperties.class)); }; } diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientConfiguration.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientConfiguration.java index 6e670b44bd2d..33f83f815684 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientConfiguration.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientConfiguration.java @@ -35,11 +35,10 @@ */ @SpringBootConfiguration @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, - JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) + DispatcherServletAutoConfiguration.class, JacksonAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class }) class SampleWebClientConfiguration { - @RestController private static class ExampleController { diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientTests.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientTests.java index 7782bea29471..ae74a85406cd 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientTests.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/web/client/SampleWebClientTests.java @@ -56,9 +56,7 @@ static class Config { @Bean public RestTemplateBuilder restTemplateBuilder() { - return new RestTemplateBuilder() - .setConnectTimeout(1000) - .setReadTimeout(1000); + return new RestTemplateBuilder().setConnectTimeout(1000).setReadTimeout(1000); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/ApplicationPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/ApplicationPluginActionIntegrationTests.java index d6b244752b1c..0870b3ca29ce 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/ApplicationPluginActionIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/ApplicationPluginActionIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindConverter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindConverter.java index a876135eb13a..8d1333a99622 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindConverter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindConverter.java @@ -26,8 +26,6 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; import org.springframework.beans.BeanUtils; import org.springframework.beans.PropertyEditorRegistry; @@ -35,6 +33,7 @@ import org.springframework.beans.propertyeditors.FileEditor; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.core.ResolvableType; +import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; @@ -62,16 +61,27 @@ class BindConverter { BindConverter(ConversionService conversionService, Consumer propertyEditorInitializer) { Assert.notNull(conversionService, "ConversionService must not be null"); - this.conversionService = new CompositeConversionService( - new TypeConverterConversionService(propertyEditorInitializer), - conversionService); + List conversionServices = getConversionServices( + conversionService, propertyEditorInitializer); + this.conversionService = new CompositeConversionService(conversionServices); + } + + private List getConversionServices( + ConversionService conversionService, + Consumer propertyEditorInitializer) { + List services = new ArrayList<>(); + services.add(new TypeConverterConversionService(propertyEditorInitializer)); + services.add(conversionService); + if (!(conversionService instanceof ApplicationConversionService)) { + services.add(ApplicationConversionService.getSharedInstance()); + } + return services; } public boolean canConvert(Object value, ResolvableType type, Annotation... annotations) { - TypeDescriptor sourceType = TypeDescriptor.forObject(value); - TypeDescriptor targetType = new ResolvableTypeDescriptor(type, annotations); - return this.conversionService.canConvert(sourceType, targetType); + return this.conversionService.canConvert(TypeDescriptor.forObject(value), + new ResolvableTypeDescriptor(type, annotations)); } public T convert(Object result, Bindable target) { @@ -83,9 +93,8 @@ public T convert(Object value, ResolvableType type, Annotation... annotation if (value == null) { return null; } - TypeDescriptor sourceType = TypeDescriptor.forObject(value); - TypeDescriptor targetType = new ResolvableTypeDescriptor(type, annotations); - return (T) this.conversionService.convert(value, sourceType, targetType); + return (T) this.conversionService.convert(value, TypeDescriptor.forObject(value), + new ResolvableTypeDescriptor(type, annotations)); } /** @@ -100,6 +109,62 @@ private static class ResolvableTypeDescriptor extends TypeDescriptor { } + /** + * Composite {@link ConversionService} used to call multiple services + */ + static class CompositeConversionService implements ConversionService { + + private final List delegates; + + CompositeConversionService(List delegates) { + this.delegates = delegates; + } + + @Override + public boolean canConvert(Class sourceType, Class targetType) { + Assert.notNull(targetType, "Target type to convert to cannot be null"); + return canConvert( + (sourceType != null ? TypeDescriptor.valueOf(sourceType) : null), + TypeDescriptor.valueOf(targetType)); + } + + @Override + public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { + for (ConversionService service : this.delegates) { + if (service.canConvert(sourceType, targetType)) { + return true; + } + } + return false; + } + + @Override + @SuppressWarnings("unchecked") + public T convert(Object source, Class targetType) { + Assert.notNull(targetType, "Target type to convert to cannot be null"); + return (T) convert(source, TypeDescriptor.forObject(source), + TypeDescriptor.valueOf(targetType)); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, + TypeDescriptor targetType) { + for (int i = 0; i < this.delegates.size() - 1; i++) { + try { + ConversionService delegate = this.delegates.get(i); + if (delegate.canConvert(sourceType, targetType)) { + return delegate.convert(source, sourceType, targetType); + } + } + catch (ConversionException ex) { + } + } + return this.delegates.get(this.delegates.size() - 1).convert(source, + sourceType, targetType); + } + + } + /** * A {@link ConversionService} implementation that delegates to a * {@link SimpleTypeConverter}. Allows {@link PropertyEditor} based conversion for @@ -107,15 +172,18 @@ private static class ResolvableTypeDescriptor extends TypeDescriptor { */ private static class TypeConverterConversionService extends GenericConversionService { - private SimpleTypeConverter typeConverter; - TypeConverterConversionService(Consumer initializer) { - this.typeConverter = new SimpleTypeConverter(); + addConverter(new TypeConverterConverter(createTypeConverter(initializer))); + ApplicationConversionService.addDelimitedStringConverters(this); + } + + private SimpleTypeConverter createTypeConverter( + Consumer initializer) { + SimpleTypeConverter typeConverter = new SimpleTypeConverter(); if (initializer != null) { - initializer.accept(this.typeConverter); + initializer.accept(typeConverter); } - addConverter(new TypeConverterConverter(this.typeConverter)); - ApplicationConversionService.addDelimitedStringConverters(this); + return typeConverter; } @Override @@ -135,9 +203,9 @@ public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) */ private static class TypeConverterConverter implements ConditionalGenericConverter { - private SimpleTypeConverter typeConverter; + private final SimpleTypeConverter typeConverter; - TypeConverterConverter(SimpleTypeConverter typeConverter) { + public TypeConverterConverter(SimpleTypeConverter typeConverter) { this.typeConverter = typeConverter; } @@ -154,18 +222,20 @@ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - return this.typeConverter.convertIfNecessary(source, targetType.getType()); + SimpleTypeConverter typeConverter = this.typeConverter; + return typeConverter.convertIfNecessary(source, targetType.getType()); } private PropertyEditor getPropertyEditor(Class type) { + SimpleTypeConverter typeConverter = this.typeConverter; if (type == null || type == Object.class || Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type)) { return null; } - PropertyEditor editor = this.typeConverter.getDefaultEditor(type); + PropertyEditor editor = typeConverter.getDefaultEditor(type); if (editor == null) { - editor = this.typeConverter.findCustomEditor(type, null); + editor = typeConverter.findCustomEditor(type, null); } if (editor == null && String.class != type) { editor = BeanUtils.findEditorByConvention(type); @@ -178,66 +248,4 @@ private PropertyEditor getPropertyEditor(Class type) { } - private static final class CompositeConversionService implements ConversionService { - - private final List delegates; - - private CompositeConversionService( - TypeConverterConversionService typeConverterConversionService, - ConversionService conversionService) { - List delegates = new ArrayList(); - delegates.add(typeConverterConversionService); - delegates.add(conversionService); - if (!(conversionService instanceof ApplicationConversionService)) { - delegates.add(ApplicationConversionService.getSharedInstance()); - } - this.delegates = delegates; - } - - @Override - public boolean canConvert(Class sourceType, Class targetType) { - return canConvert((delegate) -> delegate.canConvert(sourceType, targetType)); - } - - @Override - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - return canConvert((delegate) -> delegate.canConvert(sourceType, targetType)); - } - - private boolean canConvert(Predicate canConvert) { - for (ConversionService delegate : this.delegates) { - if (canConvert.test(delegate)) { - return true; - } - } - return false; - } - - @Override - public T convert(Object source, Class targetType) { - Class sourceType = source.getClass(); - return convert((delegate) -> delegate.canConvert(sourceType, targetType), - (delegate) -> delegate.convert(source, targetType)); - } - - @Override - public Object convert(Object source, TypeDescriptor sourceType, - TypeDescriptor targetType) { - return convert((delegate) -> delegate.canConvert(sourceType, targetType), - (delegate) -> delegate.convert(source, sourceType, targetType)); - } - - public T convert(Predicate canConvert, - Function convert) { - for (int i = 0; i < this.delegates.size() - 1; i++) { - ConversionService delegate = this.delegates.get(i); - if (canConvert.test(delegate)) { - return convert.apply(delegate); - } - } - return convert.apply(this.delegates.get(this.delegates.size() - 1)); - } - - } - } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java index 42a0800c02de..50ba1f8a4838 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java @@ -157,52 +157,42 @@ protected void addConnector(int port, AbstractServletWebServerFactory factory) { @Test public void sslEnabledMultiProtocolsConfiguration() { - Ssl ssl = new Ssl(); - ssl.setKeyStore("src/test/resources/test.jks"); - ssl.setKeyStorePassword("secret"); - ssl.setKeyPassword("password"); - ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); - ssl.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1.2" }); - JettyServletWebServerFactory factory = getFactory(); - factory.setSsl(ssl); - + factory.setSsl(getSslSettings("TLSv1.1", "TLSv1.2")); this.webServer = factory.getWebServer(); this.webServer.start(); - JettyWebServer jettyWebServer = (JettyWebServer) this.webServer; ServerConnector connector = (ServerConnector) jettyWebServer.getServer() .getConnectors()[0]; SslConnectionFactory connectionFactory = connector .getConnectionFactory(SslConnectionFactory.class); - assertThat(connectionFactory.getSslContextFactory().getIncludeProtocols()) - .isEqualTo(new String[] { "TLSv1.1", "TLSv1.2" }); + .containsExactly("TLSv1.1", "TLSv1.2"); } @Test public void sslEnabledProtocolsConfiguration() { - Ssl ssl = new Ssl(); - ssl.setKeyStore("src/test/resources/test.jks"); - ssl.setKeyStorePassword("secret"); - ssl.setKeyPassword("password"); - ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); - ssl.setEnabledProtocols(new String[] { "TLSv1.1" }); - JettyServletWebServerFactory factory = getFactory(); - factory.setSsl(ssl); - + factory.setSsl(getSslSettings("TLSv1.1")); this.webServer = factory.getWebServer(); this.webServer.start(); - JettyWebServer jettyWebServer = (JettyWebServer) this.webServer; ServerConnector connector = (ServerConnector) jettyWebServer.getServer() .getConnectors()[0]; SslConnectionFactory connectionFactory = connector .getConnectionFactory(SslConnectionFactory.class); - assertThat(connectionFactory.getSslContextFactory().getIncludeProtocols()) - .isEqualTo(new String[] { "TLSv1.1" }); + .containsExactly("TLSv1.1"); + } + + private Ssl getSslSettings(String... enabledProtocols) { + Ssl ssl = new Ssl(); + ssl.setKeyStore("src/test/resources/test.jks"); + ssl.setKeyStorePassword("secret"); + ssl.setKeyPassword("password"); + ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" }); + ssl.setEnabledProtocols(enabledProtocols); + return ssl; } private void assertTimeout(JettyServletWebServerFactory factory, int expected) {