Commit 3e4da3cc authored by Phillip Webb's avatar Phillip Webb

Polish

parent c7ed5c3d
/*
* 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.
......
/*
* 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.
......
/*
* 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.
......
......@@ -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<AssertableApplicationContext> assertBinding(
Consumer<AppSystemProperties> appSystemProperties) {
Consumer<AppSystemProperties> properties) {
return (context) -> {
assertThat(context).hasSingleBean(AppSystemProperties.class);
appSystemProperties.accept(context.getBean(AppSystemProperties.class));
properties.accept(context.getBean(AppSystemProperties.class));
};
}
......
......@@ -35,11 +35,10 @@ import org.springframework.web.bind.annotation.RestController;
*/
@SpringBootConfiguration
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class,
DispatcherServletAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class })
DispatcherServletAutoConfiguration.class, JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class })
class SampleWebClientConfiguration {
@RestController
private static class ExampleController {
......
......@@ -56,9 +56,7 @@ public class SampleWebClientTests {
@Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder()
.setConnectTimeout(1000)
.setReadTimeout(1000);
return new RestTemplateBuilder().setConnectTimeout(1000).setReadTimeout(1000);
}
}
......
/*
* 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.
......
......@@ -26,8 +26,6 @@ import java.util.List;
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.SimpleTypeConverter;
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<PropertyEditorRegistry> propertyEditorInitializer) {
Assert.notNull(conversionService, "ConversionService must not be null");
this.conversionService = new CompositeConversionService(
new TypeConverterConversionService(propertyEditorInitializer),
conversionService);
List<ConversionService> conversionServices = getConversionServices(
conversionService, propertyEditorInitializer);
this.conversionService = new CompositeConversionService(conversionServices);
}
private List<ConversionService> getConversionServices(
ConversionService conversionService,
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
List<ConversionService> 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> T convert(Object result, Bindable<T> target) {
......@@ -83,9 +93,8 @@ class BindConverter {
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 @@ class BindConverter {
}
/**
* Composite {@link ConversionService} used to call multiple services
*/
static class CompositeConversionService implements ConversionService {
private final List<ConversionService> delegates;
CompositeConversionService(List<ConversionService> 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> T convert(Object source, Class<T> 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 @@ class BindConverter {
*/
private static class TypeConverterConversionService extends GenericConversionService {
private SimpleTypeConverter typeConverter;
TypeConverterConversionService(Consumer<PropertyEditorRegistry> initializer) {
this.typeConverter = new SimpleTypeConverter();
addConverter(new TypeConverterConverter(createTypeConverter(initializer)));
ApplicationConversionService.addDelimitedStringConverters(this);
}
private SimpleTypeConverter createTypeConverter(
Consumer<PropertyEditorRegistry> 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 @@ class BindConverter {
*/
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 @@ class BindConverter {
@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 @@ class BindConverter {
}
private static final class CompositeConversionService implements ConversionService {
private final List<ConversionService> delegates;
private CompositeConversionService(
TypeConverterConversionService typeConverterConversionService,
ConversionService conversionService) {
List<ConversionService> delegates = new ArrayList<ConversionService>();
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<ConversionService> canConvert) {
for (ConversionService delegate : this.delegates) {
if (canConvert.test(delegate)) {
return true;
}
}
return false;
}
@Override
public <T> T convert(Object source, Class<T> 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> T convert(Predicate<ConversionService> canConvert,
Function<ConversionService, T> 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));
}
}
}
......@@ -157,52 +157,42 @@ public class JettyServletWebServerFactoryTests
@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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment