Commit 0d0e5eb5 authored by Phillip Webb's avatar Phillip Webb

Merge branch '1.1.x'

parents 55a84c7b 336b96b8
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure; package org.springframework.boot.actuate.autoconfigure;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -36,6 +37,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; ...@@ -36,6 +37,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.web.ErrorAttributes; import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
...@@ -75,13 +77,23 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -75,13 +77,23 @@ public class EndpointWebMvcChildContextConfiguration {
// instances get their callback very early in the context lifecycle. // instances get their callback very early in the context lifecycle.
private ManagementServerProperties managementServerProperties; private ManagementServerProperties managementServerProperties;
private ServerProperties server;
@Override @Override
public void customize(ConfigurableEmbeddedServletContainer container) { public void customize(ConfigurableEmbeddedServletContainer container) {
if (this.managementServerProperties == null) { if (this.managementServerProperties == null) {
this.managementServerProperties = BeanFactoryUtils this.managementServerProperties = BeanFactoryUtils
.beanOfTypeIncludingAncestors(this.beanFactory, .beanOfTypeIncludingAncestors(this.beanFactory,
ManagementServerProperties.class); ManagementServerProperties.class);
this.server = BeanFactoryUtils
.beanOfTypeIncludingAncestors(this.beanFactory,
ServerProperties.class);
} }
// Customize as per the parent context first (so e.g. the access logs go to the same place)
server.customize(container);
// Then reset the error pages
container.setErrorPages(Collections.<ErrorPage>emptySet());
// and add the management-specific bits
container.setPort(this.managementServerProperties.getPort()); container.setPort(this.managementServerProperties.getPort());
container.setAddress(this.managementServerProperties.getAddress()); container.setAddress(this.managementServerProperties.getAddress());
container.setContextPath(this.managementServerProperties.getContextPath()); container.setContextPath(this.managementServerProperties.getContextPath());
......
...@@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; ...@@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.EnvironmentTestUtils;
...@@ -222,6 +223,7 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -222,6 +223,7 @@ public class EndpointWebMvcAutoConfigurationTests {
assertThat(localServerPort, notNullValue()); assertThat(localServerPort, notNullValue());
assertThat(localManagementPort, notNullValue()); assertThat(localManagementPort, notNullValue());
assertThat(localServerPort, not(equalTo(localManagementPort))); assertThat(localServerPort, not(equalTo(localManagementPort)));
assertThat(applicationContext.getBean(ServerPortConfig.class).getCount(), equalTo(2));
this.applicationContext.close(); this.applicationContext.close();
assertAllClosed(); assertAllClosed();
} }
...@@ -303,10 +305,22 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -303,10 +305,22 @@ public class EndpointWebMvcAutoConfigurationTests {
@Configuration @Configuration
public static class ServerPortConfig { public static class ServerPortConfig {
private int count = 0;
public int getCount() {
return count;
}
@Bean @Bean
public ServerProperties serverProperties() { public ServerProperties serverProperties() {
ServerProperties properties = new ServerProperties(); ServerProperties properties = new ServerProperties() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
count++;
super.customize(container);
}
};
properties.setPort(ports.get().server); properties.setPort(ports.get().server);
return properties; return properties;
} }
......
...@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; ...@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -163,6 +164,7 @@ public class ThymeleafAutoConfiguration { ...@@ -163,6 +164,7 @@ public class ThymeleafAutoConfiguration {
@Configuration @Configuration
@ConditionalOnClass({ Servlet.class }) @ConditionalOnClass({ Servlet.class })
@ConditionalOnWebApplication
protected static class ThymeleafViewResolverConfiguration { protected static class ThymeleafViewResolverConfiguration {
@Autowired @Autowired
......
/*
* Copyright 2012-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.mongo;
import org.junit.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link MongoProperties}.
*
* @author Phillip Webb
*/
public class MongoPropertiesTests {
@Test
public void canBindCharArrayPassword() {
// gh-1572
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(context, "spring.data.mongodb.password:word");
context.register(Conf.class);
context.refresh();
MongoProperties properties = context.getBean(MongoProperties.class);
assertThat(properties.getPassword(), equalTo("word".toCharArray()));
}
@Configuration
@EnableConfigurationProperties(MongoProperties.class)
static class Conf {
}
}
...@@ -30,6 +30,7 @@ import org.springframework.mock.web.MockHttpServletRequest; ...@@ -30,6 +30,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.support.RequestContext; import org.springframework.web.servlet.support.RequestContext;
import org.thymeleaf.TemplateEngine; import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context; import org.thymeleaf.context.Context;
...@@ -38,8 +39,10 @@ import org.thymeleaf.spring4.view.ThymeleafViewResolver; ...@@ -38,8 +39,10 @@ import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver; import org.thymeleaf.templateresolver.TemplateResolver;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
...@@ -49,7 +52,7 @@ import static org.junit.Assert.assertTrue; ...@@ -49,7 +52,7 @@ import static org.junit.Assert.assertTrue;
*/ */
public class ThymeleafAutoConfigurationTests { public class ThymeleafAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
@After @After
public void close() { public void close() {
...@@ -148,4 +151,33 @@ public class ThymeleafAutoConfigurationTests { ...@@ -148,4 +151,33 @@ public class ThymeleafAutoConfigurationTests {
assertEquals("<html><body data-foo=\"bar\"></body></html>", result); assertEquals("<html><body data-foo=\"bar\"></body></html>", result);
} }
@Test
public void renderTemplate() throws Exception {
this.context.register(ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
TemplateEngine engine = this.context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("foo", "bar"));
String result = engine.process("home", attrs);
assertEquals("<html><body>bar</body></html>", result);
}
@Test
public void renderNonWebAppTemplate() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
assertEquals(0, context.getBeanNamesForType(ViewResolver.class).length);
try {
TemplateEngine engine = context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("greeting",
"Hello World"));
String result = engine.process("message", attrs);
assertThat(result, containsString("Hello World"));
}
finally {
context.close();
}
}
} }
...@@ -81,7 +81,8 @@ public class BasicErrorControllerIntegrationTest { ...@@ -81,7 +81,8 @@ public class BasicErrorControllerIntegrationTest {
"http://localhost:" + this.port + "/bind", Map.class); "http://localhost:" + this.port + "/bind", Map.class);
String resp = entity.getBody().toString(); String resp = entity.getBody().toString();
assertThat(resp, containsString("Error count: 1")); assertThat(resp, containsString("Error count: 1"));
assertThat(resp, containsString("errors=[{codes=")); assertThat(resp, containsString("errors=[{"));
assertThat(resp, containsString("codes=["));
assertThat(resp, containsString("org.springframework.validation.BindException")); assertThat(resp, containsString("org.springframework.validation.BindException"));
} }
......
<html><body th:text="${foo}">Home</body></html>
\ No newline at end of file
<html><body>Message: <span th:text="${greeting}">Hello</span></body></html>
\ No newline at end of file
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
-- Simple REST service with production features -- Simple REST service with production features
* link:spring-boot-sample-actuator-ui[spring-boot-sample-actuator-ui] * link:spring-boot-sample-actuator-ui[spring-boot-sample-actuator-ui]
-- A web UI example with production features -- A web UI example with production features
* link:spring-boot-sample-actuator-ui[spring-boot-sample-actuator-noweb] * link:spring-boot-sample-actuator-noweb[spring-boot-sample-actuator-noweb]
-- A production features sample with no web application -- A production features sample with no web application
* link:spring-boot-sample-actuator-ui[spring-boot-sample-actuator-log4j] * link:spring-boot-sample-actuator-log4j[spring-boot-sample-actuator-log4j]
-- A production features sample using log4j for logging (instead of logback) -- A production features sample using log4j for logging (instead of logback)
* link:spring-boot-sample-web-ui[spring-boot-sample-web-ui] * link:spring-boot-sample-web-ui[spring-boot-sample-web-ui]
-- A thymeleaf web application -- A thymeleaf web application
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
-- Example showing database migrations with Liquibase -- Example showing database migrations with Liquibase
* link:spring-boot-sample-amqp[spring-boot-sample-amqp] * link:spring-boot-sample-amqp[spring-boot-sample-amqp]
-- Example showing message-oriented application using RabbitMQ -- Example showing message-oriented application using RabbitMQ
* link:spring-boot-sample-amqp[spring-boot-sample-hornetq] * link:spring-boot-sample-hornetq[spring-boot-sample-hornetq]
-- Example showing message-oriented application using HornetQ -- Example showing message-oriented application using HornetQ
* link:spring-boot-sample-batch[spring-boot-sample-batch] * link:spring-boot-sample-batch[spring-boot-sample-batch]
-- Define and run a Batch job in a few lines of code -- Define and run a Batch job in a few lines of code
......
logging.file: /tmp/logs/app.log logging.file: /tmp/logs/app.log
logging.level.org.springframework.security: INFO logging.level.org.springframework.security: INFO
management.address: 127.0.0.1 management.address: 127.0.0.1
#management.port: 8181
endpoints.shutdown.enabled: true endpoints.shutdown.enabled: true
server.tomcat.basedir: target/tomcat server.tomcat.basedir: target/tomcat
server.tomcat.access_log_enabled: true server.tomcat.access_log_enabled: true
......
...@@ -49,6 +49,7 @@ class RelaxedConversionService implements ConversionService { ...@@ -49,6 +49,7 @@ class RelaxedConversionService implements ConversionService {
this.additionalConverters = new GenericConversionService(); this.additionalConverters = new GenericConversionService();
this.additionalConverters this.additionalConverters
.addConverterFactory(new StringToEnumIgnoringCaseConverterFactory()); .addConverterFactory(new StringToEnumIgnoringCaseConverterFactory());
this.additionalConverters.addConverter(new StringToCharArrayConverter());
} }
@Override @Override
......
/*
* Copyright 2012-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.bind;
import org.springframework.core.convert.converter.Converter;
/**
* Converts a String to a Char Array.
*
* @author Phillip Webb
*/
class StringToCharArrayConverter implements Converter<String, char[]> {
@Override
public char[] convert(String source) {
return source.toCharArray();
}
}
...@@ -188,6 +188,16 @@ public class ConfigurationPropertiesBindingPostProcessorTests { ...@@ -188,6 +188,16 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
assertTrue("No init", ConfigurationPropertiesWithFactoryBean.factoryBeanInit); assertTrue("No init", ConfigurationPropertiesWithFactoryBean.factoryBeanInit);
} }
@Test
public void configurationPropertiesWithCharArray() throws Exception {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, "test.chars:word");
this.context.register(PropertyWithCharArray.class);
this.context.refresh();
assertThat(this.context.getBean(PropertyWithCharArray.class).getChars(),
equalTo("word".toCharArray()));
}
@Configuration @Configuration
@EnableConfigurationProperties @EnableConfigurationProperties
public static class TestConfigurationWithValidatingSetter { public static class TestConfigurationWithValidatingSetter {
...@@ -302,6 +312,23 @@ public class ConfigurationPropertiesBindingPostProcessorTests { ...@@ -302,6 +312,23 @@ public class ConfigurationPropertiesBindingPostProcessorTests {
} }
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "test")
public static class PropertyWithCharArray {
private char[] chars;
public char[] getChars() {
return this.chars;
}
public void setChars(char[] chars) {
this.chars = chars;
}
}
@Configuration @Configuration
@EnableConfigurationProperties @EnableConfigurationProperties
@ConfigurationProperties(prefix = "test") @ConfigurationProperties(prefix = "test")
......
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