diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointMBeanExportAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointMBeanExportAutoConfiguration.java index 7ff646c159..91067c9beb 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointMBeanExportAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointMBeanExportAutoConfiguration.java @@ -35,7 +35,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -50,6 +49,7 @@ import org.springframework.util.StringUtils; * * @author Christian Dupuis * @author Andy Wilkinson + * @author Madhura Bhave */ @Configuration @Conditional(JmxEnabledCondition.class) @@ -103,8 +103,10 @@ public class EndpointMBeanExportAutoConfiguration { @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { - boolean jmxEnabled = isEnabled(context, "spring.jmx."); - boolean jmxEndpointsEnabled = isEnabled(context, "endpoints.jmx."); + boolean jmxEnabled = context.getEnvironment() + .getProperty("spring.jmx.enabled", Boolean.class, true); + boolean jmxEndpointsEnabled = context.getEnvironment() + .getProperty("endpoints.jmx.enabled", Boolean.class, true); if (jmxEnabled && jmxEndpointsEnabled) { return ConditionOutcome.match( ConditionMessage.forCondition("JMX Enabled").found("properties") @@ -114,12 +116,6 @@ public class EndpointMBeanExportAutoConfiguration { .because("spring.jmx.enabled or endpoints.jmx.enabled is not set")); } - private boolean isEnabled(ConditionContext context, String prefix) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), prefix); - return resolver.getProperty("enabled", Boolean.class, true); - } - } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java index 02d8d0578f..2370a3e5fb 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java @@ -49,7 +49,6 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; @@ -89,6 +88,7 @@ import org.springframework.web.servlet.DispatcherServlet; * @author Johannes Edmeier * @author EddĂș MelĂ©ndez * @author Venil Noronha + * @author Madhura Bhave */ @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @@ -133,9 +133,9 @@ public class EndpointWebMvcAutoConfiguration @Override public void afterSingletonsInstantiated() { ManagementServerPort managementPort = ManagementServerPort.DIFFERENT; + Environment environment = this.applicationContext.getEnvironment(); if (this.applicationContext instanceof WebApplicationContext) { - managementPort = ManagementServerPort - .get(this.applicationContext.getEnvironment()); + managementPort = ManagementServerPort.get(environment); } if (managementPort == ManagementServerPort.DIFFERENT) { if (this.applicationContext instanceof ServletWebServerApplicationContext @@ -150,17 +150,14 @@ public class EndpointWebMvcAutoConfiguration } } if (managementPort == ManagementServerPort.SAME) { - if (new RelaxedPropertyResolver(this.applicationContext.getEnvironment(), - "management.ssl.").getProperty("enabled") != null) { + if (environment.getProperty("management.ssl.enabled") != null) { throw new IllegalStateException( "Management-specific SSL cannot be configured as the management " + "server is not listening on a separate port"); } - if (this.applicationContext - .getEnvironment() instanceof ConfigurableEnvironment) { + if (environment instanceof ConfigurableEnvironment) { addLocalManagementPortPropertyAlias( - (ConfigurableEnvironment) this.applicationContext - .getEnvironment()); + (ConfigurableEnvironment) environment); } } } @@ -356,9 +353,7 @@ public class EndpointWebMvcAutoConfiguration } private static Integer getPortProperty(Environment environment, String prefix) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, - prefix); - return resolver.getProperty("port", Integer.class); + return environment.getProperty(prefix + "port", Integer.class); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java index c7d30a745c..b1391d287e 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java @@ -47,7 +47,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -64,6 +63,7 @@ import org.springframework.web.cors.CorsConfiguration; * @author Dave Syer * @author Ben Hale * @author Vedran Pavic + * @author Madhura Bhave * @since 1.3.0 */ @ManagementContextConfiguration @@ -225,8 +225,7 @@ public class EndpointWebMvcManagementContextConfiguration { return ConditionOutcome .match(message.found("logging.path").items(config)); } - config = new RelaxedPropertyResolver(environment, "endpoints.logfile.") - .getProperty("external-file"); + config = environment.getProperty("endpoints.logfile.external-file"); if (StringUtils.hasText(config)) { return ConditionOutcome.match( message.found("endpoints.logfile.external-file").items(config)); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java index e42923143d..dd276abbba 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java @@ -33,7 +33,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -60,6 +59,7 @@ import org.springframework.web.servlet.mvc.ServletWrappingController; * @author Christian Dupuis * @author Dave Syer * @author Andy Wilkinson + * @author Madhura Bhave */ @Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @@ -108,9 +108,8 @@ public class JolokiaAutoConfiguration { private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), prefix); - return resolver.getProperty("enabled", Boolean.class, defaultValue); + return context.getEnvironment().getProperty(prefix + "enabled", Boolean.class, + defaultValue); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/OnEnabledEndpointElementCondition.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/OnEnabledEndpointElementCondition.java index 04196b84b7..3acc0297c1 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/OnEnabledEndpointElementCondition.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/OnEnabledEndpointElementCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -21,9 +21,9 @@ import java.lang.annotation.Annotation; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; /** @@ -31,6 +31,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata; * {@code defaults} name or individually via the name of the element. * * @author Stephane Nicoll + * @author Madhura Bhave */ abstract class OnEnabledEndpointElementCondition extends SpringBootCondition { @@ -59,10 +60,10 @@ abstract class OnEnabledEndpointElementCondition extends SpringBootCondition { protected ConditionOutcome getEndpointOutcome(ConditionContext context, String endpointName) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), this.prefix + endpointName + "."); - if (resolver.containsProperty("enabled")) { - boolean match = resolver.getProperty("enabled", Boolean.class, true); + Environment environment = context.getEnvironment(); + String enabledProperty = this.prefix + endpointName + ".enabled"; + if (environment.containsProperty(enabledProperty)) { + boolean match = environment.getProperty(enabledProperty, Boolean.class, true); return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType).because( this.prefix + endpointName + ".enabled is " + match)); @@ -71,9 +72,8 @@ abstract class OnEnabledEndpointElementCondition extends SpringBootCondition { } protected ConditionOutcome getDefaultEndpointsOutcome(ConditionContext context) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), this.prefix + "defaults."); - boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); + boolean match = Boolean.valueOf(context.getEnvironment() + .getProperty(this.prefix + "defaults.enabled", "true")); return new ConditionOutcome(match, ConditionMessage.forCondition(this.annotationType).because( this.prefix + "defaults.enabled is considered " + match)); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfiguration.java index 4d7cc6b3df..135d8567f9 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfiguration.java @@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.security.IgnoredRequestCustomizer; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; @@ -84,11 +83,9 @@ public class CloudFoundryActuatorAutoConfiguration { private CloudFoundrySecurityService getCloudFoundrySecurityService( RestTemplateBuilder restTemplateBuilder, Environment environment) { - RelaxedPropertyResolver cloudFoundryProperties = new RelaxedPropertyResolver( - environment, "management.cloudfoundry."); String cloudControllerUrl = environment.getProperty("vcap.application.cf_api"); - boolean skipSslValidation = cloudFoundryProperties - .getProperty("skip-ssl-validation", Boolean.class, false); + boolean skipSslValidation = environment.getProperty( + "management.cloudfoundry.skip-ssl-validation", Boolean.class, false); return cloudControllerUrl == null ? null : new CloudFoundrySecurityService(restTemplateBuilder, cloudControllerUrl, skipSslValidation); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/OnEnabledEndpointCondition.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/OnEnabledEndpointCondition.java index ffd903100a..6f0df8ea88 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/OnEnabledEndpointCondition.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/OnEnabledEndpointCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -19,16 +19,17 @@ package org.springframework.boot.actuate.condition; import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; /** * {@link Condition} that checks whether or not an endpoint is enabled. * * @author Andy Wilkinson + * @author Madhura Bhave */ class OnEnabledEndpointCondition extends SpringBootCondition { @@ -49,10 +50,10 @@ class OnEnabledEndpointCondition extends SpringBootCondition { private ConditionOutcome determineEndpointOutcome(String endpointName, boolean enabledByDefault, ConditionContext context) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), "endpoints." + endpointName + "."); - if (resolver.containsProperty("enabled") || !enabledByDefault) { - boolean match = resolver.getProperty("enabled", Boolean.class, + Environment environment = context.getEnvironment(); + String enabledProperty = "endpoints." + endpointName + ".enabled"; + if (environment.containsProperty(enabledProperty) || !enabledByDefault) { + boolean match = environment.getProperty(enabledProperty, Boolean.class, enabledByDefault); ConditionMessage message = ConditionMessage .forCondition(ConditionalOnEnabledEndpoint.class, @@ -64,9 +65,8 @@ class OnEnabledEndpointCondition extends SpringBootCondition { } private ConditionOutcome determineAllEndpointsOutcome(ConditionContext context) { - RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( - context.getEnvironment(), "endpoints."); - boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); + boolean match = Boolean.valueOf( + context.getEnvironment().getProperty("endpoints.enabled", "true")); ConditionMessage message = ConditionMessage .forCondition(ConditionalOnEnabledEndpoint.class) .because("All endpoints are " + (match ? "enabled" : "disabled") diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java index fc86febd32..70aab222de 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java @@ -17,6 +17,7 @@ package org.springframework.boot.actuate.endpoint.mvc; import java.security.Principal; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -27,18 +28,13 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.boot.actuate.endpoint.HealthEndpoint; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Status; -import org.springframework.boot.bind.RelaxedNames; -import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ResponseBody; /** @@ -53,8 +49,9 @@ import org.springframework.web.bind.annotation.ResponseBody; * @since 1.1.0 */ @ConfigurationProperties(prefix = "endpoints.health") -public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter - implements EnvironmentAware { +public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter { + + private static final List DEFAULT_ROLES = Arrays.asList("ROLE_ACTUATOR"); private final boolean secure; @@ -62,8 +59,6 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter statusMapping = new HashMap<>(); - private RelaxedPropertyResolver securityPropertyResolver; - private long lastAccess = 0; private Health cached; @@ -73,15 +68,16 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter(DEFAULT_ROLES)); } public HealthMvcEndpoint(HealthEndpoint delegate, boolean secure, List roles) { super(delegate); + Assert.notNull(roles, "Roles must not be null"); this.secure = secure; - setupDefaultStatusMapping(); this.roles = roles; + setupDefaultStatusMapping(); } private void setupDefaultStatusMapping() { @@ -89,12 +85,6 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter code.equals(getUniformValue(key))) + .map(this.statusMapping::get).findFirst().orElse(null); } return null; } + private String getUniformValue(String code) { + if (code == null) { + return null; + } + StringBuilder builder = new StringBuilder(); + for (char ch : code.toCharArray()) { + if (Character.isAlphabetic(ch) || Character.isDigit(ch)) { + builder.append(Character.toLowerCase(ch)); + } + } + return builder.toString(); + } + private Health getHealth(HttpServletRequest request, Principal principal) { long accessTime = System.currentTimeMillis(); if (isCacheStale(accessTime)) { @@ -207,13 +206,7 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter getRoles() { - if (this.roles != null) { - return this.roles; - } - String[] roles = StringUtils.commaDelimitedListToStringArray( - this.securityPropertyResolver.getProperty("roles", "ROLE_ACTUATOR")); - roles = StringUtils.trimArrayElements(roles); - return Arrays.asList(roles); + return this.roles; } private boolean isSpringSecurityAuthentication(Principal principal) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/EnvironmentInfoContributor.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/EnvironmentInfoContributor.java index d0ffb41168..c061e5e0ee 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/EnvironmentInfoContributor.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/EnvironmentInfoContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -16,7 +16,10 @@ package org.springframework.boot.actuate.info; -import org.springframework.boot.bind.PropertySourcesBinder; +import java.util.Map; + +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.env.ConfigurableEnvironment; /** @@ -24,19 +27,24 @@ import org.springframework.core.env.ConfigurableEnvironment; * * @author Meang Akira Tanaka * @author Stephane Nicoll + * @author Madhura Bhave * @since 1.4.0 */ public class EnvironmentInfoContributor implements InfoContributor { - private final PropertySourcesBinder binder; + private static final Bindable> STRING_OBJECT_MAP = Bindable + .mapOf(String.class, Object.class); + + private final ConfigurableEnvironment environment; public EnvironmentInfoContributor(ConfigurableEnvironment environment) { - this.binder = new PropertySourcesBinder(environment); + this.environment = environment; } @Override public void contribute(Info.Builder builder) { - builder.withDetails(this.binder.extractAll("info")); + Binder binder = Binder.get(this.environment); + binder.bind("info", STRING_OBJECT_MAP).ifBound(builder::withDetails); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoPropertiesInfoContributor.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoPropertiesInfoContributor.java index 6f30be29f2..383c7472b9 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoPropertiesInfoContributor.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/info/InfoPropertiesInfoContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -17,11 +17,15 @@ package org.springframework.boot.actuate.info; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; -import org.springframework.boot.bind.PropertySourcesBinder; +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.info.InfoProperties; +import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.util.StringUtils; @@ -30,11 +34,15 @@ import org.springframework.util.StringUtils; * * @param the type of the {@link InfoProperties} to expose * @author Stephane Nicoll + * @author Madhura Bhave * @since 1.4.0 */ public abstract class InfoPropertiesInfoContributor implements InfoContributor { + private static final Bindable> STRING_OBJECT_MAP = Bindable + .mapOf(String.class, Object.class); + private final T properties; private final Mode mode; @@ -85,7 +93,10 @@ public abstract class InfoPropertiesInfoContributor * @return the raw content */ protected Map extractContent(PropertySource propertySource) { - return new PropertySourcesBinder(propertySource).extractAll(""); + MutablePropertySources sources = new MutablePropertySources(); + sources.addFirst(propertySource); + return new Binder(ConfigurationPropertySources.get(sources)) + .bind("", STRING_OBJECT_MAP).orElseGet(LinkedHashMap::new); } /** diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java index 0c2b398feb..e85f8a9b96 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java @@ -21,7 +21,6 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Properties; import javax.sql.DataSource; @@ -55,14 +54,16 @@ import org.springframework.boot.autoconfigure.info.ProjectInfoProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.bind.PropertySourcesBinder; +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.MapConfigurationPropertySource; import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.ResolvableType; import org.springframework.core.annotation.Order; -import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.validation.BindException; @@ -310,17 +311,19 @@ public class EndpointAutoConfigurationTests { private static class GitFullInfoContributor implements InfoContributor { + private static final ResolvableType STRING_OBJECT_MAP = ResolvableType + .forClassWithGenerics(Map.class, String.class, Object.class); + private Map content = new LinkedHashMap<>(); GitFullInfoContributor(Resource location) throws BindException, IOException { - if (location.exists()) { - Properties gitInfoProperties = PropertiesLoaderUtils - .loadProperties(location); - PropertiesPropertySource gitPropertySource = new PropertiesPropertySource( - "git", gitInfoProperties); - this.content = new PropertySourcesBinder(gitPropertySource) - .extractAll("git"); + if (!location.exists()) { + return; } + MapConfigurationPropertySource source = new MapConfigurationPropertySource( + PropertiesLoaderUtils.loadProperties(location)); + new Binder(source).bind("info", + Bindable.of(STRING_OBJECT_MAP).withExistingValue(this.content)); } @Override diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index df17a03424..e8c4734539 100755 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -62,6 +62,7 @@ import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactor import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.testutil.Matched; @@ -357,7 +358,7 @@ public class EndpointWebMvcAutoConfigurationTests { @Test public void contextPath() throws Exception { EnvironmentTestUtils.addEnvironment(this.applicationContext, - "management.contextPath:/test", "management.security.enabled:false"); + "management.context-path:/test", "management.security.enabled:false"); this.applicationContext.register(RootConfig.class, EndpointConfig.class, PropertyPlaceholderAutoConfiguration.class, JacksonAutoConfiguration.class, @@ -448,7 +449,7 @@ public class EndpointWebMvcAutoConfigurationTests { this.applicationContext.register(RootConfig.class, BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class); EnvironmentTestUtils.addEnvironment(this.applicationContext, - "ENDPOINTS_ENABLED:false"); + "endpoints.enabled:false"); this.applicationContext.refresh(); assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).isEmpty(); } @@ -646,9 +647,10 @@ public class EndpointWebMvcAutoConfigurationTests { throws Exception { this.applicationContext.register(LoggingConfig.class, RootConfig.class, BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class); + ConfigurationPropertySources.attach(this.applicationContext.getEnvironment()); EnvironmentTestUtils.addEnvironment(this.applicationContext, "endpoints.enabled:false", - String.format("endpoints_%s_enabled:true", name)); + String.format("endpoints.%s.enabled:true", name)); this.applicationContext.refresh(); assertThat(this.applicationContext.getBeansOfType(type)).hasSize(1); } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfigurationTests.java index c177119879..9b9697cea9 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundryActuatorAutoConfigurationTests.java @@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.security.IgnoredRequestCustomizer; import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockHttpServletRequest; @@ -120,6 +121,7 @@ public class CloudFoundryActuatorAutoConfigurationTests { public void skipSslValidation() throws Exception { EnvironmentTestUtils.addEnvironment(this.context, "management.cloudfoundry.skipSslValidation:true"); + ConfigurationPropertySources.attach(this.context.getEnvironment()); this.context.refresh(); CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping(); Object interceptor = ReflectionTestUtils.getField(handlerMapping, diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java index 6f0476cc80..998e5f7584 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java @@ -16,8 +16,10 @@ package org.springframework.boot.actuate.endpoint.mvc; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -28,11 +30,8 @@ import org.junit.Test; import org.springframework.boot.actuate.endpoint.HealthEndpoint; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Status; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; import org.springframework.security.core.Authentication; @@ -54,9 +53,8 @@ import static org.mockito.Mockito.mock; */ public class HealthMvcEndpointTests { - private static final PropertySource SECURITY_ROLES = new MapPropertySource("test", - Collections.singletonMap("management.security.roles", - "HERO")); + private static final List SECURITY_ROLES = new ArrayList<>( + Arrays.asList("HERO")); private HttpServletRequest request = new MockHttpServletRequest(); @@ -64,8 +62,6 @@ public class HealthMvcEndpointTests { private HealthMvcEndpoint mvc = null; - private MockEnvironment environment; - private HttpServletRequest defaultUser = createAuthenticationRequest("ROLE_ACTUATOR"); private HttpServletRequest hero = createAuthenticationRequest("HERO"); @@ -81,8 +77,6 @@ public class HealthMvcEndpointTests { this.endpoint = mock(HealthEndpoint.class); given(this.endpoint.isEnabled()).willReturn(true); this.mvc = new HealthMvcEndpoint(this.endpoint); - this.environment = new MockEnvironment(); - this.mvc.setEnvironment(this.environment); } @Test @@ -123,7 +117,7 @@ public class HealthMvcEndpointTests { public void customMappingWithRelaxedName() { given(this.endpoint.invoke()) .willReturn(new Health.Builder().outOfService().build()); - this.mvc.setStatusMapping(Collections.singletonMap("out-of-service", + this.mvc.setStatusMapping(Collections.singletonMap("out-OF-serVice", HttpStatus.INTERNAL_SERVER_ERROR)); Object result = this.mvc.invoke(this.request, null); assertThat(result instanceof ResponseEntity).isTrue(); @@ -165,7 +159,7 @@ public class HealthMvcEndpointTests { @Test public void rightAuthorityPresentShouldExposeDetails() throws Exception { - this.environment.getPropertySources().addLast(SECURITY_ROLES); + this.mvc = new HealthMvcEndpoint(this.endpoint, true, SECURITY_ROLES); Authentication principal = mock(Authentication.class); Set authorities = Collections .singleton(new SimpleGrantedAuthority("HERO")); @@ -180,7 +174,7 @@ public class HealthMvcEndpointTests { @Test public void customRolePresentShouldExposeDetails() { - this.environment.getPropertySources().addLast(SECURITY_ROLES); + this.mvc = new HealthMvcEndpoint(this.endpoint, true, SECURITY_ROLES); given(this.endpoint.invoke()) .willReturn(new Health.Builder().up().withDetail("foo", "bar").build()); Object result = this.mvc.invoke(this.hero, null); @@ -191,7 +185,7 @@ public class HealthMvcEndpointTests { @Test public void customRoleShouldNotExposeDetailsForDefaultRole() { - this.environment.getPropertySources().addLast(SECURITY_ROLES); + this.mvc = new HealthMvcEndpoint(this.endpoint, true, SECURITY_ROLES); given(this.endpoint.invoke()) .willReturn(new Health.Builder().up().withDetail("foo", "bar").build()); Object result = this.mvc.invoke(this.defaultUser, null);