This commit is contained in:
Phillip Webb 2017-09-14 18:33:03 -07:00
parent 796d400318
commit 324a00fd6d
26 changed files with 189 additions and 226 deletions

View File

@ -100,7 +100,8 @@ public class EndpointEnablementProvider {
if (result != null) { if (result != null) {
return result; return result;
} }
boolean enablement = determineGlobalDefaultEnablement(defaultEnablement, exposure); boolean enablement = determineGlobalDefaultEnablement(defaultEnablement,
exposure);
String message = determineGlobalDefaultMessage(endpointId, enablement, exposure, String message = determineGlobalDefaultMessage(endpointId, enablement, exposure,
defaultEnablement); defaultEnablement);
return new EndpointEnablement(enablement, message); return new EndpointEnablement(enablement, message);

View File

@ -61,15 +61,16 @@ public class ConfigurationPropertiesReportEndpointAutoConfigurationTests {
@Test @Test
public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception {
this.contextRunner.withUserConfiguration(Config.class) this.contextRunner.withUserConfiguration(Config.class)
.withPropertyValues("endpoints.configprops.keys-to-sanitize: .*pass.*, property") .withPropertyValues(
"endpoints.configprops.keys-to-sanitize: .*pass.*, property")
.run(validateTestProperties("******", "******")); .run(validateTestProperties("******", "******"));
} }
private ContextConsumer<AssertableApplicationContext> validateTestProperties(String dbPassword, private ContextConsumer<AssertableApplicationContext> validateTestProperties(
String myTestProperty) { String dbPassword, String myTestProperty) {
return context -> { return context -> {
assertThat(context).hasSingleBean( assertThat(context)
ConfigurationPropertiesReportEndpoint.class); .hasSingleBean(ConfigurationPropertiesReportEndpoint.class);
ConfigurationPropertiesReportEndpoint endpoint = context ConfigurationPropertiesReportEndpoint endpoint = context
.getBean(ConfigurationPropertiesReportEndpoint.class); .getBean(ConfigurationPropertiesReportEndpoint.class);
ConfigurationPropertiesDescriptor properties = endpoint ConfigurationPropertiesDescriptor properties = endpoint
@ -94,7 +95,7 @@ public class ConfigurationPropertiesReportEndpointAutoConfigurationTests {
} }
@ConfigurationProperties("test") @ConfigurationProperties("test")
private static class TestProperties { static class TestProperties {
private String dbPassword = "123456"; private String dbPassword = "123456";

View File

@ -127,16 +127,14 @@ public class EndpointEnablementProviderTests {
public void defaultEnablementNeutral() { public void defaultEnablementNeutral() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL); DefaultEnablement.NEUTRAL);
validate(enablement, true, validate(enablement, true, "endpoint 'biz' is enabled (default)");
"endpoint 'biz' is enabled (default)");
} }
@Test @Test
public void defaultEnablementNeutralWeb() { public void defaultEnablementNeutralWeb() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB); DefaultEnablement.NEUTRAL, EndpointExposure.WEB);
validate(enablement, false, validate(enablement, false, "endpoint 'default' (web) is disabled by default");
"endpoint 'default' (web) is disabled by default");
} }
@Test @Test
@ -151,8 +149,7 @@ public class EndpointEnablementProviderTests {
public void defaultEnablementNeutralWithGeneralDisablement() { public void defaultEnablementNeutralWithGeneralDisablement() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, "endpoints.default.enabled=false"); DefaultEnablement.NEUTRAL, "endpoints.default.enabled=false");
validate(enablement, false, validate(enablement, false, "found property endpoints.default.enabled");
"found property endpoints.default.enabled");
} }
@Test @Test
@ -160,18 +157,15 @@ public class EndpointEnablementProviderTests {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.jmx.enabled=false"); "endpoints.default.jmx.enabled=false");
validate(enablement, false, validate(enablement, false, "found property endpoints.default.jmx.enabled");
"found property endpoints.default.jmx.enabled");
} }
@Test @Test
public void defaultEnablementNeutralTechTakesPrecedence() { public void defaultEnablementNeutralTechTakesPrecedence() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=true", "endpoints.default.enabled=true", "endpoints.default.jmx.enabled=false");
"endpoints.default.jmx.enabled=false"); validate(enablement, false, "found property endpoints.default.jmx.enabled");
validate(enablement, false,
"found property endpoints.default.jmx.enabled");
} }
@Test @Test
@ -179,8 +173,7 @@ public class EndpointEnablementProviderTests {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB, DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
"endpoints.default.web.enabled=true"); "endpoints.default.web.enabled=true");
validate(enablement, true, validate(enablement, true, "found property endpoints.default.web.enabled");
"found property endpoints.default.web.enabled");
} }
@Test @Test
@ -196,8 +189,7 @@ public class EndpointEnablementProviderTests {
public void defaultEnablementNeutralWithOverride() { public void defaultEnablementNeutralWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, "endpoints.biz.enabled=false"); DefaultEnablement.NEUTRAL, "endpoints.biz.enabled=false");
validate(enablement, false, validate(enablement, false, "found property endpoints.biz.enabled");
"found property endpoints.biz.enabled");
} }
@Test @Test
@ -205,8 +197,7 @@ public class EndpointEnablementProviderTests {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB, DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
"endpoints.biz.web.enabled=true"); "endpoints.biz.web.enabled=true");
validate(enablement, true, validate(enablement, true, "found property endpoints.biz.web.enabled");
"found property endpoints.biz.web.enabled");
} }
@Test @Test
@ -214,41 +205,33 @@ public class EndpointEnablementProviderTests {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.biz.jmx.enabled=false"); "endpoints.biz.jmx.enabled=false");
validate(enablement, false, validate(enablement, false, "found property endpoints.biz.jmx.enabled");
"found property endpoints.biz.jmx.enabled");
} }
@Test @Test
public void defaultEnablementNeutralTechTakesPrecedenceOnEverything() { public void defaultEnablementNeutralTechTakesPrecedenceOnEverything() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.enabled=false", "endpoints.default.jmx.enabled=false",
"endpoints.default.jmx.enabled=false", "endpoints.biz.enabled=false", "endpoints.biz.jmx.enabled=true");
"endpoints.biz.enabled=false", validate(enablement, true, "found property endpoints.biz.jmx.enabled");
"endpoints.biz.jmx.enabled=true");
validate(enablement, true,
"found property endpoints.biz.jmx.enabled");
} }
@Test @Test
public void defaultEnablementNeutralSpecificTakesPrecedenceOnDefaults() { public void defaultEnablementNeutralSpecificTakesPrecedenceOnDefaults() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.enabled=false", "endpoints.default.jmx.enabled=false",
"endpoints.default.jmx.enabled=false",
"endpoints.biz.enabled=true"); "endpoints.biz.enabled=true");
validate(enablement, true, validate(enablement, true, "found property endpoints.biz.enabled");
"found property endpoints.biz.enabled");
} }
@Test @Test
public void defaultEnablementNeutralDefaultTechTakesPrecedenceOnGeneralDefault() { public void defaultEnablementNeutralDefaultTechTakesPrecedenceOnGeneralDefault() {
EndpointEnablement enablement = getEndpointEnablement("biz", EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX, DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.enabled=false", "endpoints.default.jmx.enabled=true");
"endpoints.default.jmx.enabled=true"); validate(enablement, true, "found property endpoints.default.jmx.enabled");
validate(enablement, true,
"found property endpoints.default.jmx.enabled");
} }
private EndpointEnablement getEndpointEnablement(String id, private EndpointEnablement getEndpointEnablement(String id,

View File

@ -56,7 +56,6 @@ public class EnvironmentEndpointAutoConfigurationTests {
.doesNotHaveBean(EnvironmentEndpoint.class)); .doesNotHaveBean(EnvironmentEndpoint.class));
} }
@Test @Test
public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception { public void keysToSanitizeCanBeConfiguredViaTheEnvironment() throws Exception {
this.contextRunner.withSystemProperties("dbPassword=123456", "apiKey=123456") this.contextRunner.withSystemProperties("dbPassword=123456", "apiKey=123456")
@ -84,5 +83,4 @@ public class EnvironmentEndpointAutoConfigurationTests {
.filter((source) -> name.equals(source.getName())).findFirst().get(); .filter((source) -> name.equals(source.getName())).findFirst().get();
} }
} }

View File

@ -84,8 +84,8 @@ public class HealthEndpointAutoConfigurationTests {
@Test @Test
public void runShouldHaveStatusEndpointBeanEvenIfDefaultIsDisabled() { public void runShouldHaveStatusEndpointBeanEvenIfDefaultIsDisabled() {
this.contextRunner.withPropertyValues("endpoints.default.enabled:false") this.contextRunner.withPropertyValues("endpoints.default.enabled:false").run(
.run((context) -> assertThat(context).hasSingleBean(StatusEndpoint.class)); (context) -> assertThat(context).hasSingleBean(StatusEndpoint.class));
} }
@Test @Test

View File

@ -55,8 +55,7 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, checkEndpointMBeans(mBeanServer,
new String[] { "autoconfig", "beans", "configprops", "env", "health", new String[] { "autoconfig", "beans", "configprops", "env", "health",
"info", "mappings", "status", "threaddump", "info", "mappings", "status", "threaddump", "trace" },
"trace" },
new String[] { "shutdown" }); new String[] { "shutdown" });
}); });
} }
@ -68,8 +67,8 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, new String[0], checkEndpointMBeans(mBeanServer, new String[0],
new String[] { "autoconfig", "beans", "configprops", "env", new String[] { "autoconfig", "beans", "configprops", "env",
"health", "mappings", "shutdown", "health", "mappings", "shutdown", "threaddump",
"threaddump", "trace" }); "trace" });
}); });
} }
@ -81,8 +80,7 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, new String[] { "beans" }, checkEndpointMBeans(mBeanServer, new String[] { "beans" },
new String[] { "autoconfig", "configprops", "env", "health", new String[] { "autoconfig", "configprops", "env", "health",
"mappings", "shutdown", "mappings", "shutdown", "threaddump", "trace" });
"threaddump", "trace" });
}); });
} }

View File

@ -44,7 +44,6 @@ public class LogFileWebEndpointManagementContextConfigurationTests {
@Rule @Rule
public TemporaryFolder temp = new TemporaryFolder(); public TemporaryFolder temp = new TemporaryFolder();
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withUserConfiguration( .withUserConfiguration(
LogFileWebEndpointManagementContextConfiguration.class); LogFileWebEndpointManagementContextConfiguration.class);
@ -81,18 +80,19 @@ public class LogFileWebEndpointManagementContextConfigurationTests {
@Test @Test
public void logFileWebEndpointUsesConfiguredExternalFile() throws IOException { public void logFileWebEndpointUsesConfiguredExternalFile() throws IOException {
File file = this.temp.newFile("logfile"); File file = this.temp.newFile("logfile");
FileCopyUtils.copy("--TEST--" .getBytes(), file); FileCopyUtils.copy("--TEST--".getBytes(), file);
this.contextRunner this.contextRunner
.withPropertyValues("endpoints.logfile.external-file:" .withPropertyValues(
+ file.getAbsolutePath()).run((context) -> { "endpoints.logfile.external-file:" + file.getAbsolutePath())
.run((context) -> {
assertThat(context).hasSingleBean(LogFileWebEndpoint.class); assertThat(context).hasSingleBean(LogFileWebEndpoint.class);
LogFileWebEndpoint endpoint = context.getBean(LogFileWebEndpoint.class); LogFileWebEndpoint endpoint = context
.getBean(LogFileWebEndpoint.class);
Resource resource = endpoint.logFile(); Resource resource = endpoint.logFile();
assertThat(resource).isNotNull(); assertThat(resource).isNotNull();
assertThat(StreamUtils.copyToString(resource.getInputStream(), assertThat(StreamUtils.copyToString(resource.getInputStream(),
StandardCharsets.UTF_8)).isEqualTo("--TEST--"); StandardCharsets.UTF_8)).isEqualTo("--TEST--");
}); });
} }
} }

View File

@ -119,8 +119,8 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
private EndpointInfo<T> createEndpointInfo(String beanName, Class<?> beanType, private EndpointInfo<T> createEndpointInfo(String beanName, Class<?> beanType,
AnnotationAttributes attributes) { AnnotationAttributes attributes) {
String id = attributes.getString("id"); String id = attributes.getString("id");
DefaultEnablement defaultEnablement = (DefaultEnablement) attributes.get( DefaultEnablement defaultEnablement = (DefaultEnablement) attributes
"defaultEnablement"); .get("defaultEnablement");
Map<Method, T> operations = discoverOperations(id, beanName, beanType); Map<Method, T> operations = discoverOperations(id, beanName, beanType);
return new EndpointInfo<>(id, defaultEnablement, operations.values()); return new EndpointInfo<>(id, defaultEnablement, operations.values());
} }

View File

@ -72,8 +72,8 @@ public class SecurityProperties implements SecurityPrerequisite {
/** /**
* Security filter chain dispatcher types. * Security filter chain dispatcher types.
*/ */
private Set<DispatcherType> dispatcherTypes = new HashSet<>(Arrays private Set<DispatcherType> dispatcherTypes = new HashSet<>(Arrays.asList(
.asList(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST)); DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST));
public int getOrder() { public int getOrder() {
return this.order; return this.order;

View File

@ -31,17 +31,16 @@ import org.springframework.util.ObjectUtils;
*/ */
public class NonUniqueSessionRepositoryException extends RuntimeException { public class NonUniqueSessionRepositoryException extends RuntimeException {
private final List<Class<? extends SessionRepository<?>>> availableCandidates; private final List<Class<?>> availableCandidates;
public NonUniqueSessionRepositoryException( public NonUniqueSessionRepositoryException(List<Class<?>> availableCandidates) {
List<Class<? extends SessionRepository<?>>> availableCandidates) {
super("Multiple session repository candidates are available, set the " super("Multiple session repository candidates are available, set the "
+ "'spring.session.store-type' property accordingly"); + "'spring.session.store-type' property accordingly");
this.availableCandidates = (!ObjectUtils.isEmpty(availableCandidates) this.availableCandidates = (!ObjectUtils.isEmpty(availableCandidates)
? availableCandidates : Collections.emptyList()); ? availableCandidates : Collections.emptyList());
} }
public List<Class<? extends SessionRepository<?>>> getAvailableCandidates() { public List<Class<?>> getAvailableCandidates() {
return this.availableCandidates; return this.availableCandidates;
} }

View File

@ -18,7 +18,6 @@ package org.springframework.boot.autoconfigure.session;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.session.SessionRepository;
/** /**
* A {@link AbstractFailureAnalyzer} for {@link NonUniqueSessionRepositoryException}. * A {@link AbstractFailureAnalyzer} for {@link NonUniqueSessionRepositoryException}.
@ -34,8 +33,7 @@ class NonUniqueSessionRepositoryFailureAnalyzer
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append(String.format("Multiple Spring Session store implementations are " message.append(String.format("Multiple Spring Session store implementations are "
+ "available on the classpath:%n")); + "available on the classpath:%n"));
for (Class<? extends SessionRepository<?>> candidate : cause for (Class<?> candidate : cause.getAvailableCandidates()) {
.getAvailableCandidates()) {
message.append(String.format(" - %s%n", candidate.getName())); message.append(String.format(" - %s%n", candidate.getName()));
} }
StringBuilder action = new StringBuilder(); StringBuilder action = new StringBuilder();

View File

@ -106,7 +106,7 @@ public class SessionAutoConfiguration {
@PostConstruct @PostConstruct
public void checkAvailableImplementations() { public void checkAvailableImplementations() {
List<Class<? extends SessionRepository<?>>> candidates = new ArrayList<>(); List<Class<?>> candidates = new ArrayList<>();
addCandidate(candidates, addCandidate(candidates,
"org.springframework.session.hazelcast.HazelcastSessionRepository"); "org.springframework.session.hazelcast.HazelcastSessionRepository");
addCandidate(candidates, addCandidate(candidates,
@ -119,12 +119,9 @@ public class SessionAutoConfiguration {
} }
} }
@SuppressWarnings("unchecked") private void addCandidate(List<Class<?>> candidates, String type) {
private void addCandidate(List<Class<? extends SessionRepository<?>>> candidates,
String fqn) {
try { try {
Class<? extends SessionRepository<?>> candidate = (Class<? extends SessionRepository<?>>) this.classLoader Class<?> candidate = this.classLoader.loadClass(type);
.loadClass(fqn);
if (candidate != null) { if (candidate != null) {
candidates.add(candidate); candidates.add(candidate);
} }

View File

@ -52,7 +52,6 @@ public class ResourceProperties {
private final Chain chain = new Chain(); private final Chain chain = new Chain();
public String[] getStaticLocations() { public String[] getStaticLocations() {
return this.staticLocations; return this.staticLocations;
} }

View File

@ -166,7 +166,8 @@ public class WebMvcAutoConfiguration {
@Configuration @Configuration
@Import(EnableWebMvcConfiguration.class) @Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class }) @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware { public static class WebMvcAutoConfigurationAdapter
implements WebMvcConfigurer, ResourceLoaderAware {
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class); private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
@ -316,8 +317,8 @@ public class WebMvcAutoConfiguration {
if (!registry.hasMappingForPattern(staticPathPattern)) { if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration( customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern) registry.addResourceHandler(staticPathPattern)
.addResourceLocations( .addResourceLocations(getResourceLocations(
getResourceLocations(this.resourceProperties.getStaticLocations())) this.resourceProperties.getStaticLocations()))
.setCachePeriod(cachePeriod)); .setCachePeriod(cachePeriod));
} }
} }
@ -329,29 +330,32 @@ public class WebMvcAutoConfiguration {
} }
static String[] getResourceLocations(String[] staticLocations) { static String[] getResourceLocations(String[] staticLocations) {
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length]; String[] locations = new String[staticLocations.length
+ SERVLET_LOCATIONS.length];
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length); System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
System.arraycopy(SERVLET_LOCATIONS, 0, locations, System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length,
staticLocations.length, SERVLET_LOCATIONS.length); SERVLET_LOCATIONS.length);
return locations; return locations;
} }
private Optional<Resource> getWelcomePage() { private Optional<Resource> getWelcomePage() {
return Arrays.stream(getResourceLocations(this.resourceProperties.getStaticLocations())) String[] locations = getResourceLocations(
.map(location -> this.resourceLoader.getResource(location + "index.html")) this.resourceProperties.getStaticLocations());
.filter(resource -> { return Arrays.stream(locations).map(this::getIndexHtml)
try { .filter(this::isReadable).findFirst();
if (resource.exists()) {
resource.getURL();
return true;
} }
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
private boolean isReadable(Resource resource) {
try {
return resource.exists() && (resource.getURL() != null);
} }
catch (Exception ex) { catch (Exception ex) {
// Ignore
}
return false; return false;
}) }
.findFirst();
} }
private void customizeResourceHandlerRegistration( private void customizeResourceHandlerRegistration(
@ -359,7 +363,6 @@ public class WebMvcAutoConfiguration {
if (this.resourceHandlerRegistrationCustomizer != null) { if (this.resourceHandlerRegistrationCustomizer != null) {
this.resourceHandlerRegistrationCustomizer.customize(registration); this.resourceHandlerRegistrationCustomizer.customize(registration);
} }
} }
@Bean @Bean
@ -403,10 +406,11 @@ public class WebMvcAutoConfiguration {
} }
private List<Resource> resolveFaviconLocations() { private List<Resource> resolveFaviconLocations() {
String[] resourceLocations = getResourceLocations(this.resourceProperties.getStaticLocations()); String[] staticLocations = getResourceLocations(
List<Resource> locations = new ArrayList<>(resourceLocations.length + 1); this.resourceProperties.getStaticLocations());
Arrays.stream(resourceLocations) List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
.forEach(location -> locations.add(this.resourceLoader.getResource(location))); Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
.forEach(locations::add);
locations.add(new ClassPathResource("/")); locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations); return Collections.unmodifiableList(locations);
} }

View File

@ -121,8 +121,8 @@ public class OAuth2RestOperationsConfigurationTests {
} }
@Configuration @Configuration
@Import({ SecurityProperties.class, @Import({ SecurityProperties.class, OAuth2ClientConfiguration.class,
OAuth2ClientConfiguration.class, OAuth2RestOperationsConfiguration.class }) OAuth2RestOperationsConfiguration.class })
protected static class ConfigForSessionScopedConfiguration protected static class ConfigForSessionScopedConfiguration
extends WebApplicationConfiguration { extends WebApplicationConfiguration {

View File

@ -52,23 +52,22 @@ public class SessionAutoConfigurationHazelcastTests
@Test @Test
public void defaultConfig() { public void defaultConfig() {
this.contextRunner this.contextRunner.withPropertyValues("spring.session.store-type=hazelcast")
.withPropertyValues("spring.session.store-type=hazelcast")
.run(this::validateDefaultConfig); .run(this::validateDefaultConfig);
} }
@Test @Test
public void defaultConfigWithUniqueStoreImplementation() { public void defaultConfigWithUniqueStoreImplementation() {
this.contextRunner.withClassLoader(new HideClassesClassLoader( this.contextRunner
JdbcOperationsSessionRepository.class, .withClassLoader(
RedisOperationsSessionRepository.class)).run( new HideClassesClassLoader(JdbcOperationsSessionRepository.class,
this::validateDefaultConfig); RedisOperationsSessionRepository.class))
.run(this::validateDefaultConfig);
} }
private void validateDefaultConfig(AssertableWebApplicationContext context) { private void validateDefaultConfig(AssertableWebApplicationContext context) {
validateSessionRepository(context, HazelcastSessionRepository.class); validateSessionRepository(context, HazelcastSessionRepository.class);
HazelcastInstance hazelcastInstance = context HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class);
.getBean(HazelcastInstance.class);
verify(hazelcastInstance, times(1)).getMap("spring:session:sessions"); verify(hazelcastInstance, times(1)).getMap("spring:session:sessions");
} }

View File

@ -46,13 +46,13 @@ public class SessionAutoConfigurationIntegrationTests
SessionAutoConfiguration.class)) SessionAutoConfiguration.class))
.withPropertyValues("spring.datasource.generate-unique-name=true"); .withPropertyValues("spring.datasource.generate-unique-name=true");
@Test @Test
public void severalCandidatesWithNoSessionStore() { public void severalCandidatesWithNoSessionStore() {
this.contextRunner.withUserConfiguration(HazelcastConfiguration.class).run((context) -> { this.contextRunner.withUserConfiguration(HazelcastConfiguration.class)
.run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context).getFailure() assertThat(context).getFailure().hasCauseInstanceOf(
.hasCauseInstanceOf(NonUniqueSessionRepositoryException.class); NonUniqueSessionRepositoryException.class);
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure().hasMessageContaining(
"Multiple session repository candidates are available"); "Multiple session repository candidates are available");
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure().hasMessageContaining(
@ -65,12 +65,12 @@ public class SessionAutoConfigurationIntegrationTests
this.contextRunner.withUserConfiguration(HazelcastConfiguration.class) this.contextRunner.withUserConfiguration(HazelcastConfiguration.class)
.withPropertyValues("spring.session.store-type=redis").run((context) -> { .withPropertyValues("spring.session.store-type=redis").run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context).getFailure() assertThat(context).getFailure().hasCauseInstanceOf(
.hasCauseInstanceOf(SessionRepositoryUnavailableException.class); SessionRepositoryUnavailableException.class);
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure().hasMessageContaining(
"No session repository could be auto-configured"); "No session repository could be auto-configured");
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure()
"session store type is 'redis'"); .hasMessageContaining("session store type is 'redis'");
}); });
} }
@ -82,7 +82,6 @@ public class SessionAutoConfigurationIntegrationTests
JdbcOperationsSessionRepository.class)); JdbcOperationsSessionRepository.class));
} }
@Configuration @Configuration
static class HazelcastConfiguration { static class HazelcastConfiguration {

View File

@ -58,8 +58,7 @@ public class SessionAutoConfigurationJdbcTests
@Test @Test
public void defaultConfig() { public void defaultConfig() {
this.contextRunner this.contextRunner.withPropertyValues("spring.session.store-type=jdbc")
.withPropertyValues("spring.session.store-type=jdbc")
.withConfiguration( .withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class)) AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))
.run(this::validateDefaultConfig); .run(this::validateDefaultConfig);
@ -68,22 +67,20 @@ public class SessionAutoConfigurationJdbcTests
@Test @Test
public void defaultConfigWithUniqueStoreImplementation() { public void defaultConfigWithUniqueStoreImplementation() {
this.contextRunner this.contextRunner
.withClassLoader(new HideClassesClassLoader( .withClassLoader(
HazelcastSessionRepository.class, new HideClassesClassLoader(HazelcastSessionRepository.class,
RedisOperationsSessionRepository.class) RedisOperationsSessionRepository.class))
)
.withConfiguration( .withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class)) AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))
.run(this::validateDefaultConfig); .run(this::validateDefaultConfig);
} }
private void validateDefaultConfig(AssertableWebApplicationContext context) { private void validateDefaultConfig(AssertableWebApplicationContext context) {
JdbcOperationsSessionRepository repository = validateSessionRepository( JdbcOperationsSessionRepository repository = validateSessionRepository(context,
context, JdbcOperationsSessionRepository.class); JdbcOperationsSessionRepository.class);
assertThat(new DirectFieldAccessor(repository) assertThat(new DirectFieldAccessor(repository).getPropertyValue("tableName"))
.getPropertyValue("tableName")).isEqualTo("SPRING_SESSION"); .isEqualTo("SPRING_SESSION");
assertThat(context.getBean(JdbcSessionProperties.class) assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema())
.getInitializeSchema())
.isEqualTo(DatabaseInitializationMode.EMBEDDED); .isEqualTo(DatabaseInitializationMode.EMBEDDED);
assertThat(context.getBean(JdbcOperations.class) assertThat(context.getBean(JdbcOperations.class)
.queryForList("select * from SPRING_SESSION")).isEmpty(); .queryForList("select * from SPRING_SESSION")).isEmpty();

View File

@ -50,8 +50,7 @@ public class SessionAutoConfigurationRedisTests
@Test @Test
public void defaultConfig() { public void defaultConfig() {
this.contextRunner this.contextRunner.withPropertyValues("spring.session.store-type=redis")
.withPropertyValues("spring.session.store-type=redis")
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:created:", .run(validateSpringSessionUsesRedis("spring:session:event:created:",
RedisFlushMode.ON_SAVE)); RedisFlushMode.ON_SAVE));
@ -60,8 +59,8 @@ public class SessionAutoConfigurationRedisTests
@Test @Test
public void defaultConfigWithUniqueStoreImplementation() { public void defaultConfigWithUniqueStoreImplementation() {
this.contextRunner this.contextRunner
.withClassLoader(new HideClassesClassLoader( .withClassLoader(
HazelcastSessionRepository.class, new HideClassesClassLoader(HazelcastSessionRepository.class,
JdbcOperationsSessionRepository.class)) JdbcOperationsSessionRepository.class))
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:created:", .run(validateSpringSessionUsesRedis("spring:session:event:created:",

View File

@ -66,12 +66,12 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat
this.contextRunner.withPropertyValues("spring.session.store-type=jdbc") this.contextRunner.withPropertyValues("spring.session.store-type=jdbc")
.run((context) -> { .run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context).getFailure() assertThat(context).getFailure().hasCauseInstanceOf(
.hasCauseInstanceOf(SessionRepositoryUnavailableException.class); SessionRepositoryUnavailableException.class);
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure().hasMessageContaining(
"No session repository could be auto-configured"); "No session repository could be auto-configured");
assertThat(context).getFailure().hasMessageContaining( assertThat(context).getFailure()
"session store type is 'jdbc'"); .hasMessageContaining("session store type is 'jdbc'");
}); });
} }
@ -96,8 +96,7 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat
@Test @Test
public void springSessionTimeoutIsNotAValidProperty() { public void springSessionTimeoutIsNotAValidProperty() {
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class) this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
.withPropertyValues("spring.session.timeout=3000") .withPropertyValues("spring.session.timeout=3000").run((context) -> {
.run((context) -> {
assertThat(context).hasFailed(); assertThat(context).hasFailed();
assertThat(context).getFailure() assertThat(context).getFailure()
.isInstanceOf(BeanCreationException.class); .isInstanceOf(BeanCreationException.class);

View File

@ -367,8 +367,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
if (endpointId == null || "".equals(endpointId)) { if (endpointId == null || "".equals(endpointId)) {
return; // Can't process that endpoint return; // Can't process that endpoint
} }
Boolean enabledByDefault = determineEnabledByDefault(elementValues.get( Boolean enabledByDefault = determineEnabledByDefault(
"defaultEnablement")); elementValues.get("defaultEnablement"));
String type = this.typeUtils.getQualifiedName(element); String type = this.typeUtils.getQualifiedName(element);
this.metadataCollector this.metadataCollector
.add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null)); .add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null));

View File

@ -123,9 +123,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.withDescription("The name of this simple properties.") .withDescription("The name of this simple properties.")
.withDefaultValue("boot").withDeprecation(null, null)); .withDefaultValue("boot").withDeprecation(null, null));
assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class) assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class)
.withDefaultValue(false) .withDefaultValue(false).fromSource(SimpleProperties.class)
.fromSource(SimpleProperties.class).withDescription("A simple flag.") .withDescription("A simple flag.").withDeprecation(null, null));
.withDeprecation(null, null));
assertThat(metadata).has(Metadata.withProperty("simple.comparator")); assertThat(metadata).has(Metadata.withProperty("simple.comparator"));
assertThat(metadata).doesNotHave(Metadata.withProperty("simple.counter")); assertThat(metadata).doesNotHave(Metadata.withProperty("simple.counter"));
assertThat(metadata).doesNotHave(Metadata.withProperty("simple.size")); assertThat(metadata).doesNotHave(Metadata.withProperty("simple.size"));
@ -163,8 +162,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.withDefaultValue(false)); .withDefaultValue(false));
assertThat(metadata) assertThat(metadata)
.has(Metadata.withProperty("simple.type.my-short", Short.class)); .has(Metadata.withProperty("simple.type.my-short", Short.class));
assertThat(metadata).has( assertThat(metadata)
Metadata.withProperty("simple.type.my-primitive-short", Short.class) .has(Metadata.withProperty("simple.type.my-primitive-short", Short.class)
.withDefaultValue(0)); .withDefaultValue(0));
assertThat(metadata) assertThat(metadata)
.has(Metadata.withProperty("simple.type.my-integer", Integer.class)); .has(Metadata.withProperty("simple.type.my-integer", Integer.class));
@ -245,8 +244,7 @@ public class ConfigurationMetadataAnnotationProcessorTests {
Class<?> type = BoxingPojo.class; Class<?> type = BoxingPojo.class;
ConfigurationMetadata metadata = compile(type); ConfigurationMetadata metadata = compile(type);
assertThat(metadata).has(Metadata.withGroup("boxing").fromSource(type)); assertThat(metadata).has(Metadata.withGroup("boxing").fromSource(type));
assertThat(metadata).has( assertThat(metadata).has(Metadata.withProperty("boxing.flag", Boolean.class)
Metadata.withProperty("boxing.flag", Boolean.class)
.withDefaultValue(false).fromSource(type)); .withDefaultValue(false).fromSource(type));
assertThat(metadata).has( assertThat(metadata).has(
Metadata.withProperty("boxing.counter", Integer.class).fromSource(type)); Metadata.withProperty("boxing.counter", Integer.class).fromSource(type));
@ -316,8 +314,7 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.fromSource(DeprecatedMethodConfig.Foo.class) .fromSource(DeprecatedMethodConfig.Foo.class)
.withDeprecation(null, null)); .withDeprecation(null, null));
assertThat(metadata).has(Metadata.withProperty("foo.flag", Boolean.class) assertThat(metadata).has(Metadata.withProperty("foo.flag", Boolean.class)
.withDefaultValue(false) .withDefaultValue(false).fromSource(DeprecatedMethodConfig.Foo.class)
.fromSource(DeprecatedMethodConfig.Foo.class)
.withDeprecation(null, null)); .withDeprecation(null, null));
} }
@ -331,8 +328,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.fromSource( .fromSource(
org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class) org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class)
.withDeprecation(null, null)); .withDeprecation(null, null));
assertThat(metadata).has(Metadata.withProperty("foo.flag", Boolean.class) assertThat(metadata).has(
.withDefaultValue(false) Metadata.withProperty("foo.flag", Boolean.class).withDefaultValue(false)
.fromSource( .fromSource(
org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class) org.springframework.boot.configurationsample.method.DeprecatedClassMethodConfig.Foo.class)
.withDeprecation(null, null)); .withDeprecation(null, null));
@ -879,34 +876,30 @@ public class ConfigurationMetadataAnnotationProcessorTests {
assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isFalse(); assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isFalse();
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isTrue(); assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isTrue();
assertThat(metadata).has( assertThat(metadata).has(Metadata.withProperty("foo.counter")
Metadata.withProperty("foo.counter").fromSource(FooProperties.class) .fromSource(FooProperties.class).withDefaultValue(0));
.withDefaultValue(0)); assertThat(metadata).has(Metadata.withProperty("bar.counter")
assertThat(metadata).has( .fromSource(BarProperties.class).withDefaultValue(0));
Metadata.withProperty("bar.counter").fromSource(BarProperties.class)
.withDefaultValue(0));
metadata = project.incrementalBuild(BarProperties.class); metadata = project.incrementalBuild(BarProperties.class);
assertThat(metadata).has( assertThat(metadata).has(Metadata.withProperty("foo.counter")
Metadata.withProperty("foo.counter").fromSource(FooProperties.class) .fromSource(FooProperties.class).withDefaultValue(0));
.withDefaultValue(0)); assertThat(metadata).has(Metadata.withProperty("bar.counter")
assertThat(metadata).has( .fromSource(BarProperties.class).withDefaultValue(0));
Metadata.withProperty("bar.counter").fromSource(BarProperties.class)
.withDefaultValue(0));
project.addSourceCode(BarProperties.class, project.addSourceCode(BarProperties.class,
BarProperties.class.getResourceAsStream("BarProperties.snippet")); BarProperties.class.getResourceAsStream("BarProperties.snippet"));
metadata = project.incrementalBuild(BarProperties.class); metadata = project.incrementalBuild(BarProperties.class);
assertThat(metadata).has(Metadata.withProperty("bar.extra")); assertThat(metadata).has(Metadata.withProperty("bar.extra"));
assertThat(metadata).has(Metadata.withProperty("foo.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("foo.counter").withDefaultValue(0));
assertThat(metadata).has(Metadata.withProperty("bar.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("bar.counter").withDefaultValue(0));
project.revert(BarProperties.class); project.revert(BarProperties.class);
metadata = project.incrementalBuild(BarProperties.class); metadata = project.incrementalBuild(BarProperties.class);
assertThat(metadata).isNotEqualTo(Metadata.withProperty("bar.extra")); assertThat(metadata).isNotEqualTo(Metadata.withProperty("bar.extra"));
assertThat(metadata).has(Metadata.withProperty("foo.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("foo.counter").withDefaultValue(0));
assertThat(metadata).has(Metadata.withProperty("bar.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("bar.counter").withDefaultValue(0));
} }
@Test @Test
@ -914,15 +907,15 @@ public class ConfigurationMetadataAnnotationProcessorTests {
TestProject project = new TestProject(this.temporaryFolder, FooProperties.class, TestProject project = new TestProject(this.temporaryFolder, FooProperties.class,
BarProperties.class); BarProperties.class);
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withProperty("foo.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("foo.counter").withDefaultValue(0));
assertThat(metadata).has(Metadata.withProperty("bar.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("bar.counter").withDefaultValue(0));
project.replaceText(BarProperties.class, "@ConfigurationProperties", project.replaceText(BarProperties.class, "@ConfigurationProperties",
"//@ConfigurationProperties"); "//@ConfigurationProperties");
metadata = project.incrementalBuild(BarProperties.class); metadata = project.incrementalBuild(BarProperties.class);
assertThat(metadata).has(Metadata.withProperty("foo.counter") assertThat(metadata)
.withDefaultValue(0)); .has(Metadata.withProperty("foo.counter").withDefaultValue(0));
assertThat(metadata).isNotEqualTo(Metadata.withProperty("bar.counter")); assertThat(metadata).isNotEqualTo(Metadata.withProperty("bar.counter"));
} }
@ -931,25 +924,21 @@ public class ConfigurationMetadataAnnotationProcessorTests {
TestProject project = new TestProject(this.temporaryFolder, FooProperties.class, TestProject project = new TestProject(this.temporaryFolder, FooProperties.class,
BarProperties.class); BarProperties.class);
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has( assertThat(metadata).has(Metadata.withProperty("foo.counter")
Metadata.withProperty("foo.counter").fromSource(FooProperties.class) .fromSource(FooProperties.class).withDefaultValue(0));
.withDefaultValue(0)); assertThat(metadata).has(Metadata.withProperty("bar.counter")
assertThat(metadata).has( .fromSource(BarProperties.class).withDefaultValue(0));
Metadata.withProperty("bar.counter").fromSource(BarProperties.class)
.withDefaultValue(0));
assertThat(metadata).doesNotHave(Metadata.withProperty("bar.counter") assertThat(metadata).doesNotHave(Metadata.withProperty("bar.counter")
.fromSource(RenamedBarProperties.class)); .fromSource(RenamedBarProperties.class));
project.delete(BarProperties.class); project.delete(BarProperties.class);
project.add(RenamedBarProperties.class); project.add(RenamedBarProperties.class);
metadata = project.incrementalBuild(RenamedBarProperties.class); metadata = project.incrementalBuild(RenamedBarProperties.class);
assertThat(metadata).has( assertThat(metadata).has(Metadata.withProperty("foo.counter")
Metadata.withProperty("foo.counter").fromSource(FooProperties.class) .fromSource(FooProperties.class).withDefaultValue(0));
.withDefaultValue(0)); assertThat(metadata).doesNotHave(Metadata.withProperty("bar.counter")
assertThat(metadata).doesNotHave( .fromSource(BarProperties.class).withDefaultValue(0));
Metadata.withProperty("bar.counter").fromSource(BarProperties.class) assertThat(metadata).has(Metadata.withProperty("bar.counter").withDefaultValue(0)
.withDefaultValue(0)); .fromSource(RenamedBarProperties.class));
assertThat(metadata).has(Metadata.withProperty("bar.counter")
.withDefaultValue(0).fromSource(RenamedBarProperties.class));
} }
private void assertSimpleLombokProperties(ConfigurationMetadata metadata, private void assertSimpleLombokProperties(ConfigurationMetadata metadata,

View File

@ -19,4 +19,5 @@ package org.springframework.boot.configurationsample;
public enum DefaultEnablement { public enum DefaultEnablement {
ENABLED, DISABLED, NEUTRAL ENABLED, DISABLED, NEUTRAL
} }

View File

@ -29,6 +29,7 @@ import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
@ -67,6 +68,7 @@ public class ConfigurationPropertiesBinderBuilder {
* @param applicationContext the application context * @param applicationContext the application context
*/ */
public ConfigurationPropertiesBinderBuilder(ApplicationContext applicationContext) { public ConfigurationPropertiesBinderBuilder(ApplicationContext applicationContext) {
Assert.notNull(applicationContext, "ApplicationContext must not be null");
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
} }